diff -r ebc84c812384 -r 46218c8b8afa Symbian3/PDK/Source/GUID-B1CE51BC-B452-5FC9-9C00-35447AF40671.dita --- a/Symbian3/PDK/Source/GUID-B1CE51BC-B452-5FC9-9C00-35447AF40671.dita Thu Mar 11 15:24:26 2010 +0000 +++ b/Symbian3/PDK/Source/GUID-B1CE51BC-B452-5FC9-9C00-35447AF40671.dita Thu Mar 11 18:02:22 2010 +0000 @@ -1,357 +1,357 @@ - - - - - - Implement -the controllable power resourcesThis document describes how to write and use power resources. -
Purpose

Implement your power resource according -to the type of resource you wish to support.

Introduction

Power -resources controlled by the PRM can be turned on, off and varied with software.

See -the Power -resources section for detailed information about resources. There are -five main types of resource that can be implemented:

    -
  • static resources - derived -from the DStaticPowerResource base class,

  • -
  • static resource that -support dependancy - derived from the DStaticpowerResourceD base -class,

  • -
  • dynamic resources - -derived from the DDynamicPowerResource base class. Create -dynamic resources in the kernel data section or in the heap,

  • -
  • dynamic resource that -support dependancy - derived from the DDynamicPowerResourceD.

  • -
  • custom sense resources -- when shared the power level of this resource may be increased or decreased -freely by some privileged clients but not by others, which are bound by the -requirement of the privileged clients.

  • -

Note: dynamic resources and resource dependancies are only -supported in the extended version of the PRM. See setup and configuration requirements.

-
Implementing power resources

The following tasks -are covered in this tutorial:

    -
  • Create your resource by

    Override -the pure virtual functions,

  • -
  • Create resource dependencies,

  • -
  • Create custom resources.

  • -

Override the pure -virtual functions

The pure virtual functions of DStaticPowerResource or DDynamicPowerResource must -be implemented.

Constructor

Information about the resource -based on the resources category must be set in the iFlags bit -mask. Static variables that define a resources classification can be found -within 32\include\drivers\resource.h.

Each resource -is classified based on:

    -
  • usage,

  • -
  • operating levels,

  • -
  • latency,

  • -
  • resource sense.

  • -

Below is the example implementation of derived class constructor

// multilevel, shared, long latency, read and write, positive resource. -DMLSHLGLSPResource::DMLSHLGLSPResource() : DStaticPowerResource(KDBSHLGLSPResource, E_ON), - iMinLevel(E_OFF), iMaxLevel(E_ON), iCurrentLevel(E_ON), iPolled(ETrue) - { - iFlags = EMultilevel | KShared | KLongLatencySet | KLongLatencyGet; - . . . - }

GetInfo()

The PIL uses GetInfo() to -get resource information. The default implementation of this function provides -generic information about the resource by updating the passed descriptor that -contains an information structure TPowerResourceInfoV01. -Derived implementations must fill in all the PSL specific fields and call -the base class implementation. Below is an example implementation.

TInt DH4SndFclkResource::GetInfo(TDes8* info) const - { - __KTRACE_OPT(KRESMANAGER, Kern::Printf(">DH4SndFclkResource::GetInfo\n")); - - /** Call base class implementation to fill generic details */ - DStaticPowerResource::GetInfo((TDes8*) info); - TPowerResourceInfoV01 *buf1 = (TPowerResourceInfoV01*) info; - buf1->iMinLevel = iMinLevel; - buf1->iMaxLevel = iMaxLevel; - __KTRACE_OPT(KRESMANAGER, Kern::Printf("<DH4SndFclkResource::GetInfo\n")); - return KErrNone; - }

The member variables of the TPowerResourceInfoV01 structure -are reserved for PSL information. These can be used to return resource specific -information to clients.

DoRequest()

DoRequest() is -used by the PIL to control resources. For example, to change and read the -state of resources. DoRequest() takes a TPowerRequest object -that contains all the request information. Note: This function needs -to be implemented for all resources.

Below is an example DoRequest() function -implementation for a binary, instantaneous resource.

