# HG changeset patch # User hgs # Date 1286190959 -3600 # Node ID 2bfb1feef9de13558d761a09bbcb8a87d709e503 # Parent 957c583b417baf69a26e3b8d5631a2565e307049 201039_08 diff -r 957c583b417b -r 2bfb1feef9de kernel/eka/bmarm/ekernsmp.def --- a/kernel/eka/bmarm/ekernsmp.def Mon Oct 04 12:03:52 2010 +0100 +++ b/kernel/eka/bmarm/ekernsmp.def Mon Oct 04 12:15:59 2010 +0100 @@ -1058,4 +1058,5 @@ SetKeyOffset__10RArrayBasei @ 1057 NONAME R3UNUSED ; RArrayBase::SetKeyOffset(int) CpuRetires__5Cache @ 1058 NONAME R3UNUSED ; Cache::CpuRetires(void) KernelRetires__5Cache @ 1059 NONAME R3UNUSED ; Cache::KernelRetires(void) + Register__16DPowerControllerUi @ 1060 NONAME R3UNUSED ; DPowerController::Register(unsigned int) diff -r 957c583b417b -r 2bfb1feef9de kernel/eka/bmarm/ekernu.def --- a/kernel/eka/bmarm/ekernu.def Mon Oct 04 12:03:52 2010 +0100 +++ b/kernel/eka/bmarm/ekernu.def Mon Oct 04 12:15:59 2010 +0100 @@ -1055,3 +1055,4 @@ SetKeyOffset__10RArrayBasei @ 1054 NONAME R3UNUSED ; RArrayBase::SetKeyOffset(int) CpuRetires__5Cache @ 1055 NONAME R3UNUSED ; Cache::CpuRetires(void) KernelRetires__5Cache @ 1056 NONAME R3UNUSED ; Cache::KernelRetires(void) + Register__16DPowerControllerUi @ 1057 NONAME R3UNUSED ; DPowerController::Register(unsigned int) diff -r 957c583b417b -r 2bfb1feef9de kernel/eka/bwins/ekernu.def --- a/kernel/eka/bwins/ekernu.def Mon Oct 04 12:03:52 2010 +0100 +++ b/kernel/eka/bwins/ekernu.def Mon Oct 04 12:15:59 2010 +0100 @@ -938,4 +938,5 @@ ?SetKeyOffset@RArrayBase@@IAEXH@Z @ 937 NONAME ; void RArrayBase::SetKeyOffset(int) ?CpuRetires@Cache@@SAXXZ @ 938 NONAME ; public: static void __cdecl Cache::CpuRetires(void) ?KernelRetires@Cache@@SAXXZ @ 939 NONAME ; public: static void __cdecl Cache::KernelRetires(void) + ?Register@DPowerController@@QAEXI@Z @ 940 NONAME ; public: void __thiscall DPowerController::Register(unsigned int) diff -r 957c583b417b -r 2bfb1feef9de kernel/eka/bx86/ekernsmp.def --- a/kernel/eka/bx86/ekernsmp.def Mon Oct 04 12:03:52 2010 +0100 +++ b/kernel/eka/bx86/ekernsmp.def Mon Oct 04 12:15:59 2010 +0100 @@ -1015,4 +1015,5 @@ ?SetKeyOffset@RArrayBase@@IAEXH@Z @ 1014 NONAME ; void RArrayBase::SetKeyOffset(int) ?CpuRetires@Cache@@SAXXZ @ 1015 NONAME ; public: static void __cdecl Cache::CpuRetires(void) ?KernelRetires@Cache@@SAXXZ @ 1016 NONAME ; public: static void __cdecl Cache::KernelRetires(void) + ?Register@DPowerController@@QAEXI@Z @ 1017 NONAME ; public: void __thiscall DPowerController::Register(unsigned int) diff -r 957c583b417b -r 2bfb1feef9de kernel/eka/bx86/ekernu.def --- a/kernel/eka/bx86/ekernu.def Mon Oct 04 12:03:52 2010 +0100 +++ b/kernel/eka/bx86/ekernu.def Mon Oct 04 12:15:59 2010 +0100 @@ -960,4 +960,5 @@ ?SetKeyOffset@RArrayBase@@IAEXH@Z @ 959 NONAME ; void RArrayBase::SetKeyOffset(int) ?CpuRetires@Cache@@SAXXZ @ 960 NONAME ; public: static void __cdecl Cache::CpuRetires(void) ?KernelRetires@Cache@@SAXXZ @ 961 NONAME ; public: static void __cdecl Cache::KernelRetires(void) + ?Register@DPowerController@@QAEXI@Z @ 962 NONAME ; public: void __thiscall DPowerController::Register(unsigned int) diff -r 957c583b417b -r 2bfb1feef9de kernel/eka/bx86gcc/ekernsmp.def --- a/kernel/eka/bx86gcc/ekernsmp.def Mon Oct 04 12:03:52 2010 +0100 +++ b/kernel/eka/bx86gcc/ekernsmp.def Mon Oct 04 12:15:59 2010 +0100 @@ -1104,7 +1104,5 @@ _ZN5Cache10CpuRetiresEv @ 1103 NONAME _ZN5Cache13KernelRetiresEv @ 1104 NONAME _ZN9TRawEvent3SetENS_5TTypeEiiih @ 1105 NONAME - - - - + _ZN16DPowerController8RegisterEj @ 1106 NONAME + \ No newline at end of file diff -r 957c583b417b -r 2bfb1feef9de kernel/eka/bx86gcc/ekernu.def --- a/kernel/eka/bx86gcc/ekernu.def Mon Oct 04 12:03:52 2010 +0100 +++ b/kernel/eka/bx86gcc/ekernu.def Mon Oct 04 12:15:59 2010 +0100 @@ -1043,4 +1043,5 @@ _ZN10RArrayBase12SetKeyOffsetEi @ 1042 NONAME _ZN5Cache10CpuRetiresEv @ 1043 NONAME _ZN5Cache13KernelRetiresEv @ 1044 NONAME + _ZN16DPowerController8RegisterEj @ 1045 NONAME diff -r 957c583b417b -r 2bfb1feef9de kernel/eka/eabi/ekernsmp.def --- a/kernel/eka/eabi/ekernsmp.def Mon Oct 04 12:03:52 2010 +0100 +++ b/kernel/eka/eabi/ekernsmp.def Mon Oct 04 12:15:59 2010 +0100 @@ -1192,4 +1192,5 @@ _ZN10RArrayBase12SetKeyOffsetEi @ 1191 NONAME _ZN5Cache10CpuRetiresEv @ 1192 NONAME _ZN5Cache13KernelRetiresEv @ 1193 NONAME + _ZN16DPowerController8RegisterEj @ 1194 NONAME diff -r 957c583b417b -r 2bfb1feef9de kernel/eka/eabi/ekernu.def --- a/kernel/eka/eabi/ekernu.def Mon Oct 04 12:03:52 2010 +0100 +++ b/kernel/eka/eabi/ekernu.def Mon Oct 04 12:15:59 2010 +0100 @@ -1184,4 +1184,5 @@ _ZN10RArrayBase12SetKeyOffsetEi @ 1183 NONAME _ZN5Cache10CpuRetiresEv @ 1184 NONAME _ZN5Cache13KernelRetiresEv @ 1185 NONAME + _ZN16DPowerController8RegisterEj @ 1186 NONAME diff -r 957c583b417b -r 2bfb1feef9de kernel/eka/include/e32ver.h --- a/kernel/eka/include/e32ver.h Mon Oct 04 12:03:52 2010 +0100 +++ b/kernel/eka/include/e32ver.h Mon Oct 04 12:15:59 2010 +0100 @@ -28,7 +28,7 @@ const TInt KE32MajorVersionNumber=2; const TInt KE32MinorVersionNumber=0; -const TInt KE32BuildVersionNumber=4005; +const TInt KE32BuildVersionNumber=4006; const TInt KMachineConfigurationMajorVersionNumber=1; const TInt KMachineConfigurationMinorVersionNumber=0; diff -r 957c583b417b -r 2bfb1feef9de kernel/eka/include/kernel/kpower.h --- a/kernel/eka/include/kernel/kpower.h Mon Oct 04 12:03:52 2010 +0100 +++ b/kernel/eka/include/kernel/kpower.h Mon Oct 04 12:15:59 2010 +0100 @@ -66,6 +66,7 @@ public: IMPORT_C DPowerController(); IMPORT_C void Register(); + IMPORT_C void Register(TUint aShutdownTimeoutMs); IMPORT_C void WakeupEvent(); #ifndef __X86__ IMPORT_C TInt RegisterResourceController(DBase* aController, TInt aClientId); diff -r 957c583b417b -r 2bfb1feef9de kernel/eka/kernel/power.cpp --- a/kernel/eka/kernel/power.cpp Mon Oct 04 12:03:52 2010 +0100 +++ b/kernel/eka/kernel/power.cpp Mon Oct 04 12:15:59 2010 +0100 @@ -21,8 +21,10 @@ #include "execs.h" #include "msgqueue.h" -// #define _DEBUG_POWER - +#ifdef _DEBUG +#include +//#define _DEBUG_POWER +#endif /****************************************************************************** * Power Manager - a Power Model implementation @@ -60,9 +62,18 @@ DBatteryMonitor* iBatteryMonitor; DPowerHal* iPowerHal; - TInt iTotalCurrent; + TUint iPslShutdownTimeoutMs; // default = 0 private: +#ifndef _DEBUG_POWER + enum + { + ESHUTDOWN_TIMEOUT = 0xFFFFFFFF // -1 + }; + + TInt iPendingShutdownCount; +#endif + DPowerManager(); @@ -90,6 +101,8 @@ void NotifyWakeupEvent(TInt aReason); + static void ShutDownTimeoutFn(TAny* aArg); + DMutex* iFeatureLock; DThread* iClient; // protected by the system lock TClientRequest* iRequest; // protected by the system lock @@ -142,7 +155,7 @@ return self; } -DPowerManager::DPowerManager() +DPowerManager::DPowerManager() { } @@ -328,7 +341,29 @@ NKern::ThreadLeaveCS(); } -// Called in CS + +void DPowerManager::ShutDownTimeoutFn(TAny* aArg) + { + __KTRACE_OPT(KPOWER,Kern::Printf(">DPowerManager::ShutDownTimeoutFn")); + NFastSemaphore* sem = (NFastSemaphore*)aArg; +#ifdef _DEBUG_POWER + NKern::FSSignal(sem); +#else + TUint SignalCount = __e32_atomic_load_acq32(&(PowerManager->iPendingShutdownCount)); + DPowerHandler* ph = PowerManager->iHandlers; + do + { + ph->iSem = NULL; + ph = ph->iPrev; + }while(ph != PowerManager->iHandlers); + + __e32_atomic_store_rel32(&(PowerManager->iPendingShutdownCount), (TUint)ESHUTDOWN_TIMEOUT); // = -1 + NKern::FSSignalN(sem,SignalCount); + + __KTRACE_OPT(KPOWER,Kern::Printf("PowerManger::PowerDown(0x%x) Enter", iPowerController->iTargetState)); @@ -344,7 +379,12 @@ } __PM_ASSERT(iHandlers); - NFastSemaphore sem(0); + NFastSemaphore shutdownSem(0); + NTimer ntimer; + TDfc dfc(ShutDownTimeoutFn, &shutdownSem); +#ifndef _DEBUG_POWER + iPendingShutdownCount = 0; +#endif DPowerHandler* ph = iHandlers; //Power down in reverse order of handle registration. do @@ -352,25 +392,56 @@ #ifdef _DEBUG_POWER __PM_ASSERT(!(ph->iStatus & DPowerHandler::EDone)); #endif - ph->iSem = &sem; + ph->iSem = &shutdownSem; ph->PowerDown(iPowerController->iTargetState); -#ifdef _DEBUG_POWER - __PM_ASSERT(!(ph->iStatus & DPowerHandler::EDone)); - NKern::FSWait(&sem); // power down drivers one after another to simplify debug - __PM_ASSERT(!ph->iSem); - __PM_ASSERT(ph->iStatus & EDone); - ph->iStatus &= ~EDone; -#endif +#ifndef _DEBUG_POWER + iPendingShutdownCount++; +#else + if(iPslShutdownTimeoutMs>0) + { + // Fire shut down timeout timer + ntimer.OneShot(iPslShutdownTimeoutMs, dfc); + } + + NKern::FSWait(&shutdownSem); // power down drivers one after another to simplify debug + __e32_atomic_and_ord32(&(ph->iStatus), ~DPowerHandler::EDone); + + // timeout condition + if(iPslShutdownTimeoutMs>0 && ph->iSem) + { + __e32_atomic_store_ord_ptr(&ph->iSem, 0); + } + ntimer.Cancel(); +#endif ph = ph->iPrev; }while(ph != iHandlers); #ifndef _DEBUG_POWER + if(iPslShutdownTimeoutMs>0) + { + // Fire shut down timeout timer + ntimer.OneShot(iPslShutdownTimeoutMs, dfc); + } + ph = iHandlers; do { - NKern::FSWait(&sem); + NKern::FSWait(&shutdownSem); + if(__e32_atomic_load_acq32(&iPendingShutdownCount)==ESHUTDOWN_TIMEOUT) + { + iPendingShutdownCount = 0; + NKern::Lock(); + shutdownSem.Reset(); // iPendingShutdownCount could be altered while ShutDownTimeoutFn is running + // reset it to make sure shutdownSem is completely clean. + NKern::Unlock(); + break; + } + __e32_atomic_add_ord32(&iPendingShutdownCount, (TUint)(~0x0)); // iPendingShutDownCount--; ph = ph->iPrev; }while(ph != iHandlers); + + ntimer.Cancel(); + #endif TTickQ::Wait(); @@ -382,6 +453,8 @@ K::SecondQ->WakeUp(); TTickQ::Signal(); + NFastSemaphore powerupSem(0); + ph = iHandlers->iNext; //Power up in same order of handle registration. do @@ -389,14 +462,13 @@ #ifdef _DEBUG_POWER __PM_ASSERT(!(ph->iStatus & DPowerHandler::EDone)); #endif - ph->iSem = &sem; + ph->iSem = &powerupSem; ph->PowerUp(); #ifdef _DEBUG_POWER - __PM_ASSERT(!(ph->iStatus & DPowerHandler::EDone)); - NKern::FSWait(&sem); // power down drivers one after another to simplify debug + NKern::FSWait(&powerupSem); // power down drivers one after another to simplify debug __PM_ASSERT(!ph->iSem); - __PM_ASSERT(ph->iStatus & EDone); - ph->iStatus &= ~EDone; + __PM_ASSERT(ph->iStatus & DPowerHandler::EDone); + ph->iStatus &= ~DPowerHandler::EDone; #endif ph = ph->iNext; }while(ph != iHandlers->iNext); @@ -405,7 +477,7 @@ ph = iHandlers->iNext; do { - NKern::FSWait(&sem); + NKern::FSWait(&powerupSem); ph = ph->iNext; }while(ph != iHandlers->iNext); #endif @@ -420,6 +492,7 @@ return KErrNone; } + /****************************************************************************** * Power Handlers ******************************************************************************/ @@ -578,22 +651,13 @@ /** @deprecated, no replacement */ -EXPORT_C void DPowerHandler::DeltaCurrentConsumption(TInt aDelta) +EXPORT_C void DPowerHandler::DeltaCurrentConsumption(TInt /* aDelta */) { - __e32_atomic_add_ord32(&iCurrent, aDelta); - __PM_ASSERT(iCurrent >= 0); - __e32_atomic_add_ord32(&PowerManager->iTotalCurrent, aDelta); - __PM_ASSERT(PowerManager->iTotalCurrent >= 0); } /** @deprecated, no replacement */ -EXPORT_C void DPowerHandler::SetCurrentConsumption(TInt aCurrent) +EXPORT_C void DPowerHandler::SetCurrentConsumption(TInt /* aCurrent */) { - __PM_ASSERT(aCurrent >= 0); - TInt old = (TInt)__e32_atomic_swp_ord32(&iCurrent, aCurrent); - TInt delta = aCurrent - old; - __e32_atomic_add_ord32(&PowerManager->iTotalCurrent, delta); - __PM_ASSERT(PowerManager->iTotalCurrent >= 0); } /****************************************************************************** @@ -652,6 +716,25 @@ K::PowerModel = PowerManager; } +/** +Registers this power controller object with the power manager. + +The power manager can only use the power controller after registration. + +@param aShutdownTimeoutMs The kernel shut down time out value in msec. + +@pre Calling thread must be in a critical section. +@pre No fast mutex can be held. +@pre Call in a thread context. +@pre Kernel must be unlocked +@pre interrupts enabled +*/ +EXPORT_C void DPowerController::Register(TUint aShutdownTimeoutMs) + { + PowerManager->iPslShutdownTimeoutMs = aShutdownTimeoutMs; + Register(); + } + #ifndef __X86__ /** Registers resource controller with power controller diff -r 957c583b417b -r 2bfb1feef9de kernel/eka/release.txt --- a/kernel/eka/release.txt Mon Oct 04 12:03:52 2010 +0100 +++ b/kernel/eka/release.txt Mon Oct 04 12:15:59 2010 +0100 @@ -1,3 +1,11 @@ +Version 2.00.4006 +================= +(Made by vfebvre 27/09/2010) + +1. erifung + 1. RP540323 REQ:405-4716 kernel side device driver staged shutdown feature + + Version 2.00.4005 ================= (Made by vfebvre 24/09/2010) diff -r 957c583b417b -r 2bfb1feef9de kerneltest/e32test/power/d_lddpowerseqtest.cpp --- a/kerneltest/e32test/power/d_lddpowerseqtest.cpp Mon Oct 04 12:03:52 2010 +0100 +++ b/kerneltest/e32test/power/d_lddpowerseqtest.cpp Mon Oct 04 12:15:59 2010 +0100 @@ -60,6 +60,9 @@ DTest2PowerHandler(); void PowerUp(); void PowerDown(TPowerState); + void ActDead(); +private: + TBool iActDead; }; class DTestFactory : public DLogicalDevice @@ -86,6 +89,8 @@ virtual TInt Request(TInt aReqNo, TAny* a1, TAny* a2); DTest1PowerHandler power1; DTest2PowerHandler power2; +private: + TUint iPslShutdownTimeoutMsBackup; }; @@ -149,6 +154,7 @@ power2.Remove(); //try to remove a handler twice - should not cause any problems power2.Remove(); + ((DTestPowerManager*)(Kern::PowerModel()))->iPslShutdownTimeoutMs = iPslShutdownTimeoutMsBackup; } TInt DTest1::Request(TInt aReqNo, TAny* a1, TAny* a2) @@ -192,10 +198,18 @@ // 'Control' functions... switch(aReqNo) { + // DoControl case RLddTest1::ESET_SLEEPTIME: sleepTime = (TUint)a1; break; + case RLddTest1::EPOWER_ACTDEAD_POWER2: + power2.ActDead(); + break; + case RLddTest1::EPOWER_ESETPOWERDOWNTIMEOUT: + iPslShutdownTimeoutMsBackup = ((DTestPowerManager*)(Kern::PowerModel()))->iPslShutdownTimeoutMs; + ((DTestPowerManager*)(Kern::PowerModel()))->iPslShutdownTimeoutMs = (TUint)a1; + break; } } @@ -209,7 +223,7 @@ // } -DTest2PowerHandler::DTest2PowerHandler():DPowerHandler(KLitPower2) +DTest2PowerHandler::DTest2PowerHandler():DPowerHandler(KLitPower2), iActDead(EFalse) { // // Power handler2 constructor @@ -276,5 +290,14 @@ Kern::RequestComplete(aStatus_down2, KErrNone); - PowerDownDone(); + if(!iActDead) + { + PowerDownDone(); + } } + +void DTest2PowerHandler::ActDead() + { + iActDead = ETrue; + } + diff -r 957c583b417b -r 2bfb1feef9de kerneltest/e32test/power/d_lddpowerseqtest.h --- a/kerneltest/e32test/power/d_lddpowerseqtest.h Mon Oct 04 12:03:52 2010 +0100 +++ b/kerneltest/e32test/power/d_lddpowerseqtest.h Mon Oct 04 12:15:59 2010 +0100 @@ -37,7 +37,9 @@ EPOWERDOWN_POWER1 = 1, EPOWERDOWN_POWER2 = 2, EPOWERUP_POWER1 = 3, - EPOWERUP_POWER2 = 4 + EPOWERUP_POWER2 = 4, + EPOWER_ACTDEAD_POWER2 = 5, + EPOWER_ESETPOWERDOWNTIMEOUT = 6 }; public: @@ -47,9 +49,26 @@ inline void Test_power1up(TRequestStatus &aStatus, TUint &time); inline void Test_power2up(TRequestStatus &aStatus, TUint &time); inline TInt Test_setSleepTime(TUint sleepTime); + inline void Test_power2ActDead(); + inline void Test_setPowerDownTimeout(TUint aTimeout); static inline TInt Unload(); }; +#ifdef __KERNEL_MODE__ +class DTestPowerManager : public DPowerModel + { +public: + TAny* iDummy; + TAny* iDummy2; + TAny* iDummy3; + + // the offset of iPslShutdownTimeoutMs should be exactly same as + // of offset in DPowerManager + TUint iPslShutdownTimeoutMs; // default = 0 + + }; +#endif // __KERNEL_MODE__ + #include "d_lddpowerseqtest.inl" #endif //__DLDDPOWERSEQTEST_H__ diff -r 957c583b417b -r 2bfb1feef9de kerneltest/e32test/power/d_lddpowerseqtest.inl --- a/kerneltest/e32test/power/d_lddpowerseqtest.inl Mon Oct 04 12:03:52 2010 +0100 +++ b/kerneltest/e32test/power/d_lddpowerseqtest.inl Mon Oct 04 12:15:59 2010 +0100 @@ -28,6 +28,10 @@ { DoRequest(EPOWERUP_POWER2, aStatus, (TAny *)&time); } inline TInt RLddTest1::Test_setSleepTime(TUint time) { return DoControl(ESET_SLEEPTIME, (TAny *)time); } +inline void RLddTest1::Test_power2ActDead() + { DoControl(EPOWER_ACTDEAD_POWER2); } +inline void RLddTest1::Test_setPowerDownTimeout(TUint aTimeout) + { DoControl(EPOWER_ESETPOWERDOWNTIMEOUT, (TAny *) aTimeout); } inline TInt RLddTest1::Unload() { return User::FreeLogicalDevice(KLddName); } #endif diff -r 957c583b417b -r 2bfb1feef9de kerneltest/e32test/power/t_lddpowerseqtest.cpp --- a/kerneltest/e32test/power/t_lddpowerseqtest.cpp Mon Oct 04 12:03:52 2010 +0100 +++ b/kerneltest/e32test/power/t_lddpowerseqtest.cpp Mon Oct 04 12:15:59 2010 +0100 @@ -78,11 +78,11 @@ User::WaitForRequest(statuspowerdown1); test(statuspowerdown1.Int() == KErrNone); - test.Printf(_L("Waiting for power up request completion of handler1\n")); + test.Printf(_L("Waiting for power down request completion of handler1\n")); User::WaitForRequest(statuspowerdown2); test(statuspowerdown2.Int() == KErrNone); - test.Printf(_L("Waiting for power down request completion of handler2\n")); + test.Printf(_L("Waiting for power up request completion of handler2\n")); User::WaitForRequest(statuspowerup1); test(statuspowerup1.Int() == KErrNone); @@ -94,6 +94,24 @@ User::WaitForRequest(tstatus); test(tstatus.Int() == KErrNone); + test.Printf(_L("Set power manager shut down timeout value\n")); + ldd.Test_setPowerDownTimeout(10); + + test.Printf(_L("Instruct power handler 2 to act dead\n")); + ldd.Test_power2ActDead(); + + test.Printf(_L("Enable wakeup power events to standby\n")); + r = Power::EnableWakeupEvents(EPwStandby); + test (r == KErrNone); + + wakeup.HomeTime(); + wakeup += TTimeIntervalMicroSeconds(5000000); + timer.At(tstatus, wakeup); + + test.Printf(_L("Powerdown\n")); + r = Power::PowerDown(); + test (r == KErrNone); + timer.Close(); test(time_power2down >= time_power1down + timeInterval);