msm: smsm: Add SMSM notifier wakelock
Add wakelock that is locked in the SMSM interrupt handler and unlocked
in the workqueue after notifications have been completed.
This prevents the sleep code from putting the system to sleep before the
SMSM notification workqueue gets scheduled.
CRs-Fixed: 345581
Change-Id: Idb93493dfa79cd4ea80b857ed92c4b2f9b96af3f
Signed-off-by: Eric Holmberg <eholmber@codeaurora.org>
diff --git a/arch/arm/mach-msm/smd.c b/arch/arm/mach-msm/smd.c
index e3248ad..a1c044e 100644
--- a/arch/arm/mach-msm/smd.c
+++ b/arch/arm/mach-msm/smd.c
@@ -32,6 +32,7 @@
#include <linux/remote_spinlock.h>
#include <linux/uaccess.h>
#include <linux/kfifo.h>
+#include <linux/wakelock.h>
#include <mach/msm_smd.h>
#include <mach/msm_iomap.h>
#include <mach/system.h>
@@ -82,7 +83,10 @@
};
static struct smsm_shared_info smsm_info;
-struct kfifo smsm_snapshot_fifo;
+static struct kfifo smsm_snapshot_fifo;
+static struct wake_lock smsm_snapshot_wakelock;
+static int smsm_snapshot_count;
+static DEFINE_SPINLOCK(smsm_snapshot_count_lock);
struct smsm_size_info_type {
uint32_t num_hosts;
@@ -2264,6 +2268,8 @@
pr_err("%s: SMSM state fifo alloc failed %d\n", __func__, i);
return i;
}
+ wake_lock_init(&smsm_snapshot_wakelock, WAKE_LOCK_SUSPEND,
+ "smsm_snapshot");
if (!smsm_info.state) {
smsm_info.state = smem_alloc2(ID_SHARED_STATE,
@@ -2338,6 +2344,7 @@
{
int n;
uint32_t new_state;
+ unsigned long flags;
int ret;
ret = kfifo_avail(&smsm_snapshot_fifo);
@@ -2356,6 +2363,14 @@
return;
}
}
+
+ spin_lock_irqsave(&smsm_snapshot_count_lock, flags);
+ if (smsm_snapshot_count == 0) {
+ SMx_POWER_INFO("SMSM snapshot wake lock\n");
+ wake_lock(&smsm_snapshot_wakelock);
+ }
+ ++smsm_snapshot_count;
+ spin_unlock_irqrestore(&smsm_snapshot_count_lock, flags);
schedule_work(&smsm_cb_work);
}
@@ -2578,6 +2593,7 @@
uint32_t new_state;
uint32_t state_changes;
int ret;
+ unsigned long flags;
int snapshot_size = SMSM_NUM_ENTRIES * sizeof(uint32_t);
if (!smd_initialized)
@@ -2614,6 +2630,18 @@
}
}
mutex_unlock(&smsm_lock);
+
+ spin_lock_irqsave(&smsm_snapshot_count_lock, flags);
+ if (smsm_snapshot_count) {
+ --smsm_snapshot_count;
+ if (smsm_snapshot_count == 0) {
+ SMx_POWER_INFO("SMSM snapshot wake unlock\n");
+ wake_unlock(&smsm_snapshot_wakelock);
+ }
+ } else {
+ pr_err("%s: invalid snapshot count\n", __func__);
+ }
+ spin_unlock_irqrestore(&smsm_snapshot_count_lock, flags);
}
}