summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGary King <GKing@nvidia.com>2010-02-01 17:30:26 -0800
committerGerrit Code Review <gerrit2@git-master-01.nvidia.com>2010-02-01 17:30:26 -0800
commit417a18fb1e71a9975c77250f08ba45c4d7efbd6f (patch)
tree656fcaac482b02074793203b49ca7ae3d23ab374
parent3d13613ce235128f6e7e9a46e74d3865b3a940f9 (diff)
parenta531df9ef14cd29e5fb0f0bdb650d7a422c7f0c2 (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.c88
-rw-r--r--arch/arm/mach-tegra/nvec/nvec_private.h1
-rw-r--r--drivers/input/keyboard/tegra-nvec.c9
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);