Merge "msm: smd_pkt: Handle wakelocks appropriately to optimize power usage" into msm-3.0
diff --git a/arch/arm/mach-msm/smd_pkt.c b/arch/arm/mach-msm/smd_pkt.c
index 63c5fef..aeffbfd 100644
--- a/arch/arm/mach-msm/smd_pkt.c
+++ b/arch/arm/mach-msm/smd_pkt.c
@@ -66,6 +66,7 @@
int blocking_write;
int is_open;
+ int poll_mode;
unsigned ch_size;
uint open_modem_wait;
@@ -74,6 +75,7 @@
struct completion ch_allocated;
struct wake_lock pa_wake_lock; /* Packet Arrival Wake lock*/
struct work_struct packet_arrival_work;
+ struct spinlock pa_spinlock;
} *smd_pkt_devp[NUM_SMD_PKT_PORTS];
struct class *smd_pkt_classp;
@@ -236,6 +238,7 @@
int pkt_size;
struct smd_pkt_dev *smd_pkt_devp;
struct smd_channel *chl;
+ unsigned long flags;
D(KERN_ERR "%s: read %i bytes\n",
__func__, count);
@@ -316,6 +319,16 @@
D_DUMP_BUFFER("read: ", bytes_read, buf);
mutex_unlock(&smd_pkt_devp->rx_lock);
+ mutex_lock(&smd_pkt_devp->ch_lock);
+ spin_lock_irqsave(&smd_pkt_devp->pa_spinlock, flags);
+ if (smd_pkt_devp->poll_mode &&
+ !smd_cur_packet_size(smd_pkt_devp->ch)) {
+ wake_unlock(&smd_pkt_devp->pa_wake_lock);
+ smd_pkt_devp->poll_mode = 0;
+ }
+ spin_unlock_irqrestore(&smd_pkt_devp->pa_spinlock, flags);
+ mutex_unlock(&smd_pkt_devp->ch_lock);
+
D(KERN_ERR "%s: just read %i bytes\n",
__func__, bytes_read);
@@ -409,6 +422,7 @@
if (!smd_pkt_devp)
return POLLERR;
+ smd_pkt_devp->poll_mode = 1;
poll_wait(file, &smd_pkt_devp->ch_read_wait_queue, wait);
if (smd_read_avail(smd_pkt_devp->ch))
mask |= POLLIN | POLLRDNORM;
@@ -419,6 +433,7 @@
static void check_and_wakeup_reader(struct smd_pkt_dev *smd_pkt_devp)
{
int sz;
+ unsigned long flags;
if (!smd_pkt_devp || !smd_pkt_devp->ch)
return;
@@ -437,6 +452,9 @@
/* here we have a packet of size sz ready */
wake_up(&smd_pkt_devp->ch_read_wait_queue);
+ spin_lock_irqsave(&smd_pkt_devp->pa_spinlock, flags);
+ wake_lock(&smd_pkt_devp->pa_wake_lock);
+ spin_unlock_irqrestore(&smd_pkt_devp->pa_spinlock, flags);
schedule_work(&smd_pkt_devp->packet_arrival_work);
D(KERN_ERR "%s: after wake_up\n", __func__);
}
@@ -707,6 +725,7 @@
r = smd_close(smd_pkt_devp->ch);
smd_pkt_devp->ch = 0;
smd_pkt_devp->blocking_write = 0;
+ smd_pkt_devp->poll_mode = 0;
if (smd_pkt_devp->pil)
pil_put(smd_pkt_devp->pil);
}
@@ -776,8 +795,10 @@
init_waitqueue_head(&smd_pkt_devp[i]->ch_read_wait_queue);
init_waitqueue_head(&smd_pkt_devp[i]->ch_write_wait_queue);
smd_pkt_devp[i]->is_open = 0;
+ smd_pkt_devp[i]->poll_mode = 0;
init_waitqueue_head(&smd_pkt_devp[i]->ch_opened_wait_queue);
+ spin_lock_init(&smd_pkt_devp[i]->pa_spinlock);
mutex_init(&smd_pkt_devp[i]->ch_lock);
mutex_init(&smd_pkt_devp[i]->rx_lock);
mutex_init(&smd_pkt_devp[i]->tx_lock);