Adaptation/GUID-A789E0D6-74B2-517D-B73A-F9B11794F175.dita
changeset 15 307f4279f433
equal deleted inserted replaced
14:578be2adaf3e 15:307f4279f433
       
     1 <?xml version="1.0" encoding="utf-8"?>
       
     2 <!-- Copyright (c) 2007-2010 Nokia Corporation and/or its subsidiary(-ies) All rights reserved. -->
       
     3 <!-- This component and the accompanying materials are made available under the terms of the License 
       
     4 "Eclipse Public License v1.0" which accompanies this distribution, 
       
     5 and is available at the URL "http://www.eclipse.org/legal/epl-v10.html". -->
       
     6 <!-- Initial Contributors:
       
     7     Nokia Corporation - initial contribution.
       
     8 Contributors: 
       
     9 -->
       
    10 <!DOCTYPE concept
       
    11   PUBLIC "-//OASIS//DTD DITA Concept//EN" "concept.dtd">
       
    12 <concept id="GUID-A789E0D6-74B2-517D-B73A-F9B11794F175" xml:lang="en"><title>Peripheral Driver Power Implementation Tutorial</title><shortdesc>Describes an implementation of the <codeph>DPowerHandler</codeph> class.</shortdesc><prolog><metadata><keywords/></metadata></prolog><conbody>
       
    13 <p>Peripheral driver power management is based on the <xref href="GUID-761AE02B-41A6-35EA-AA9F-0AEEFF67A6F7.dita"><apiname>DPowerHandler</apiname></xref> class. This is a class that defines the interface that the driver
       
    14 must provide to the generic kernel side power manager. </p>
       
    15 <p>The class also provides the necessary support functions. The class
       
    16 is defined as: </p>
       
    17 <codeblock id="GUID-C34B90B1-5AB2-51E4-A7C9-01601B8698F6" xml:space="preserve">class DPowerHandler : public DBase
       
    18     {
       
    19 public:
       
    20     IMPORT_C ~DPowerHandler();
       
    21 public:
       
    22     IMPORT_C DPowerHandler(const TDesC&amp; aName);
       
    23     IMPORT_C void Add();
       
    24     IMPORT_C void Remove();
       
    25     IMPORT_C void PowerUpDone();
       
    26     IMPORT_C void PowerDownDone();
       
    27     IMPORT_C void SetCurrentConsumption(TInt aCurrent);
       
    28     IMPORT_C void DeltaCurrentConsumption(TInt aCurrent);
       
    29 public: 
       
    30     virtual void PowerDown(TPowerState aTargetState) = 0;
       
    31     virtual void PowerUp() = 0;
       
    32 private:
       
    33     ...
       
    34     };
       
    35       </codeblock>
       
    36 <p>Typically, at least one power handler object is implemented by
       
    37 the peripheral driver. In some cases the peripheral driver interface
       
    38 class may derive from <xref href="GUID-761AE02B-41A6-35EA-AA9F-0AEEFF67A6F7.dita"><apiname>DPowerHandler</apiname></xref>, in others
       
    39 it creates and owns an instance of a <xref href="GUID-761AE02B-41A6-35EA-AA9F-0AEEFF67A6F7.dita"><apiname>DPowerHandler</apiname></xref> derived class. </p>
       
    40 <p>The first eight functions are exported from the kernel, <filepath>EKERN.EXE</filepath>, while the remaining two pure virtual functions
       
    41 are implemented by the peripheral driver. </p>
       
    42 <ul>
       
    43 <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>
       
    44 <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>
       
    45 </ul>
       
    46 <p>Notes: </p>
       
    47 <ol id="GUID-C1640CE7-AF3E-5EF4-9D4C-B44F19B83AB3">
       
    48 <li id="GUID-757692DC-EE42-577F-8D92-AC1C61A7C381"><p>Current consumption
       
    49 monitoring does not have a full implementation in the power manager
       
    50 at present. It is unclear whether this will be ever required. However, <xref href="GUID-761AE02B-41A6-35EA-AA9F-0AEEFF67A6F7.dita"><apiname>DPowerHandler</apiname></xref> does 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
       
    51 a power handler can use to track the peripheral's power consumption.
       
    52 Note that this is not based on actual measurements. </p> <p> <codeph>SetCurrentConsumption()</codeph> sets a target current consumption,
       
    53 usually at driver creation time. </p> <p> <codeph>DeltaCurrentConsumption()</codeph> changes this target current consumption value, specifying a positive
       
    54 or a negative value as appropriate; this might be called in response
       
    55 to an operation that is about to start. </p> <p>Although we have described
       
    56 the context in which these functions would be used, we recommend that
       
    57 you do not use them. </p> </li>
       
    58 <li id="GUID-54F4071B-E8E3-5EC3-A7F3-26F74451C707"><p>Fixed media
       
    59 drivers do not have a power handler. This means there is currently
       
    60 no mechanism to power down media drivers and the associated fixed
       
    61 media when the system transitions to a low power state. </p> </li>
       
    62 <li id="GUID-AF58E9DB-F1E9-5802-A9E8-8744CBA6C461"><p>The <codeph>__NEW_POWER_HANDLERS</codeph> macro is used to maintain backwards
       
    63 compatibility with the power model used in previous versions of Symbian
       
    64 platform. If this macro is <i>not</i> defined, it is possible for
       
    65 power handlers to revert back to the behavior they present in Kernel
       
    66 Architecture 1 (EKA1). </p> <p>If implementing an old style power
       
    67 handler, the following functions will have to have an implementation
       
    68 provided by the peripheral driver: </p> <codeblock id="GUID-8D7F6D5A-01C7-5F7B-BE25-11D4D3110A26" xml:space="preserve">virtual TInt DoPowerUp()
       
    69 virtual void DoPowerDown(TUint32 /* aPowerDownMask */)
       
    70 virtual void DoEmergencyPowerDown()
       
    71           </codeblock> <p>If using at least an old style power handler
       
    72 the power manager will not complete any powering down (transition
       
    73 to <i>Off</i> or <i>Standby</i>). Thus it is recommended that they
       
    74 not be used. </p> </li>
       
    75 </ol>
       
    76 <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 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 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 manager</xref> during a transition to the <i>Standby</i> or
       
    77 the <i>Off</i> state. The <xref href="GUID-87AB8B20-04EE-31D2-8F3D-EA904D05B8D0.dita"><apiname>TPowerState</apiname></xref> argument
       
    78 specifies which of the two power states is the target. </p> <p><b>Implementation issues</b> </p> <ol id="GUID-60A913E7-16A2-5350-ACC0-448B980C045E">
       
    79 <li id="GUID-98DC816F-B1DE-5524-BCD6-A1AA9DADC05F"><p>After receiving
       
    80 a request to power down, as a result of a system transition to the <i>Standby</i> or <i>Off</i> states, a peripheral driver should perform
       
    81 the necessary activity to power down the peripheral and ancillary
       
    82 hardware, unless it is required for the detection of wake-up events.
       
    83 This activity might include requesting the removal of the power supply
       
    84 and any other power resources. </p> </li>
       
    85 <li id="GUID-3EA32F60-D2B5-522D-901F-91B9D802B67F"><p>The power down
       
    86 operation can be done in the same thread in which <codeph>PowerDown()</codeph> runs, i.e. synchronously, or it can run in another thread, i.e.
       
    87 asynchronously. You would probably implement power down in another
       
    88 thread if the operation were potentially slow. Once the peripheral
       
    89 has powered down, it must inform 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>, and this function can be
       
    90 called from the same thread in which <codeph>PowerDown()</codeph> runs,
       
    91 or it can be called from another thread. Two points to note: </p> <ul>
       
    92 <li id="GUID-E108AAD0-6E84-5BF5-91DA-0EBACD909DA5"><p> <codeph>PowerDownDone()</codeph> can be called before or after <codeph>PowerDown()</codeph> returns </p> </li>
       
    93 <li id="GUID-0341DC51-FAFA-5CA0-8F11-E1BD7765DCD5"><p> <codeph>PowerDownDone()</codeph> cannot be called before <codeph>PowerDown()</codeph> has been entered. </p> </li>
       
    94 </ul> </li>
       
    95 <li id="GUID-0DF3E109-1EE8-5760-BE17-0998CF32EC97"><p> <codeph>PowerDown()</codeph> is only called on a transition to the <i>Standby</i> or the <i>Off</i> state. If the peripheral hardware is powered down when the peripheral
       
    96 driver is closed, or when the hardware resources are relinquished
       
    97 by the driver, then this is managed by the driver alone. </p> </li>
       
    98 <li id="GUID-C3E38B61-7417-5C1A-AB24-355738BCD3EF"><p>There are synchronisation
       
    99 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
       
   100 when the driver object is created. This registers the power handler
       
   101 with the power manager so that so that the driver can receive notification
       
   102 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 called when the peripheral driver is in the process of being
       
   103 destroyed. This de-registers the power handler so that the driver
       
   104 is no longer notified of 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 relation to one another. For example,
       
   105 it is entirely possible that the kernel may be asking the driver to
       
   106 power down while it is being created, or indeed while it is being
       
   107 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>, and the <xref href="GUID-0C435514-EEC6-5660-BB5F-535790349632.dita#GUID-0C435514-EEC6-5660-BB5F-535790349632/GUID-330F07B2-BBDF-5675-B7D5-FF6B25DD03F4">Power 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 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,
       
   108 all acquire a lock, a <codeph>DMutex</codeph>. While the lock itself
       
   109 is internal to Symbian platform, it does impose a requirement that: </p> <ul>
       
   110 <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>
       
   111 <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>
       
   112 <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>
       
   113 <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>
       
   114 </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>, therefore, schedules a DFC
       
   115 to run on the same thread (a DFC queue) as the 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>
       
   116 </ol> </section>
       
   117 <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 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 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 manager</xref> during a transition from the <i>Standby</i> state
       
   118 back to the <i>Active</i> state. It is up to the peripheral driver
       
   119 to decide whether or not to power up the peripheral. </p> <p><b>Implementation
       
   120 issues</b> </p> <ol id="GUID-A0A555C9-516B-5408-AC8D-86F7F37501CA">
       
   121 <li id="GUID-FF569561-DFB4-59F0-9665-34567D9E159A"><p>After receiving
       
   122 a notification to power up, as a result of a system transition from
       
   123 the <i>Standby</i> to the <i>Active</i> state, it is up to the peripheral
       
   124 driver to decide whether or not to power up the peripheral and ancillary
       
   125 hardware. The decision usually depends on whether or not the peripheral
       
   126 driver is currently in use. </p> </li>
       
   127 <li id="GUID-C2317AFC-9615-56B3-83CC-B2A8F515FF01"><p>The power up
       
   128 operation can be done in the same thread in which <codeph>PowerUp()</codeph> runs, i.e. synchronously, or it can run in another thread, i.e.
       
   129 asynchronously. You would probably implement power up in another thread
       
   130 if the operation were potentially slow. Whether or not the peripheral
       
   131 driver intends to power up immediately, it must acknowledge the power
       
   132 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>, and this function can be called from the same thread in which <codeph>PowerUp()</codeph> runs, or it can be called from another thread.
       
   133 Two points to note: </p> <ul>
       
   134 <li id="GUID-C8BA1C99-2731-56A0-96B1-99BF61DF7A46"><p> <codeph>PowerUpDone()</codeph> can be called before or after <codeph>PowerUp()</codeph> returns </p> </li>
       
   135 <li id="GUID-0CBF462D-12B9-5598-B968-00F69099E409"><p> <codeph>PowerUpDone()</codeph> cannot be called before <codeph>PowerUp()</codeph> has been entered. </p> </li>
       
   136 </ul> </li>
       
   137 <li id="GUID-C64797E0-F77B-55D8-8BBC-C0335174B0DF"><p> <codeph>PowerUp()</codeph> is only called on a transition to the <i>Active</i> state. If the
       
   138 peripheral hardware is powered up when the peripheral driver is opened,
       
   139 or when the hardware resources are first used by the driver, then
       
   140 this is managed by the driver alone. </p> </li>
       
   141 <li id="GUID-534A5CAA-4FF8-596A-AC79-DBFB31ACF1B9"><p>There are synchronisation
       
   142 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
       
   143 when the driver object is created. This registers the power handler
       
   144 with the power manager so that so that the driver can receive notification
       
   145 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 called when the peripheral driver is in the process of being
       
   146 destroyed. This de-registers the power handler so that the driver
       
   147 is no longer notified of 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 relation to one another. For example,
       
   148 it is entirely possible that the kernel may be asking the driver to
       
   149 power down while it is being created, or indeed while it is being
       
   150 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>, and the <xref href="GUID-0C435514-EEC6-5660-BB5F-535790349632.dita#GUID-0C435514-EEC6-5660-BB5F-535790349632/GUID-330F07B2-BBDF-5675-B7D5-FF6B25DD03F4">power 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 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,
       
   151 all acquire a lock, a <codeph>DMutex</codeph>. While the lock itself
       
   152 is internal to Symbian platform, it does impose a requirement that: </p> <ul>
       
   153 <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>
       
   154 <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>
       
   155 <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>
       
   156 <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>
       
   157 </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>, therefore, schedules a DFC to
       
   158 run on the same thread (a DFC queue) as the 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>
       
   159 </ol> </section>
       
   160 </conbody></concept>