TInt DH4MmcCtrllerPwrResource::DoRequest(TPowerRequest& aRequest) - { - TInt retVal = KErrNone; - TUint16 config; - /** Enable/disable the MMC controller by programming the MMC controller 'CON' register- 'POW' bit */ - if (aRequest.ReqType()==TPowerRequest::EGet) - { - PRM_PSL_RESOURCE_GET_STATE_START_TRACE - config = OMAPMMC_GET_REG(KHoMMC_Con_Reg); - if(config & KHtMMC_PowerUp) - { - aRequest.Level() = 1; - iCurLevel = 1; - } - else - { - aRequest.Level() = 0; - iCurLevel = 0; - } - PRM_PSL_RESOURCE_GET_STATE_END_TRACE - } - else if(aRequest.ReqType()==TPowerRequest::ESetDefaultLevel) - { - PRM_PSL_RESOURCE_CHANGE_STATE_START_TRACE - OMAPMMC_MOD_REG(KHoMMC_Con_Reg, KHtMMC_PowerUp, KClear32); - iCurLevel = iDefaultLevel; - aRequest.Level() = iDefaultLevel; - PRM_PSL_RESOURCE_CHANGE_STATE_END_TRACE - } - else - { - PRM_PSL_RESOURCE_CHANGE_STATE_START_TRACE - if(aRequest.Level() == 1) - { - OMAPMMC_MOD_REG(KHoMMC_Con_Reg, KClear32, KHtMMC_PowerUp); - } - else - { - OMAPMMC_MOD_REG(KHoMMC_Con_Reg, KHtMMC_PowerUp, KClear32); - } - iCurLevel = aRequest.Level(); - PRM_PSL_RESOURCE_CHANGE_STATE_END_TRACE - } - return retVal; - }

The DoRequest function implementation should take care -of blocking the Resource Controller thread as operations on a long latency -resource take a significant amount of time to complete (in hardware). Usually -the request completion is notified either through an ISR (interrupt driven) -or through register setting (polling wait) by hardware.

Below is an -example DoRequest() implementation for a long latency resource.

