diff options
author | Gary King <GKing@nvidia.com> | 2010-02-01 17:30:26 -0800 |
---|---|---|
committer | Gerrit Code Review <gerrit2@git-master-01.nvidia.com> | 2010-02-01 17:30:26 -0800 |
commit | 417a18fb1e71a9975c77250f08ba45c4d7efbd6f (patch) | |
tree | 656fcaac482b02074793203b49ca7ae3d23ab374 | |
parent | 3d13613ce235128f6e7e9a46e74d3865b3a940f9 (diff) | |
parent | a531df9ef14cd29e5fb0f0bdb650d7a422c7f0c2 (diff) |
Merge "tegra: NvEC threads are added into refrigerator for suspend/resume cases" into android-tegra-2.6.29
-rw-r--r-- | arch/arm/mach-tegra/nvec/nvec.c | 88 | ||||
-rw-r--r-- | arch/arm/mach-tegra/nvec/nvec_private.h | 1 | ||||
-rw-r--r-- | drivers/input/keyboard/tegra-nvec.c | 9 |
3 files changed, 59 insertions, 39 deletions
diff --git a/arch/arm/mach-tegra/nvec/nvec.c b/arch/arm/mach-tegra/nvec/nvec.c index e1ffae6d52e2..34dedfdfb15b 100644 --- a/arch/arm/mach-tegra/nvec/nvec.c +++ b/arch/arm/mach-tegra/nvec/nvec.c @@ -30,12 +30,15 @@ * */ +#include "linux/freezer.h" + #include "nvcommon.h" #include "nvassert.h" #include "nvec.h" #include "nvec_transport.h" #include "nvec_private.h" + #define DEBUG_NVEC 0 #define DISP_MESSAGE(x) do { if (DEBUG_NVEC) { NvOsDebugPrintf x ; } } while (0) @@ -46,6 +49,9 @@ static NvU32 s_refcount = 0; static NvEcPrivState g_ec = {0}; // init mutex to NULL +/* Wakes up EC */ +static DECLARE_WAIT_QUEUE_HEAD(wq_ec); + // forward declarations static void NvEcPrivProcessSendRequest( NvEcPrivState *ec ); @@ -230,40 +236,49 @@ NvEcPrivPowerResumeHook( NvEcHandle hEc ) static void NvEcPrivPingThread(void *args) { - NvError NvStatus = NvError_Success; - NvEcRequest req; - NvEcResponse resp; - NvEcPrivState *ec = (NvEcPrivState *)args; - - while (!ec->exitPingThread) - { - if (NvStatus == NvError_Timeout) - { - // send no-op commands - DISP_MESSAGE(("NvEcPrivPingThread: Sending no-op command\n")); - - req.PacketType = NvEcPacketType_Request; - req.RequestType = NvEcRequestResponseType_Control; - req.RequestSubtype = (NvEcRequestResponseSubtype) - NvEcControlSubtype_NoOperation; - req.NumPayloadBytes = 0; - - NvStatus = NvEcSendRequest( - ec->hEc, - &req, - &resp, - sizeof(req), - sizeof(resp)); - if (NvStatus != NvError_Success) - DISP_MESSAGE(("NvEcPrivPingThread: no-op command send fail\n")); - - if (resp.Status != NvEcStatus_Success) - DISP_MESSAGE(("NvEcPrivPingThread: no-op command fail\n")); - - DISP_MESSAGE(("NvEcPrivPingThread: no-op command sent\n")); - } - NvStatus = NvOsSemaphoreWaitTimeout(ec->hPingSema, NVEC_PING_TIMEOUT); - } + NvError NvStatus = NvError_Success; + NvEcRequest req; + NvEcResponse resp; + NvEcPrivState *ec = (NvEcPrivState *)args; + int timeout = 0; + + set_freezable_with_signal(); + + while (!ec->exitPingThread){ + // request timed out + if (timeout > 0){ + // send no-op commands + DISP_MESSAGE(("NvEcPrivPingThread: Sending no-op command\n")); + req.PacketType = NvEcPacketType_Request; + req.RequestType = NvEcRequestResponseType_Control; + req.RequestSubtype = (NvEcRequestResponseSubtype) + NvEcControlSubtype_NoOperation; + req.NumPayloadBytes = 0; + + NvStatus = NvEcSendRequest( + ec->hEc, + &req, + &resp, + sizeof(req), + sizeof(resp)); + if (NvStatus != NvError_Success) + DISP_MESSAGE(("NvEcPrivPingThread: no-op command send fail\n")); + + if (resp.Status != NvEcStatus_Success) + DISP_MESSAGE(("NvEcPrivPingThread: no-op command fail\n")); + + DISP_MESSAGE(("NvEcPrivPingThread: no-op command sent\n")); + ec->IsEcActive = NV_FALSE; + } + + timeout = NVEC_PING_TIMEOUT; + timeout = wait_event_freezable_timeout( + wq_ec, + ec->IsEcActive, + timeout); + if (timeout == 0) + ec->IsEcActive = NV_FALSE; + } } NvError @@ -362,6 +377,8 @@ NvEcOpen(NvEcHandle *phEc, NvOsMutexUnlock( ec->mutex ); + ec->IsEcActive = NV_FALSE; + return NvSuccess; clean: @@ -1010,7 +1027,7 @@ NvEcPrivThread( void * args ) NvU32 tStatus = 0; NvError wait = NvSuccess; NvError e; - + while( !ec->exitThread ) { #if ENABLE_TIMEOUT @@ -1169,6 +1186,7 @@ NvEcSendRequest( NV_CHECK_ERROR_CLEANUP( NvOsSemaphoreCreate( &responseSema, 0 ) ); } + ec->IsEcActive = NV_TRUE; // kick the "heartbeat" thread so that the pings would only be sent when // there are no commands being sent from AP->EC. if (ec->hPingSema) diff --git a/arch/arm/mach-tegra/nvec/nvec_private.h b/arch/arm/mach-tegra/nvec/nvec_private.h index ac2fc811b62a..7b8b649a9a9d 100644 --- a/arch/arm/mach-tegra/nvec/nvec_private.h +++ b/arch/arm/mach-tegra/nvec/nvec_private.h @@ -204,6 +204,7 @@ typedef struct NvEcPrivStateRec NvOsThreadHandle hPingThread; NvOsSemaphoreHandle hPingSema; NvBool exitPingThread; + NvBool IsEcActive; } NvEcPrivState; diff --git a/drivers/input/keyboard/tegra-nvec.c b/drivers/input/keyboard/tegra-nvec.c index 7081e92377b3..df6f2e27ca20 100644 --- a/drivers/input/keyboard/tegra-nvec.c +++ b/drivers/input/keyboard/tegra-nvec.c @@ -255,6 +255,7 @@ struct nvec_keyboard struct input_dev *input_dev; struct task_struct *task; char name[128]; + int shutdown; unsigned short keycode[512]; NvEcHandle hNvec; NvEcEventRegistrationHandle hEvent; @@ -267,7 +268,7 @@ static int nvec_keyboard_recv(void *arg) struct input_dev *input_dev = (struct input_dev *)arg; struct nvec_keyboard *keyboard = input_get_drvdata(input_dev); - while (!kthread_should_stop()) { + while (!keyboard->shutdown) { unsigned int pressed; NvU32 code; NvU8 flags; @@ -278,9 +279,8 @@ static int nvec_keyboard_recv(void *arg) continue; } - /* Check for the thread terminaiton request */ - if (kthread_should_stop()) - return 0; + if (keyboard->shutdown) + break; pressed = (flags & NV_ODM_SCAN_CODE_FLAG_MAKE); @@ -396,6 +396,7 @@ static int __devexit nvec_keyboard_remove(struct platform_device *dev) NvOdmKeyboardDeInit(); NvEcClose(keyboard->hNvec); keyboard->hNvec = NULL; + keyboard->shutdown = 1; input_free_device(input_dev); kfree(keyboard); |