201039_08
authorhgs
Mon, 04 Oct 2010 12:15:59 +0100
changeset 280 2bfb1feef9de
parent 279 957c583b417b
child 282 664ff9a1a8fa
child 285 ff5437e4337c
201039_08
kernel/eka/bmarm/ekernsmp.def
kernel/eka/bmarm/ekernu.def
kernel/eka/bwins/ekernu.def
kernel/eka/bx86/ekernsmp.def
kernel/eka/bx86/ekernu.def
kernel/eka/bx86gcc/ekernsmp.def
kernel/eka/bx86gcc/ekernu.def
kernel/eka/eabi/ekernsmp.def
kernel/eka/eabi/ekernu.def
kernel/eka/include/e32ver.h
kernel/eka/include/kernel/kpower.h
kernel/eka/kernel/power.cpp
kernel/eka/release.txt
kerneltest/e32test/power/d_lddpowerseqtest.cpp
kerneltest/e32test/power/d_lddpowerseqtest.h
kerneltest/e32test/power/d_lddpowerseqtest.inl
kerneltest/e32test/power/t_lddpowerseqtest.cpp
--- 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)
 
--- 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)
--- 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)
 
--- 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)
 
--- 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)
 
--- 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
--- 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
 
--- 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
 
--- 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
 
--- 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;
--- 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);
--- 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 <nkern/nk_trace.h>
+//#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("<DPowerManager::ShutDownTimeoutFn"));
+#endif
+	}
+
 TInt DPowerManager::PowerDown()
 	{ // called by ExecHandler 
 	__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
--- 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)
--- 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;
+	}
+
--- 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__
--- 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
--- 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);