Symbian3/PDK/Source/GUID-A789E0D6-74B2-517D-B73A-F9B11794F175.dita
changeset 1 25a17d01db0c
child 3 46218c8b8afa
equal deleted inserted replaced
0:89d6a7a84779 1:25a17d01db0c
       
     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-A789E0D6-74B2-517D-B73A-F9B11794F175" xml:lang="en"><title>Peripheral
       
    13 Driver Power Implementation Tutorial</title><shortdesc/><prolog><metadata><keywords/></metadata></prolog><conbody>
       
    14 <p>Peripheral driver power management is based on the <xref href="GUID-761AE02B-41A6-35EA-AA9F-0AEEFF67A6F7.dita"><apiname>DPowerHandler</apiname></xref> class.
       
    15 This is a class that defines the interface that the driver must provide to
       
    16 the generic kernel side power manager. </p>
       
    17 <p>The class also provides the necessary support functions. The class is defined
       
    18 as: </p>
       
    19 <codeblock id="GUID-C34B90B1-5AB2-51E4-A7C9-01601B8698F6" xml:space="preserve">class DPowerHandler : public DBase
       
    20     {
       
    21 public:
       
    22     IMPORT_C ~DPowerHandler();
       
    23 public:
       
    24     IMPORT_C DPowerHandler(const TDesC&amp; aName);
       
    25     IMPORT_C void Add();
       
    26     IMPORT_C void Remove();
       
    27     IMPORT_C void PowerUpDone();
       
    28     IMPORT_C void PowerDownDone();
       
    29     IMPORT_C void SetCurrentConsumption(TInt aCurrent);
       
    30     IMPORT_C void DeltaCurrentConsumption(TInt aCurrent);
       
    31 public: 
       
    32     virtual void PowerDown(TPowerState aTargetState) = 0;
       
    33     virtual void PowerUp() = 0;
       
    34 private:
       
    35     ...
       
    36     };
       
    37       </codeblock>
       
    38 <p>Typically, at least one power handler object is implemented by the peripheral
       
    39 driver. In some cases the peripheral driver interface class may derive from <xref href="GUID-761AE02B-41A6-35EA-AA9F-0AEEFF67A6F7.dita"><apiname>DPowerHandler</apiname></xref>,
       
    40 in others it creates and owns an instance of a <xref href="GUID-761AE02B-41A6-35EA-AA9F-0AEEFF67A6F7.dita"><apiname>DPowerHandler</apiname></xref> derived
       
    41 class. </p>
       
    42 <p>The Symbian port of the <xref href="GUID-8C22AF20-EE0E-5AD2-BEFD-FED5A7DBB09B.dita">LCD
       
    43 Extension</xref> for the Lubbock reference board is an example of the first
       
    44 type of implementation. </p>
       
    45 <p>The first eight functions are exported from the kernel, <filepath>EKERN.EXE</filepath>,
       
    46 while the remaining two pure virtual functions are implemented by the peripheral
       
    47 driver. </p>
       
    48 <ul>
       
    49 <li id="GUID-C5E97751-13E6-5439-AA62-2323D4DA7A37"><p> <xref href="GUID-A789E0D6-74B2-517D-B73A-F9B11794F175.dita#GUID-A789E0D6-74B2-517D-B73A-F9B11794F175/GUID-6A4484AA-B10E-54D8-B32B-05583EB66841">PowerDown()</xref>  </p> </li>
       
    50 <li id="GUID-44F74198-A6DA-56FA-AE39-AADBC3DFB79F"><p> <xref href="GUID-A789E0D6-74B2-517D-B73A-F9B11794F175.dita#GUID-A789E0D6-74B2-517D-B73A-F9B11794F175/GUID-389D4920-2956-5CBE-979E-30C23A0C3E49">PowerUp()</xref>  </p> </li>
       
    51 </ul>
       
    52 <p>Notes: </p>
       
    53 <ol id="GUID-C1640CE7-AF3E-5EF4-9D4C-B44F19B83AB3">
       
    54 <li id="GUID-757692DC-EE42-577F-8D92-AC1C61A7C381"><p>Current consumption
       
    55 monitoring does not have a full implementation in the power manager at present.
       
    56 It is unclear whether this will be ever required. However, <xref href="GUID-761AE02B-41A6-35EA-AA9F-0AEEFF67A6F7.dita"><apiname>DPowerHandler</apiname></xref> does
       
    57 provide two functions: <xref href="GUID-761AE02B-41A6-35EA-AA9F-0AEEFF67A6F7.dita#GUID-761AE02B-41A6-35EA-AA9F-0AEEFF67A6F7/GUID-01C1C7F2-CC98-303F-B044-90C1B96304B6"><apiname>DPowerHandler::SetCurrentConsumption()</apiname></xref> and <xref href="GUID-761AE02B-41A6-35EA-AA9F-0AEEFF67A6F7.dita#GUID-761AE02B-41A6-35EA-AA9F-0AEEFF67A6F7/GUID-96524179-926E-371A-9694-235C4D3B6163"><apiname>DPowerHandler::DeltaCurrentConsumption()</apiname></xref> that
       
    58 a power handler can use to track the peripheral's power consumption. Note
       
    59 that this is not based on actual measurements. </p> <p> <codeph>SetCurrentConsumption()</codeph> sets
       
    60 a target current consumption, usually at driver creation time. </p> <p> <codeph>DeltaCurrentConsumption()</codeph> changes
       
    61 this target current consumption value, specifying a positive or a negative
       
    62 value as appropriate; this might be called in response to an operation that
       
    63 is about to start. </p> <p>Although we have described the context in which
       
    64 these functions would be used, we recommend that you do not use them. </p> </li>
       
    65 <li id="GUID-54F4071B-E8E3-5EC3-A7F3-26F74451C707"><p>Fixed media drivers
       
    66 do not have a power handler. This means there is currently no mechanism to
       
    67 power down media drivers and the associated fixed media when the system transitions
       
    68 to a low power state. </p> </li>
       
    69 <li id="GUID-AF58E9DB-F1E9-5802-A9E8-8744CBA6C461"><p>The <codeph>__NEW_POWER_HANDLERS</codeph> macro
       
    70 is used to maintain backwards compatibility with the power model used in previous
       
    71 versions of Symbian OS. If this macro is <i>not</i> defined, it is possible
       
    72 for power handlers to revert back to the behaviour they present in Kernel
       
    73 Architecture 1 (EKA1). </p> <p>If implementing an old style power handler,
       
    74 the following functions will have to have an implementation provided by the
       
    75 peripheral driver: </p> <codeblock id="GUID-8D7F6D5A-01C7-5F7B-BE25-11D4D3110A26" xml:space="preserve">virtual TInt DoPowerUp()
       
    76 virtual void DoPowerDown(TUint32 /* aPowerDownMask */)
       
    77 virtual void DoEmergencyPowerDown()
       
    78           </codeblock> <p>If using at least an old style power handler the
       
    79 power manager will not complete any powering down (transition to <i>Off</i> or <i>Standby</i>).
       
    80 Thus it is recommended that they not be used. </p> </li>
       
    81 </ol>
       
    82 <section id="GUID-6A4484AA-B10E-54D8-B32B-05583EB66841"><title>DPowerHandler::PowerDown()</title> <codeblock id="GUID-61142DAF-895E-5432-B9DB-01CF88C24F26" xml:space="preserve">virtual void PowerDown(TPowerState) = 0;</codeblock> <p><b>When
       
    83 is it called?</b> </p> <p> <xref href="GUID-761AE02B-41A6-35EA-AA9F-0AEEFF67A6F7.dita#GUID-761AE02B-41A6-35EA-AA9F-0AEEFF67A6F7/GUID-578DB5FB-731D-36B2-A459-AAC7F250D726"><apiname>DPowerHandler::PowerDown()</apiname></xref> is
       
    84 called by the <xref href="GUID-0C435514-EEC6-5660-BB5F-535790349632.dita#GUID-0C435514-EEC6-5660-BB5F-535790349632/GUID-330F07B2-BBDF-5675-B7D5-FF6B25DD03F4">Power
       
    85 manager</xref> during a transition to the <i>Standby</i> or the <i>Off</i> state.
       
    86 The <xref href="GUID-87AB8B20-04EE-31D2-8F3D-EA904D05B8D0.dita"><apiname>TPowerState</apiname></xref> argument specifies which of the two power
       
    87 states is the target. </p> <p><b>Implementation issues</b> </p> <ol id="GUID-60A913E7-16A2-5350-ACC0-448B980C045E">
       
    88 <li id="GUID-98DC816F-B1DE-5524-BCD6-A1AA9DADC05F"><p>After receiving a request
       
    89 to power down, as a result of a system transition to the <i>Standby</i> or <i>Off</i> states,
       
    90 a peripheral driver should perform the necessary activity to power down the
       
    91 peripheral and ancillary hardware, unless it is required for the detection
       
    92 of wake-up events. This activity might include requesting the removal of the
       
    93 power supply and any other power resources. </p> </li>
       
    94 <li id="GUID-3EA32F60-D2B5-522D-901F-91B9D802B67F"><p>The power down operation
       
    95 can be done in the same thread in which <codeph>PowerDown()</codeph> runs,
       
    96 i.e. synchronously, or it can run in another thread, i.e. asynchronously.
       
    97 You would probably implement power down in another thread if the operation
       
    98 were potentially slow. Once the peripheral has powered down, it must inform
       
    99 the power manager by calling <xref href="GUID-761AE02B-41A6-35EA-AA9F-0AEEFF67A6F7.dita#GUID-761AE02B-41A6-35EA-AA9F-0AEEFF67A6F7/GUID-EBE8CFF8-50BD-3AC3-A4C8-47094DA5674D"><apiname>DPowerHandler::PowerDownDone()</apiname></xref>,
       
   100 and this function can be called from the same thread in which <codeph>PowerDown()</codeph> runs,
       
   101 or it can be called from another thread. Two points to note: </p> <ul>
       
   102 <li id="GUID-E108AAD0-6E84-5BF5-91DA-0EBACD909DA5"><p> <codeph>PowerDownDone()</codeph> can
       
   103 be called before or after <codeph>PowerDown()</codeph> returns </p> </li>
       
   104 <li id="GUID-0341DC51-FAFA-5CA0-8F11-E1BD7765DCD5"><p> <codeph>PowerDownDone()</codeph> cannot
       
   105 be called before <codeph>PowerDown()</codeph> has been entered. </p> </li>
       
   106 </ul> </li>
       
   107 <li id="GUID-0DF3E109-1EE8-5760-BE17-0998CF32EC97"><p> <codeph>PowerDown()</codeph> is
       
   108 only called on a transition to the <i>Standby</i> or the <i>Off</i> state.
       
   109 If the peripheral hardware is powered down when the peripheral driver is closed,
       
   110 or when the hardware resources are relinquished by the driver, then this is
       
   111 managed by the driver alone. </p> </li>
       
   112 <li id="GUID-C3E38B61-7417-5C1A-AB24-355738BCD3EF"><p>There are synchronisation
       
   113 issues related to calls to the <xref href="GUID-761AE02B-41A6-35EA-AA9F-0AEEFF67A6F7.dita#GUID-761AE02B-41A6-35EA-AA9F-0AEEFF67A6F7/GUID-E8353DF6-B21B-383F-99AB-94B6B5139E47"><apiname>DPowerHandler::Add()</apiname></xref> and <xref href="GUID-761AE02B-41A6-35EA-AA9F-0AEEFF67A6F7.dita#GUID-761AE02B-41A6-35EA-AA9F-0AEEFF67A6F7/GUID-FD0BA400-FDCD-3E8C-9130-992A95A3FF84"><apiname>DPowerHandler::Remove()</apiname></xref> functions. <xref href="GUID-761AE02B-41A6-35EA-AA9F-0AEEFF67A6F7.dita#GUID-761AE02B-41A6-35EA-AA9F-0AEEFF67A6F7/GUID-E8353DF6-B21B-383F-99AB-94B6B5139E47"><apiname>DPowerHandler::Add()</apiname></xref> is called by the peripheral driver when the driver object is created. This
       
   114 registers the power handler with the power manager so that so that the driver
       
   115 can receive notification of power state transitions. Conversely, <xref href="GUID-761AE02B-41A6-35EA-AA9F-0AEEFF67A6F7.dita#GUID-761AE02B-41A6-35EA-AA9F-0AEEFF67A6F7/GUID-FD0BA400-FDCD-3E8C-9130-992A95A3FF84"><apiname>DPowerHandler::Remove()</apiname></xref> is
       
   116 called when the peripheral driver is in the process of being destroyed. This
       
   117 de-registers the power handler so that the driver is no longer notified of
       
   118 power state transitions. Calls to <xref href="GUID-761AE02B-41A6-35EA-AA9F-0AEEFF67A6F7.dita#GUID-761AE02B-41A6-35EA-AA9F-0AEEFF67A6F7/GUID-E8353DF6-B21B-383F-99AB-94B6B5139E47"><apiname>DPowerHandler::Add()</apiname></xref>, <xref href="GUID-761AE02B-41A6-35EA-AA9F-0AEEFF67A6F7.dita#GUID-761AE02B-41A6-35EA-AA9F-0AEEFF67A6F7/GUID-FD0BA400-FDCD-3E8C-9130-992A95A3FF84"><apiname>DPowerHandler::Remove()</apiname></xref>, <xref href="GUID-761AE02B-41A6-35EA-AA9F-0AEEFF67A6F7.dita#GUID-761AE02B-41A6-35EA-AA9F-0AEEFF67A6F7/GUID-578DB5FB-731D-36B2-A459-AAC7F250D726"><apiname>DPowerHandler::PowerDown()</apiname></xref> and <xref href="GUID-761AE02B-41A6-35EA-AA9F-0AEEFF67A6F7.dita#GUID-761AE02B-41A6-35EA-AA9F-0AEEFF67A6F7/GUID-DDC564B4-BD12-30E9-B04A-DBA6CFAF8743"><apiname>DPowerHandler::PowerUp()</apiname></xref> can run asynchronously in
       
   119 relation to one another. For example, it is entirely possible that the kernel
       
   120 may be asking the driver to power down while it is being created, or indeed
       
   121 while it is being destroyed. </p> <p>To avoid deadlock, <xref href="GUID-761AE02B-41A6-35EA-AA9F-0AEEFF67A6F7.dita#GUID-761AE02B-41A6-35EA-AA9F-0AEEFF67A6F7/GUID-E8353DF6-B21B-383F-99AB-94B6B5139E47"><apiname>DPowerHandler::Add()</apiname></xref>, <xref href="GUID-761AE02B-41A6-35EA-AA9F-0AEEFF67A6F7.dita#GUID-761AE02B-41A6-35EA-AA9F-0AEEFF67A6F7/GUID-FD0BA400-FDCD-3E8C-9130-992A95A3FF84"><apiname>DPowerHandler::Remove()</apiname></xref>,
       
   122 and the <xref href="GUID-0C435514-EEC6-5660-BB5F-535790349632.dita#GUID-0C435514-EEC6-5660-BB5F-535790349632/GUID-330F07B2-BBDF-5675-B7D5-FF6B25DD03F4">Power
       
   123 manager</xref> functions that call your <xref href="GUID-761AE02B-41A6-35EA-AA9F-0AEEFF67A6F7.dita#GUID-761AE02B-41A6-35EA-AA9F-0AEEFF67A6F7/GUID-578DB5FB-731D-36B2-A459-AAC7F250D726"><apiname>DPowerHandler::PowerDown()</apiname></xref> and
       
   124 your <xref href="GUID-761AE02B-41A6-35EA-AA9F-0AEEFF67A6F7.dita#GUID-761AE02B-41A6-35EA-AA9F-0AEEFF67A6F7/GUID-DDC564B4-BD12-30E9-B04A-DBA6CFAF8743"><apiname>DPowerHandler::PowerUp()</apiname></xref> functions, all acquire a
       
   125 lock, a <codeph>DMutex</codeph>. While the lock itself is internal to Symbian
       
   126 OS, it does impose a requirement that: </p> <ul>
       
   127 <li id="GUID-9C3D1630-F6BE-5B8F-8528-E6BF769BECAB"><p> <xref href="GUID-761AE02B-41A6-35EA-AA9F-0AEEFF67A6F7.dita#GUID-761AE02B-41A6-35EA-AA9F-0AEEFF67A6F7/GUID-E8353DF6-B21B-383F-99AB-94B6B5139E47"><apiname>DPowerHandler::Add()</apiname></xref>  </p> </li>
       
   128 <li id="GUID-104276CB-95F7-57BD-9988-BEEF1CE3255F"><p> <xref href="GUID-761AE02B-41A6-35EA-AA9F-0AEEFF67A6F7.dita#GUID-761AE02B-41A6-35EA-AA9F-0AEEFF67A6F7/GUID-FD0BA400-FDCD-3E8C-9130-992A95A3FF84"><apiname>DPowerHandler::Remove()</apiname></xref>  </p> </li>
       
   129 <li id="GUID-1B260C33-7697-5574-A623-15D9693DE21F"><p> <xref href="GUID-761AE02B-41A6-35EA-AA9F-0AEEFF67A6F7.dita#GUID-761AE02B-41A6-35EA-AA9F-0AEEFF67A6F7/GUID-578DB5FB-731D-36B2-A459-AAC7F250D726"><apiname>DPowerHandler::PowerDown()</apiname></xref>  </p> </li>
       
   130 <li id="GUID-0EBC4021-B090-5799-B0F6-3B2808FBBAB1"><p> <xref href="GUID-761AE02B-41A6-35EA-AA9F-0AEEFF67A6F7.dita#GUID-761AE02B-41A6-35EA-AA9F-0AEEFF67A6F7/GUID-DDC564B4-BD12-30E9-B04A-DBA6CFAF8743"><apiname>DPowerHandler::PowerUp()</apiname></xref>  </p> </li>
       
   131 </ul> <p>all run in the same thread. A common implementation of <xref href="GUID-761AE02B-41A6-35EA-AA9F-0AEEFF67A6F7.dita#GUID-761AE02B-41A6-35EA-AA9F-0AEEFF67A6F7/GUID-578DB5FB-731D-36B2-A459-AAC7F250D726"><apiname>DPowerHandler::PowerDown()</apiname></xref>,
       
   132 therefore, schedules a DFC to run on the same thread (a DFC queue) as the
       
   133 one that calls <xref href="GUID-761AE02B-41A6-35EA-AA9F-0AEEFF67A6F7.dita#GUID-761AE02B-41A6-35EA-AA9F-0AEEFF67A6F7/GUID-E8353DF6-B21B-383F-99AB-94B6B5139E47"><apiname>DPowerHandler::Add()</apiname></xref> and <xref href="GUID-761AE02B-41A6-35EA-AA9F-0AEEFF67A6F7.dita#GUID-761AE02B-41A6-35EA-AA9F-0AEEFF67A6F7/GUID-FD0BA400-FDCD-3E8C-9130-992A95A3FF84"><apiname>DPowerHandler::Remove()</apiname></xref>. </p> </li>
       
   134 </ol> </section>
       
   135 <section id="GUID-389D4920-2956-5CBE-979E-30C23A0C3E49"><title>DPowerHandler::PowerUp()</title> <codeblock id="GUID-F66A2F92-7C60-5D61-BEAD-392FA5F36830" xml:space="preserve">virtual void PowerUp() = 0;</codeblock> <p><b>When
       
   136 is it called?</b> </p> <p> <xref href="GUID-761AE02B-41A6-35EA-AA9F-0AEEFF67A6F7.dita#GUID-761AE02B-41A6-35EA-AA9F-0AEEFF67A6F7/GUID-DDC564B4-BD12-30E9-B04A-DBA6CFAF8743"><apiname>DPowerHandler::PowerUp()</apiname></xref> is
       
   137 called by the <xref href="GUID-0C435514-EEC6-5660-BB5F-535790349632.dita#GUID-0C435514-EEC6-5660-BB5F-535790349632/GUID-330F07B2-BBDF-5675-B7D5-FF6B25DD03F4">Power
       
   138 manager</xref> during a transition from the <i>Standby</i> state back to the <i>Active</i> state.
       
   139 It is up to the peripheral driver to decide whether or not to power up the
       
   140 peripheral. </p> <p><b>Implementation issues</b> </p> <ol id="GUID-A0A555C9-516B-5408-AC8D-86F7F37501CA">
       
   141 <li id="GUID-FF569561-DFB4-59F0-9665-34567D9E159A"><p>After receiving a notification
       
   142 to power up, as a result of a system transition from the <i>Standby</i> to
       
   143 the <i>Active</i> state, it is up to the peripheral driver to decide whether
       
   144 or not to power up the peripheral and ancillary hardware. The decision usually
       
   145 depends on whether or not the peripheral driver is currently in use. </p> </li>
       
   146 <li id="GUID-C2317AFC-9615-56B3-83CC-B2A8F515FF01"><p>The power up operation
       
   147 can be done in the same thread in which <codeph>PowerUp()</codeph> runs, i.e.
       
   148 synchronously, or it can run in another thread, i.e. asynchronously. You would
       
   149 probably implement power up in another thread if the operation were potentially
       
   150 slow. Whether or not the peripheral driver intends to power up immediately,
       
   151 it must acknowledge the power up request by calling <xref href="GUID-761AE02B-41A6-35EA-AA9F-0AEEFF67A6F7.dita#GUID-761AE02B-41A6-35EA-AA9F-0AEEFF67A6F7/GUID-BF62042B-FB7B-3D5B-8379-490FBA284A7A"><apiname>DPowerHandler::PowerUpDone()</apiname></xref>,
       
   152 and this function can be called from the same thread in which <codeph>PowerUp()</codeph> runs,
       
   153 or it can be called from another thread. Two points to note: </p> <ul>
       
   154 <li id="GUID-C8BA1C99-2731-56A0-96B1-99BF61DF7A46"><p> <codeph>PowerUpDone()</codeph> can
       
   155 be called before or after <codeph>PowerUp()</codeph> returns </p> </li>
       
   156 <li id="GUID-0CBF462D-12B9-5598-B968-00F69099E409"><p> <codeph>PowerUpDone()</codeph> cannot
       
   157 be called before <codeph>PowerUp()</codeph> has been entered. </p> </li>
       
   158 </ul> </li>
       
   159 <li id="GUID-C64797E0-F77B-55D8-8BBC-C0335174B0DF"><p> <codeph>PowerUp()</codeph> is
       
   160 only called on a transition to the <i>Active</i> state. If the peripheral
       
   161 hardware is powered up when the peripheral driver is opened, or when the hardware
       
   162 resources are first used by the driver, then this is managed by the driver
       
   163 alone. </p> </li>
       
   164 <li id="GUID-534A5CAA-4FF8-596A-AC79-DBFB31ACF1B9"><p>There are synchronisation
       
   165 issues related to calls to the <xref href="GUID-761AE02B-41A6-35EA-AA9F-0AEEFF67A6F7.dita#GUID-761AE02B-41A6-35EA-AA9F-0AEEFF67A6F7/GUID-E8353DF6-B21B-383F-99AB-94B6B5139E47"><apiname>DPowerHandler::Add()</apiname></xref> and <xref href="GUID-761AE02B-41A6-35EA-AA9F-0AEEFF67A6F7.dita#GUID-761AE02B-41A6-35EA-AA9F-0AEEFF67A6F7/GUID-FD0BA400-FDCD-3E8C-9130-992A95A3FF84"><apiname>DPowerHandler::Remove()</apiname></xref> functions. <xref href="GUID-761AE02B-41A6-35EA-AA9F-0AEEFF67A6F7.dita#GUID-761AE02B-41A6-35EA-AA9F-0AEEFF67A6F7/GUID-E8353DF6-B21B-383F-99AB-94B6B5139E47"><apiname>DPowerHandler::Add()</apiname></xref> is called by the peripheral driver when the driver object is created. This
       
   166 registers the power handler with the power manager so that so that the driver
       
   167 can receive notification of power state transitions. Conversely, <xref href="GUID-761AE02B-41A6-35EA-AA9F-0AEEFF67A6F7.dita#GUID-761AE02B-41A6-35EA-AA9F-0AEEFF67A6F7/GUID-FD0BA400-FDCD-3E8C-9130-992A95A3FF84"><apiname>DPowerHandler::Remove()</apiname></xref> is
       
   168 called when the peripheral driver is in the process of being destroyed. This
       
   169 de-registers the power handler so that the driver is no longer notified of
       
   170 power state transitions. Calls to <xref href="GUID-761AE02B-41A6-35EA-AA9F-0AEEFF67A6F7.dita#GUID-761AE02B-41A6-35EA-AA9F-0AEEFF67A6F7/GUID-E8353DF6-B21B-383F-99AB-94B6B5139E47"><apiname>DPowerHandler::Add()</apiname></xref>, <xref href="GUID-761AE02B-41A6-35EA-AA9F-0AEEFF67A6F7.dita#GUID-761AE02B-41A6-35EA-AA9F-0AEEFF67A6F7/GUID-FD0BA400-FDCD-3E8C-9130-992A95A3FF84"><apiname>DPowerHandler::Remove()</apiname></xref>, <xref href="GUID-761AE02B-41A6-35EA-AA9F-0AEEFF67A6F7.dita#GUID-761AE02B-41A6-35EA-AA9F-0AEEFF67A6F7/GUID-578DB5FB-731D-36B2-A459-AAC7F250D726"><apiname>DPowerHandler::PowerDown()</apiname></xref> and <xref href="GUID-761AE02B-41A6-35EA-AA9F-0AEEFF67A6F7.dita#GUID-761AE02B-41A6-35EA-AA9F-0AEEFF67A6F7/GUID-DDC564B4-BD12-30E9-B04A-DBA6CFAF8743"><apiname>DPowerHandler::PowerUp()</apiname></xref> can run asynchronoulsy in
       
   171 relation to one another. For example, it is entirely possible that the kernel
       
   172 may be asking the driver to power down while it is being created, or indeed
       
   173 while it is being destroyed. </p> <p>To avoid deadlock, <xref href="GUID-761AE02B-41A6-35EA-AA9F-0AEEFF67A6F7.dita#GUID-761AE02B-41A6-35EA-AA9F-0AEEFF67A6F7/GUID-E8353DF6-B21B-383F-99AB-94B6B5139E47"><apiname>DPowerHandler::Add()</apiname></xref>, <xref href="GUID-761AE02B-41A6-35EA-AA9F-0AEEFF67A6F7.dita#GUID-761AE02B-41A6-35EA-AA9F-0AEEFF67A6F7/GUID-FD0BA400-FDCD-3E8C-9130-992A95A3FF84"><apiname>DPowerHandler::Remove()</apiname></xref>,
       
   174 and the <xref href="GUID-0C435514-EEC6-5660-BB5F-535790349632.dita#GUID-0C435514-EEC6-5660-BB5F-535790349632/GUID-330F07B2-BBDF-5675-B7D5-FF6B25DD03F4">power
       
   175 manager</xref> functions that call your <xref href="GUID-761AE02B-41A6-35EA-AA9F-0AEEFF67A6F7.dita#GUID-761AE02B-41A6-35EA-AA9F-0AEEFF67A6F7/GUID-578DB5FB-731D-36B2-A459-AAC7F250D726"><apiname>DPowerHandler::PowerDown()</apiname></xref> and
       
   176 your <xref href="GUID-761AE02B-41A6-35EA-AA9F-0AEEFF67A6F7.dita#GUID-761AE02B-41A6-35EA-AA9F-0AEEFF67A6F7/GUID-DDC564B4-BD12-30E9-B04A-DBA6CFAF8743"><apiname>DPowerHandler::PowerUp()</apiname></xref> functions, all acquire a
       
   177 lock, a <codeph>DMutex</codeph>. While the lock itself is internal to Symbian
       
   178 OS, it does impose a requirement that: </p> <ul>
       
   179 <li id="GUID-6A297274-057E-5549-A2D6-6E4FE0D1FDD0"><p> <xref href="GUID-761AE02B-41A6-35EA-AA9F-0AEEFF67A6F7.dita#GUID-761AE02B-41A6-35EA-AA9F-0AEEFF67A6F7/GUID-E8353DF6-B21B-383F-99AB-94B6B5139E47"><apiname>DPowerHandler::Add()</apiname></xref>  </p> </li>
       
   180 <li id="GUID-8C902FBC-D818-5A56-ADBB-5B7E0C01C192"><p> <xref href="GUID-761AE02B-41A6-35EA-AA9F-0AEEFF67A6F7.dita#GUID-761AE02B-41A6-35EA-AA9F-0AEEFF67A6F7/GUID-FD0BA400-FDCD-3E8C-9130-992A95A3FF84"><apiname>DPowerHandler::Remove()</apiname></xref>  </p> </li>
       
   181 <li id="GUID-352D5DD5-FE31-5FF9-A988-E0E4D31BD687"><p> <xref href="GUID-761AE02B-41A6-35EA-AA9F-0AEEFF67A6F7.dita#GUID-761AE02B-41A6-35EA-AA9F-0AEEFF67A6F7/GUID-578DB5FB-731D-36B2-A459-AAC7F250D726"><apiname>DPowerHandler::PowerDown()</apiname></xref>  </p> </li>
       
   182 <li id="GUID-BB116FED-0F67-57B1-98DA-1F5A3BF2E61D"><p> <xref href="GUID-761AE02B-41A6-35EA-AA9F-0AEEFF67A6F7.dita#GUID-761AE02B-41A6-35EA-AA9F-0AEEFF67A6F7/GUID-DDC564B4-BD12-30E9-B04A-DBA6CFAF8743"><apiname>DPowerHandler::PowerUp()</apiname></xref>  </p> </li>
       
   183 </ul> <p>all run in the same thread. A common implementation of <xref href="GUID-761AE02B-41A6-35EA-AA9F-0AEEFF67A6F7.dita#GUID-761AE02B-41A6-35EA-AA9F-0AEEFF67A6F7/GUID-DDC564B4-BD12-30E9-B04A-DBA6CFAF8743"><apiname>DPowerHandler::PowerUp()</apiname></xref>,
       
   184 therefore, schedules a DFC to run on the same thread (a DFC queue) as the
       
   185 one that calls <xref href="GUID-761AE02B-41A6-35EA-AA9F-0AEEFF67A6F7.dita#GUID-761AE02B-41A6-35EA-AA9F-0AEEFF67A6F7/GUID-E8353DF6-B21B-383F-99AB-94B6B5139E47"><apiname>DPowerHandler::Add()</apiname></xref> and <xref href="GUID-761AE02B-41A6-35EA-AA9F-0AEEFF67A6F7.dita#GUID-761AE02B-41A6-35EA-AA9F-0AEEFF67A6F7/GUID-FD0BA400-FDCD-3E8C-9130-992A95A3FF84"><apiname>DPowerHandler::Remove()</apiname></xref>. </p> </li>
       
   186 </ol> </section>
       
   187 </conbody></concept>