msm: smd_pkt: Add packet arrival wakelock
While handling the incoming packets from remote subsystems, delay the
system suspension by holding a wakelock with a timeout value of 2 seconds.
This will allow the user-space clients to process the incoming packets
before the system goes to suspend.
CRs-Fixed: 335782
Change-Id: Idea2fd490a52a8bfd7b97cad7e784a6782a0cf8f
Signed-off-by: Eric Holmberg <eholmber@codeaurora.org>
Signed-off-by: Karthikeyan Ramasubramanian <kramasub@codeaurora.org>
diff --git a/arch/arm/mach-msm/smd_pkt.c b/arch/arm/mach-msm/smd_pkt.c
index 8023129..63c5fef 100644
--- a/arch/arm/mach-msm/smd_pkt.c
+++ b/arch/arm/mach-msm/smd_pkt.c
@@ -31,6 +31,7 @@
#include <linux/msm_smd_pkt.h>
#include <linux/poll.h>
#include <asm/ioctls.h>
+#include <linux/wakelock.h>
#include <mach/msm_smd.h>
#include <mach/peripheral-loader.h>
@@ -45,6 +46,7 @@
#define LOOPBACK_INX (NUM_SMD_PKT_PORTS - 1)
#define DEVICE_NAME "smdpkt"
+#define WAKELOCK_TIMEOUT (2*HZ)
struct smd_pkt_dev {
struct cdev cdev;
@@ -70,7 +72,8 @@
int has_reset;
int do_reset_notification;
struct completion ch_allocated;
-
+ struct wake_lock pa_wake_lock; /* Packet Arrival Wake lock*/
+ struct work_struct packet_arrival_work;
} *smd_pkt_devp[NUM_SMD_PKT_PORTS];
struct class *smd_pkt_classp;
@@ -183,6 +186,19 @@
}
+static void packet_arrival_worker(struct work_struct *work)
+{
+ struct smd_pkt_dev *smd_pkt_devp;
+
+ smd_pkt_devp = container_of(work, struct smd_pkt_dev,
+ packet_arrival_work);
+ mutex_lock(&smd_pkt_devp->ch_lock);
+ if (smd_pkt_devp->ch)
+ wake_lock_timeout(&smd_pkt_devp->pa_wake_lock,
+ WAKELOCK_TIMEOUT);
+ mutex_unlock(&smd_pkt_devp->ch_lock);
+}
+
static long smd_pkt_ioctl(struct file *file, unsigned int cmd,
unsigned long arg)
{
@@ -421,6 +437,7 @@
/* here we have a packet of size sz ready */
wake_up(&smd_pkt_devp->ch_read_wait_queue);
+ schedule_work(&smd_pkt_devp->packet_arrival_work);
D(KERN_ERR "%s: after wake_up\n", __func__);
}
@@ -579,6 +596,10 @@
if (!smd_pkt_devp)
return -EINVAL;
+ wake_lock_init(&smd_pkt_devp->pa_wake_lock, WAKE_LOCK_SUSPEND,
+ smd_pkt_dev_name[smd_pkt_devp->i]);
+ INIT_WORK(&smd_pkt_devp->packet_arrival_work, packet_arrival_worker);
+
file->private_data = smd_pkt_devp;
mutex_lock(&smd_pkt_devp->ch_lock);
@@ -665,6 +686,9 @@
out:
mutex_unlock(&smd_pkt_devp->ch_lock);
+ if (r < 0)
+ wake_lock_destroy(&smd_pkt_devp->pa_wake_lock);
+
return r;
}
@@ -690,6 +714,7 @@
smd_pkt_devp->has_reset = 0;
smd_pkt_devp->do_reset_notification = 0;
+ wake_lock_destroy(&smd_pkt_devp->pa_wake_lock);
return r;
}