summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKumar Sanghvi <kumar.sanghvi@stericsson.com>2011-04-19 21:07:56 +0530
committerPhilippe Langlais <philippe.langlais@stericsson.com>2012-05-22 11:07:09 +0200
commitecd3d1c2e397188b5ea04a4ebb1cc8c6f69bf3b3 (patch)
tree5ff5f2a333e6a9462ebd4026179fc1ac9b8061c8
parent3f2bd84ea8f3d966f2abf93ccb5d5427805d3f95 (diff)
u8500: shrm: Update AC_Wake logic and one fix for MSR
Updates the AC_Wake logic related to MSR. Also, corrects one NULL pointer dereference. ST-Ericsson ID: ER335373 Change-Id: Ie3f46c2a7bcdde9936a0f9eed52f8dcd0ab5a06b Signed-off-by: Kumar Sanghvi <kumar.sanghvi@stericsson.com> Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/21162 Reviewed-by: QATEST Reviewed-by: Srinidhi KASAGAR <srinidhi.kasagar@stericsson.com>
-rw-r--r--drivers/char/shrm_char.c13
-rw-r--r--drivers/misc/shrm/shrm_protocol.c23
2 files changed, 14 insertions, 22 deletions
diff --git a/drivers/char/shrm_char.c b/drivers/char/shrm_char.c
index e2aaf60674f..6a6b3d7245a 100644
--- a/drivers/char/shrm_char.c
+++ b/drivers/char/shrm_char.c
@@ -236,25 +236,26 @@ int remove_msg_from_queue(struct message_queue *q)
{
struct queue_element *old_msg = NULL;
struct shrm_dev *shrm = q->shrm;
- struct list_head *msg;
+ struct list_head *msg_ptr = NULL;
+ struct list_head *old_msg_ptr = NULL;
dev_dbg(shrm->dev, "%s IN q->readptr %d\n", __func__, q->readptr);
- list_for_each(msg, &q->msg_list) {
- old_msg = list_entry(msg, struct queue_element, entry);
+ list_for_each_safe(old_msg_ptr, msg_ptr, &q->msg_list) {
+ old_msg = list_entry(old_msg_ptr, struct queue_element, entry);
if (old_msg == NULL) {
dev_err(shrm->dev, "no message found\n");
return -EFAULT;
}
+ list_del(old_msg_ptr);
+ q->readptr = (q->readptr + old_msg->size)%q->size;
+ kfree(old_msg);
break;
}
- list_del(msg);
- q->readptr = (q->readptr + old_msg->size)%q->size;
if (list_empty(&q->msg_list)) {
dev_dbg(shrm->dev, "List is empty setting RP= 0\n");
atomic_set(&q->q_rp, 0);
}
- kfree(old_msg);
dev_dbg(shrm->dev, "%s OUT\n", __func__);
return 0;
diff --git a/drivers/misc/shrm/shrm_protocol.c b/drivers/misc/shrm/shrm_protocol.c
index 0831bc8803e..0598c62812f 100644
--- a/drivers/misc/shrm/shrm_protocol.c
+++ b/drivers/misc/shrm/shrm_protocol.c
@@ -80,14 +80,6 @@ static void shm_ac_sleep_req_work(struct work_struct *work)
static void shm_ac_wake_req_work(struct work_struct *work)
{
mutex_lock(&ac_state_mutex);
- /* make sure that we bring down the ac-wake line
- * so that prcmu driver will actually write
- * to the PRCM_HOSTACCESS_REQ register on the
- * next prcmu_ac_wake_req call
- */
- prcmu_ac_sleep_req();
-
- atomic_inc(&ac_sleep_disable_count);
prcmu_ac_wake_req();
mutex_unlock(&ac_state_mutex);
}
@@ -384,13 +376,6 @@ void shm_ac_read_notif_0_tasklet(unsigned long tasklet_data)
/* multicast that modem is online */
nl_send_multicast_message(SHRM_NL_STATUS_MOD_ONLINE, GFP_ATOMIC);
-
- /* This decrement corresponds to increment
- * done in MSR sequecne
- */
- atomic_dec(&ac_sleep_disable_count);
- queue_work(shm_dev->shm_ac_sleep_wq,
- &shm_dev->shm_ac_sleep_req);
}
} else if (boot_state == BOOT_DONE) {
@@ -523,9 +508,13 @@ static int shrm_modem_reset_sequence(void)
hrtimer_cancel(&timer);
- /* reset the state for ac-wake LOW logic */
+ /*
+ * keep the count to 0 so that we can bring down the line
+ * for normal ac-wake and ac-sleep logic
+ */
atomic_set(&ac_sleep_disable_count, 0);
+ /* workaround for MSR */
queue_work(shm_dev->shm_ac_wake_wq,
&shm_dev->shm_ac_wake_req);
@@ -598,6 +587,8 @@ static irqreturn_t shrm_prcmu_irq_handler(int irq, void *data)
#ifdef CONFIG_UX500_SUSPEND
suspend_block_sleep();
#endif
+ if (shrm->msr_flag)
+ atomic_set(&ac_sleep_disable_count, 0);
atomic_inc(&ac_sleep_disable_count);
queue_work(shrm->shm_ca_wake_wq, &shrm->shm_ca_wake_req);
break;