diff options
author | Arun Murthy <arun.murthy@stericsson.com> | 2011-12-20 09:39:07 +0530 |
---|---|---|
committer | Philippe Langlais <philippe.langlais@stericsson.com> | 2012-05-22 11:07:23 +0200 |
commit | 61c8a3297f88a79648271a694a03fd44f29d40c8 (patch) | |
tree | 58198a5ec6642011e6321bb1239de9b0b3400300 | |
parent | 02d694f3b46da51fb4dec1c74690afdd82c62639 (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.c | 8 |
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); |