TInt DH4MmcPowerResource::DoRequest(TPowerRequest& aRequest) - { - TUint8 iMenelausConf; - TInt retVal = KErrNone; - - /** Access to Menelaus registers is over I2C bus. This is a long latency synchronous operation. - Create a Menelaus Request structure and send it to Menelaus chip, Wait until a response is received */ - - if (aRequest.ReqType()==TPowerRequest::EGet) - { - // Frame the request - ... - } - // Default level is off. - else if (aRequest.ReqType() == TPowerRequest::ESetDefaultLevel) - { - // Frame request to move the resource to default state - ... - } - // EChange - else - { - // Frame request to set the requested resource state - ... - } - - // Request the operation on the hardware - retVal = Menelaus::AccessRegister(iMenelausReq); - - // Wait for the request to complete - __KTRACE_OPT(KPBUS1, Kern::Printf("Waiting for menelaus req to signal sem\n")); - NKern::FSSetOwner(&iSemaphore,NULL); - iSemaphore.iCount = 0; - - // This will be signalled in Menelaus access functions callback below - NKern::FSWait(&(iSemaphore)); - - // Menelaus chip has responded - if(iMenelausAccessErr == KErrNone) - { - switch(iMenelausState) - { - case EMenelausRead: - // Return 0/1 depending on the value set - iMenelausConf = (*(iRdBuffer.Ptr())) & KHoMenelausVmmcModeMask; - if(iMenelausConf == 3) - { - iCurLevel=aRequest.Level()=1; - } - else - { - iCurLevel=aRequest.Level()=0; - } - PRM_PSL_RESOURCE_GET_STATE_END_TRACE - break; - - case EMenelausSingleWrite: - iCurLevel = aRequest.Level(); - PRM_PSL_RESOURCE_CHANGE_STATE_END_TRACE - break; - } - } - return iMenelausAccessErr; - } - -/** Below is the Menelaus access functions callback where the semaphore is signalled. */ -void DH4MmcPowerResource::MenelausAccessDone(TAny* aPtr, TInt aResult) - { - DH4MmcPowerResource* ptr = reinterpret_cast<DH4MmcPowerResource*>(aPtr); - ptr->iMenelausAccessErr = aResult; - if(aResult != KErrNone) - { - __KTRACE_OPT(KRESMANAGER, - Kern::Printf("Menelaus::MenelausAccessRegister ERR(%d)\n", aResult)); - } - // Signal the waiting thread - NKern::FSSignal(&(ptr->iSemaphore)); - return; - }

Create -resource dependencies

A resource has a dependency if the state -of the resource depends on the state of one or more resources. For example, -a clock whose frequency is derived from another clock or voltage is a dependent -resource. The PSL usually handles resource dependencies transparently. However, -if the resources have public users (clients of the PRM), then these resources -should be registered with the PRM as Resource -dependencies that are linked.

Each dependency must be assigned -a priority value. The priority is used by the PIL when propagating the change -and propagating the request for notifications. Each link stemming from a resource -must have a unique priority value.

Note: Resource dependencies -are only supported in the extended version of the PRM. Only long latency resources -are allowed to have dependents and no closed loop dependencies are allowed.

Register -resource dependencies for dynamic and static resources

Static -resources that support dependencies are created and registered with the PRM -during resource controller creation time and are derived from DStaticPowerResourceD:

DXXXStaticPowerResourceD : public DStaticPowerResourceD - { -public: - DXXXStaticPowerResourceD(); - TInt DoRequest(TPowerRequest &req); - TInt GetInfo(TDes8* aInfo) const; - TChangePropagationStatus TranslateDependentState(TInt aDepId, TInt aDepState, TInt& aResState); -private: - TInt iMinLevel; - TInt iMaxLevel; - TInt iCurrentLevel; - ... - };

Dependencies between static resources should be established -by the PSL before registering these resources with the PIL. Use the DStaticPowerResourceD::AddNode() function -provided in the base class to establish a dependency link between static resources. -See Creating -dependencies between static resources.

Dynamic resources that -support dependency are derived from DDynamicPowerResourceD. -These can be registered and deregistered from the PRM at any time after the -PRM is fully initialised. Dependencies between resources are established by -the client using PowerResourceManager::RegisterResourceDependency().

DXXXDynamicPowerResourceD : public DDynamicPowerResourceD - { -public: - DXXXDynamicPowerResourceD(); - TInt DoRequest(TPowerRequest &req); - TInt GetInfo(TDes8* aInfo) const; - TChangePropagationStatus TranslateDependentState(TInt aDepId, TInt aDepState, TInt& aResState); -private: - TInt iMinLevel; - TInt iMaxLevel; - TInt iCurrentLevel; - ... - };

Dependencies can be established between a dynamic resource -and a static (dependency enabled) resource using the same API. A client can -deregister dependencies between a pair of dynamic resource (or between a dynamic -and static resource) using PowerResourceManager::DeRegisterResourceDependency(). -When a dynamic resource that supports dependency deregisters from the PRM, -dependencies are removed automatically by the PIL.

Change the state -of dependent resources

When a state change is requested by a client -on any resource in a dependency tree before proceeding with the change the -PIL must check if the change is allowed by its dependents and the ones it -depends on. The PIL does this by calling the TranslateDependentState() function -on each resource. This is a pure virtual function in the base class and must -be implemented in the derived class.

This function is called by the -PIL prior to a resource change on any of its dependents. The function returns -one of these values:

    -
  • EChange - -If the resource accepts the state change of the dependent resource and, as -a result of the dependent resources state change this resource needs to change -its own state. The new state of this resource is updated in aResState,

  • -
  • ENoChange - -if the resource accepts the dependent resources state change and this resource -does not need to change its state,

  • -
  • ENotAllowed - -if the resource does not accept the dependent resources state change.

  • -
TChangePropagationStatus DXXDependResource::TranslateDependentState(TInt /*aDepId*/, TInt aDepState, - TInt& aResState) - { - /* Switch ON if the dependent resource is ON */ - if((aDepState == 1) && (iCurrentLevel == 0) - { - aResState = iMaxLevel; - return EChange; - } - - /* Don’t allow dependent to OFF, if this is still ON */ - else if (aDepState == 0) && (iCurrentLevel == 1) - { - return ENotAllowed; - } - - return ENoChange; - }

Create -custom resources

Clients on a shared resource may have different -requirements on the state of a shared resource. The resource sense is used -by the PIL to determine whose requirement prevails:

    -
  • positive sense resources -- when shared can have their value increased without prejudice to their clients,

  • -
  • negative sense resources -- when shared can have their value decreased without prejudice to their clients,

  • -
  • custom sense resources -- when shared may be increased or decreased freely by some privileged clients -but not by others, which are bound by the requirement of the privileged clients.

  • -

A custom function must be supplied for every Power resources resource. This function is called by the PIL every -time a change request is issued to determine if the change requested by the -client is allowed as a decision to allow the resource change is determined -solely by the PSL. The resource object contains a pointer that must be set -at construction for custom sense resources by calling this function:

inline void SetCustomFunction(TCustomFunction aCustomFunction)

This -function sets the custom function for the resource. If a custom function is -not supplied for a custom sense resource the PIL panics during a resource -state change. An example of a custom sense resource is a shared domain clock -when a domain client uses it as a bit clock.

TCustomFunction is -a function pointer:

typedef TBool (*TCustomFunction) (TInt& /*aClientId*/, - TUint /*aResourceId*/, - TInt& /*aLevel*/, - TAny* /*aLevelList*/);

The -values held in TCustomFunction are:

    -
  • the Id of the client -requesting the change,

  • -
  • the Id of the resource -on which the change is requested (this allows a single function to handle -multiple resources),

  • -
  • the level the client -is requesting,

  • -
  • a pointer to the list -of the resource’s client -levels.

  • -

Custom functions can be set at any time before a resource state change -is requested on a resource. Ideally a custom function is set at resource creation -time in the resource's constructor.

DBSHLGLSCResource::DBSHLGLSCResource() : DStaticPowerResource(KDBSHLGLSCResource, E_ON), iMinLevel(E_OFF), iMaxLevel(E_ON), iCurrentLevel(E_ON), iPolled(EFalse) - { - iFlags = KMultiLevel | KShared | KLongLatencySet | KSenseCustom; - SetCustomFunction(CustomFunction); - ... - }

The decision to allow the requested resource state change -is specified in the custom function return value. This is ETrue if -the change is allowed and EFalse if the change is not allowed.

The -function can change the state of the resource to a level other than the one -requested and can choose a client other than the passed client to hold the Caching -the prevailing level of the resource.

Supporting dependencies

If -the custom sense resource supports dependencies then use the function pointer TDependencyCustomFunction. -This takes an additional parameter that specifies the resource Client level objects.

-
-Porting the -Power Resource Manager -Implement -the PSL for the target -Port the -client drivers to use the PRM -Debugging -the PRM -Testing the -PRM PSL + + + + + + Implement +the controllable power resourcesThis document describes how to write and use power resources. +
Purpose

Implement your power resource according +to the type of resource you wish to support.

Introduction

Power +resources controlled by the PRM can be turned on, off and varied with software.

See +the Power +resources section for detailed information about resources. There are +five main types of resource that can be implemented:

    +
  • static resources - derived +from the DStaticPowerResource base class,

  • +
  • static resource that +support dependancy - derived from the DStaticpowerResourceD base +class,

  • +
  • dynamic resources - +derived from the DDynamicPowerResource base class. Create +dynamic resources in the kernel data section or in the heap,

  • +
  • dynamic resource that +support dependancy - derived from the DDynamicPowerResourceD.

  • +
  • custom sense resources +- when shared the power level of this resource may be increased or decreased +freely by some privileged clients but not by others, which are bound by the +requirement of the privileged clients.

  • +

Note: dynamic resources and resource dependancies are only +supported in the extended version of the PRM. See setup and configuration requirements.

+
Implementing power resources

The following tasks +are covered in this tutorial:

    +
  • Create your resource by

    Override +the pure virtual functions,

  • +
  • Create resource dependencies,

  • +
  • Create custom resources.

  • +

Override the pure +virtual functions

The pure virtual functions of DStaticPowerResource or DDynamicPowerResource must +be implemented.

Constructor

Information about the resource +based on the resources category must be set in the iFlags bit +mask. Static variables that define a resources classification can be found +within 32\include\drivers\resource.h.

Each resource +is classified based on:

    +
  • usage,

  • +
  • operating levels,

  • +
  • latency,

  • +
  • resource sense.

  • +

Below is the example implementation of derived class constructor

// multilevel, shared, long latency, read and write, positive resource. +DMLSHLGLSPResource::DMLSHLGLSPResource() : DStaticPowerResource(KDBSHLGLSPResource, E_ON), + iMinLevel(E_OFF), iMaxLevel(E_ON), iCurrentLevel(E_ON), iPolled(ETrue) + { + iFlags = EMultilevel | KShared | KLongLatencySet | KLongLatencyGet; + . . . + }

GetInfo()

The PIL uses GetInfo() to +get resource information. The default implementation of this function provides +generic information about the resource by updating the passed descriptor that +contains an information structure TPowerResourceInfoV01. +Derived implementations must fill in all the PSL specific fields and call +the base class implementation. Below is an example implementation.

TInt DH4SndFclkResource::GetInfo(TDes8* info) const + { + __KTRACE_OPT(KRESMANAGER, Kern::Printf(">DH4SndFclkResource::GetInfo\n")); + + /** Call base class implementation to fill generic details */ + DStaticPowerResource::GetInfo((TDes8*) info); + TPowerResourceInfoV01 *buf1 = (TPowerResourceInfoV01*) info; + buf1->iMinLevel = iMinLevel; + buf1->iMaxLevel = iMaxLevel; + __KTRACE_OPT(KRESMANAGER, Kern::Printf("<DH4SndFclkResource::GetInfo\n")); + return KErrNone; + }

The member variables of the TPowerResourceInfoV01 structure +are reserved for PSL information. These can be used to return resource specific +information to clients.

DoRequest()

DoRequest() is +used by the PIL to control resources. For example, to change and read the +state of resources. DoRequest() takes a TPowerRequest object +that contains all the request information. Note: This function needs +to be implemented for all resources.

Below is an example DoRequest() function +implementation for a binary, instantaneous resource.

TInt DH4MmcCtrllerPwrResource::DoRequest(TPowerRequest& aRequest) + { + TInt retVal = KErrNone; + TUint16 config; + /** Enable/disable the MMC controller by programming the MMC controller 'CON' register- 'POW' bit */ + if (aRequest.ReqType()==TPowerRequest::EGet) + { + PRM_PSL_RESOURCE_GET_STATE_START_TRACE + config = OMAPMMC_GET_REG(KHoMMC_Con_Reg); + if(config & KHtMMC_PowerUp) + { + aRequest.Level() = 1; + iCurLevel = 1; + } + else + { + aRequest.Level() = 0; + iCurLevel = 0; + } + PRM_PSL_RESOURCE_GET_STATE_END_TRACE + } + else if(aRequest.ReqType()==TPowerRequest::ESetDefaultLevel) + { + PRM_PSL_RESOURCE_CHANGE_STATE_START_TRACE + OMAPMMC_MOD_REG(KHoMMC_Con_Reg, KHtMMC_PowerUp, KClear32); + iCurLevel = iDefaultLevel; + aRequest.Level() = iDefaultLevel; + PRM_PSL_RESOURCE_CHANGE_STATE_END_TRACE + } + else + { + PRM_PSL_RESOURCE_CHANGE_STATE_START_TRACE + if(aRequest.Level() == 1) + { + OMAPMMC_MOD_REG(KHoMMC_Con_Reg, KClear32, KHtMMC_PowerUp); + } + else + { + OMAPMMC_MOD_REG(KHoMMC_Con_Reg, KHtMMC_PowerUp, KClear32); + } + iCurLevel = aRequest.Level(); + PRM_PSL_RESOURCE_CHANGE_STATE_END_TRACE + } + return retVal; + }

The DoRequest function implementation should take care +of blocking the Resource Controller thread as operations on a long latency +resource take a significant amount of time to complete (in hardware). Usually +the request completion is notified either through an ISR (interrupt driven) +or through register setting (polling wait) by hardware.

Below is an +example DoRequest() implementation for a long latency resource.

TInt DH4MmcPowerResource::DoRequest(TPowerRequest& aRequest) + { + TUint8 iMenelausConf; + TInt retVal = KErrNone; + + /** Access to Menelaus registers is over I2C bus. This is a long latency synchronous operation. + Create a Menelaus Request structure and send it to Menelaus chip, Wait until a response is received */ + + if (aRequest.ReqType()==TPowerRequest::EGet) + { + // Frame the request + ... + } + // Default level is off. + else if (aRequest.ReqType() == TPowerRequest::ESetDefaultLevel) + { + // Frame request to move the resource to default state + ... + } + // EChange + else + { + // Frame request to set the requested resource state + ... + } + + // Request the operation on the hardware + retVal = Menelaus::AccessRegister(iMenelausReq); + + // Wait for the request to complete + __KTRACE_OPT(KPBUS1, Kern::Printf("Waiting for menelaus req to signal sem\n")); + NKern::FSSetOwner(&iSemaphore,NULL); + iSemaphore.iCount = 0; + + // This will be signalled in Menelaus access functions callback below + NKern::FSWait(&(iSemaphore)); + + // Menelaus chip has responded + if(iMenelausAccessErr == KErrNone) + { + switch(iMenelausState) + { + case EMenelausRead: + // Return 0/1 depending on the value set + iMenelausConf = (*(iRdBuffer.Ptr())) & KHoMenelausVmmcModeMask; + if(iMenelausConf == 3) + { + iCurLevel=aRequest.Level()=1; + } + else + { + iCurLevel=aRequest.Level()=0; + } + PRM_PSL_RESOURCE_GET_STATE_END_TRACE + break; + + case EMenelausSingleWrite: + iCurLevel = aRequest.Level(); + PRM_PSL_RESOURCE_CHANGE_STATE_END_TRACE + break; + } + } + return iMenelausAccessErr; + } + +/** Below is the Menelaus access functions callback where the semaphore is signalled. */ +void DH4MmcPowerResource::MenelausAccessDone(TAny* aPtr, TInt aResult) + { + DH4MmcPowerResource* ptr = reinterpret_cast<DH4MmcPowerResource*>(aPtr); + ptr->iMenelausAccessErr = aResult; + if(aResult != KErrNone) + { + __KTRACE_OPT(KRESMANAGER, + Kern::Printf("Menelaus::MenelausAccessRegister ERR(%d)\n", aResult)); + } + // Signal the waiting thread + NKern::FSSignal(&(ptr->iSemaphore)); + return; + }

Create +resource dependencies

A resource has a dependency if the state +of the resource depends on the state of one or more resources. For example, +a clock whose frequency is derived from another clock or voltage is a dependent +resource. The PSL usually handles resource dependencies transparently. However, +if the resources have public users (clients of the PRM), then these resources +should be registered with the PRM as Resource +dependencies that are linked.

Each dependency must be assigned +a priority value. The priority is used by the PIL when propagating the change +and propagating the request for notifications. Each link stemming from a resource +must have a unique priority value.

Note: Resource dependencies +are only supported in the extended version of the PRM. Only long latency resources +are allowed to have dependents and no closed loop dependencies are allowed.

Register +resource dependencies for dynamic and static resources

Static +resources that support dependencies are created and registered with the PRM +during resource controller creation time and are derived from DStaticPowerResourceD:

DXXXStaticPowerResourceD : public DStaticPowerResourceD + { +public: + DXXXStaticPowerResourceD(); + TInt DoRequest(TPowerRequest &req); + TInt GetInfo(TDes8* aInfo) const; + TChangePropagationStatus TranslateDependentState(TInt aDepId, TInt aDepState, TInt& aResState); +private: + TInt iMinLevel; + TInt iMaxLevel; + TInt iCurrentLevel; + ... + };

Dependencies between static resources should be established +by the PSL before registering these resources with the PIL. Use the DStaticPowerResourceD::AddNode() function +provided in the base class to establish a dependency link between static resources. +See Creating +dependencies between static resources.

Dynamic resources that +support dependency are derived from DDynamicPowerResourceD. +These can be registered and deregistered from the PRM at any time after the +PRM is fully initialised. Dependencies between resources are established by +the client using PowerResourceManager::RegisterResourceDependency().

DXXXDynamicPowerResourceD : public DDynamicPowerResourceD + { +public: + DXXXDynamicPowerResourceD(); + TInt DoRequest(TPowerRequest &req); + TInt GetInfo(TDes8* aInfo) const; + TChangePropagationStatus TranslateDependentState(TInt aDepId, TInt aDepState, TInt& aResState); +private: + TInt iMinLevel; + TInt iMaxLevel; + TInt iCurrentLevel; + ... + };

Dependencies can be established between a dynamic resource +and a static (dependency enabled) resource using the same API. A client can +deregister dependencies between a pair of dynamic resource (or between a dynamic +and static resource) using PowerResourceManager::DeRegisterResourceDependency(). +When a dynamic resource that supports dependency deregisters from the PRM, +dependencies are removed automatically by the PIL.

Change the state +of dependent resources

When a state change is requested by a client +on any resource in a dependency tree before proceeding with the change the +PIL must check if the change is allowed by its dependents and the ones it +depends on. The PIL does this by calling the TranslateDependentState() function +on each resource. This is a pure virtual function in the base class and must +be implemented in the derived class.

This function is called by the +PIL prior to a resource change on any of its dependents. The function returns +one of these values:

    +
  • EChange - +If the resource accepts the state change of the dependent resource and, as +a result of the dependent resources state change this resource needs to change +its own state. The new state of this resource is updated in aResState,

  • +
  • ENoChange - +if the resource accepts the dependent resources state change and this resource +does not need to change its state,

  • +
  • ENotAllowed - +if the resource does not accept the dependent resources state change.

  • +
TChangePropagationStatus DXXDependResource::TranslateDependentState(TInt /*aDepId*/, TInt aDepState, + TInt& aResState) + { + /* Switch ON if the dependent resource is ON */ + if((aDepState == 1) && (iCurrentLevel == 0) + { + aResState = iMaxLevel; + return EChange; + } + + /* Don’t allow dependent to OFF, if this is still ON */ + else if (aDepState == 0) && (iCurrentLevel == 1) + { + return ENotAllowed; + } + + return ENoChange; + }

Create +custom resources

Clients on a shared resource may have different +requirements on the state of a shared resource. The resource sense is used +by the PIL to determine whose requirement prevails:

    +
  • positive sense resources +- when shared can have their value increased without prejudice to their clients,

  • +
  • negative sense resources +- when shared can have their value decreased without prejudice to their clients,

  • +
  • custom sense resources +- when shared may be increased or decreased freely by some privileged clients +but not by others, which are bound by the requirement of the privileged clients.

  • +

A custom function must be supplied for every Power resources resource. This function is called by the PIL every +time a change request is issued to determine if the change requested by the +client is allowed as a decision to allow the resource change is determined +solely by the PSL. The resource object contains a pointer that must be set +at construction for custom sense resources by calling this function:

inline void SetCustomFunction(TCustomFunction aCustomFunction)

This +function sets the custom function for the resource. If a custom function is +not supplied for a custom sense resource the PIL panics during a resource +state change. An example of a custom sense resource is a shared domain clock +when a domain client uses it as a bit clock.

TCustomFunction is +a function pointer:

typedef TBool (*TCustomFunction) (TInt& /*aClientId*/, + TUint /*aResourceId*/, + TInt& /*aLevel*/, + TAny* /*aLevelList*/);

The +values held in TCustomFunction are:

    +
  • the Id of the client +requesting the change,

  • +
  • the Id of the resource +on which the change is requested (this allows a single function to handle +multiple resources),

  • +
  • the level the client +is requesting,

  • +
  • a pointer to the list +of the resource’s client +levels.

  • +

Custom functions can be set at any time before a resource state change +is requested on a resource. Ideally a custom function is set at resource creation +time in the resource's constructor.

DBSHLGLSCResource::DBSHLGLSCResource() : DStaticPowerResource(KDBSHLGLSCResource, E_ON), iMinLevel(E_OFF), iMaxLevel(E_ON), iCurrentLevel(E_ON), iPolled(EFalse) + { + iFlags = KMultiLevel | KShared | KLongLatencySet | KSenseCustom; + SetCustomFunction(CustomFunction); + ... + }

The decision to allow the requested resource state change +is specified in the custom function return value. This is ETrue if +the change is allowed and EFalse if the change is not allowed.

The +function can change the state of the resource to a level other than the one +requested and can choose a client other than the passed client to hold the Caching +the prevailing level of the resource.

Supporting dependencies

If +the custom sense resource supports dependencies then use the function pointer TDependencyCustomFunction. +This takes an additional parameter that specifies the resource Client level objects.

+
+Porting the +Power Resource Manager +Implement +the PSL for the target +Port the +client drivers to use the PRM +Debugging +the PRM +Testing the +PRM PSL
\ No newline at end of file