summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArun Murthy <arun.murthy@stericsson.com>2011-12-20 09:39:07 +0530
committerPhilippe Langlais <philippe.langlais@stericsson.com>2012-06-05 10:40:23 +0200
commitb3fed0a70ea154d26733edede211456c873b61a7 (patch)
tree87e0835c76e2fb0f0285e198deadb55fd49f050a
parenta7571f5058c612dd15aeadc6e2111cf144352213 (diff)
u8500-shrm: maintain sleep statemachine in real time
ac_sleep_disable_count is flag used t control the power management state machine this counter is increased in 3 places ca_wake_req ac_msg_pend_notify_0 ac-msg_pend_notify_1 and decremented in 3 places ac_read_notify_0 ac_read_notify_1 ca_sleep_req ac_msg_pend_notify is called from 2 places, shm_write_msg ac_read_notify it gets called from "shm_write_msg" when there is only one message in the shared memory and otherwise from "ac_read_notify" LOGS <6>[ 72.793395] send_ac_msg_pend_notify_1_work I:2 <6>[ 72.793609] shm_ac_read_notif_1_tasklet D:1 <6>[ 72.793731] send_ac_msg_pend_notify_1_work I:2 <6>[ 72.793853] send_ac_msg_pend_notify_1_work I:3 <6>[ 72.793914] shm_ac_read_notif_1_tasklet D:2 <6>[ 72.804840] send_ac_msg_pend_notify_1_work I:3 <6>[ 72.805053] shm_ac_read_notif_1_tasklet D:2 From the above logs send_ac_msg_pend_notify_1_work is called twice. No problem if this is called twice, but for state machine counter ac_sleep_disable_count this causes problem which doesnt allow the system to enter sleep. This function is called twice in a real time seq, first time from the ac_read_notify, here assume that there is only one message, and hence after notifying modem will call ac_msg_pend_notify. Modem on receiving this interrupt will update the shared read pointer and send the ack. After updating the shared read pointer and before APE receiving the ACK, there is some msg write req coming to shrm. shm driver shm_write_msg is called. Here it finds that this is the only message in shared memory, because the shared read and write pointer are same. Hence send_ac_msg_pend_notify_1_work is called again. Even though msg_pend is notified twice we receive read_notification only onece. Counter ac_sleep_disable_count is incremented in ca_wake_req to 1. Then in ac_msg_pend_notify to 2, then decremented in ac_read_notify. Hence it doesnt increase beyond 2 Fix would be to check if ac_msg_pend is called twice before ac_read_notify is received, then in that case dont increment the ac_sleep_disable_count in ac_msg_pend_notify. ST-Ericsson Linux next: NA ST-Ericsson ID: 401826 ST-Ericsson FOSS-OUT ID: Trivial Change-Id: Ie4ed0ae33b011a798d620a8db531fad8c23b1d7a Signed-off-by: Arun Murthy <arun.murthy@stericsson.com> Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/43169 Reviewed-by: Bibek BASU <bibek.basu@stericsson.com> Reviewed-by: QABUILD Reviewed-by: Srinidhi KASAGAR <srinidhi.kasagar@stericsson.com>
-rw-r--r--drivers/modem/shrm/shrm_protocol.c8
1 files changed, 7 insertions, 1 deletions
diff --git a/drivers/modem/shrm/shrm_protocol.c b/drivers/modem/shrm/shrm_protocol.c
index 6cc6e347188..cbb3a820317 100644
--- a/drivers/modem/shrm/shrm_protocol.c
+++ b/drivers/modem/shrm/shrm_protocol.c
@@ -48,6 +48,7 @@ static char shrm_audio_tx_state = SHRM_SLEEP_STATE;
static char shrm_audio_rx_state = SHRM_SLEEP_STATE;
static atomic_t ac_sleep_disable_count = ATOMIC_INIT(0);
+static atomic_t ac_msg_pend_1 = ATOMIC_INIT(0);
static struct shrm_dev *shm_dev;
/* Spin lock and tasklet declaration */
@@ -440,6 +441,7 @@ void shm_ac_read_notif_1_tasklet(unsigned long tasklet_data)
hrtimer_start(&timer, ktime_set(0, 10*NSEC_PER_MSEC),
HRTIMER_MODE_REL);
atomic_dec(&ac_sleep_disable_count);
+ atomic_dec(&ac_msg_pend_1);
dev_dbg(shrm->dev, "%s OUT\n", __func__);
}
@@ -508,6 +510,7 @@ static int shrm_modem_reset_sequence(void)
* for normal ac-wake and ac-sleep logic
*/
atomic_set(&ac_sleep_disable_count, 0);
+ atomic_set(&ac_msg_pend_1, 0);
/* workaround for MSR */
queue_kthread_work(&shm_dev->shm_ac_wake_kw,
@@ -665,7 +668,10 @@ static void send_ac_msg_pend_notify_1_work(struct kthread_work *work)
update_ac_audio_shared_wptr(shrm);
mutex_lock(&ac_state_mutex);
- atomic_inc(&ac_sleep_disable_count);
+ if (!atomic_read(&ac_msg_pend_1)) {
+ atomic_inc(&ac_sleep_disable_count);
+ atomic_inc(&ac_msg_pend_1);
+ }
modem_request(shrm->modem);
mutex_unlock(&ac_state_mutex);