diff options
author | Arun Murthy <arun.murthy@stericsson.com> | 2012-02-08 17:06:31 +0530 |
---|---|---|
committer | Philippe Langlais <philippe.langlais@stericsson.com> | 2012-05-22 11:07:25 +0200 |
commit | 18f638e206e2536b835e27fae5024eb13a6f9915 (patch) | |
tree | 7c082d7a5ab0cb8f10b44985b23e64fd10d5e25a | |
parent | 83765c8325ac699f3236e8f428f6df0a7efff4b2 (diff) |
u8500-shrm: ensure that timer is started after write to GOP
After sendig AC_MSG_PEND timer is started and on getting AC_READ_NOTI timer
is stopped.
There are possibility of preemtion happening after writting to GOP register(for
sending AC_MSG_PEND) and starting the timer. Hence acquire a spin lock to
ensure that hrtimer is started after sending MSG_PEND interrupt.
ST-Ericsson Linux next: NA
ST-Ericsson ID: 413524
ST-Ericsson FOSS-OUT ID: Trivial
Change-Id: Ic3d5d6e9259dc22ca6a4741b1cdd3792f33777fb
Signed-off-by: Arun Murthy <arun.murthy@stericsson.com>
Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/48272
Reviewed-by: QABUILD
Reviewed-by: Jonas ABERG <jonas.aberg@stericsson.com>
Reviewed-by: Srinidhi KASAGAR <srinidhi.kasagar@stericsson.com>
-rw-r--r-- | drivers/modem/shrm/shrm_protocol.c | 13 |
1 files changed, 13 insertions, 0 deletions
diff --git a/drivers/modem/shrm/shrm_protocol.c b/drivers/modem/shrm/shrm_protocol.c index 40e77993613..d9187e36c68 100644 --- a/drivers/modem/shrm/shrm_protocol.c +++ b/drivers/modem/shrm/shrm_protocol.c @@ -73,6 +73,7 @@ static DEFINE_SPINLOCK(ca_audio_lock); static DEFINE_SPINLOCK(ca_wake_req_lock); static DEFINE_SPINLOCK(boot_lock); static DEFINE_SPINLOCK(mod_stuck_lock); +static DEFINE_SPINLOCK(start_timer_lock); enum shrm_nl { SHRM_NL_MOD_RESET = 1, @@ -694,6 +695,7 @@ static irqreturn_t shrm_prcmu_irq_handler(int irq, void *data) static void send_ac_msg_pend_notify_0_work(struct kthread_work *work) { + unsigned long flags; struct shrm_dev *shrm = container_of(work, struct shrm_dev, send_ac_msg_pend_notify_0); @@ -717,6 +719,7 @@ static void send_ac_msg_pend_notify_0_work(struct kthread_work *work) return; } + spin_lock_irqsave(&start_timer_lock, flags); /* Trigger AcMsgPendingNotification to CMU */ writel((1<<GOP_COMMON_AC_MSG_PENDING_NOTIFICATION_BIT), shrm->intr_base + GOP_SET_REGISTER_BASE); @@ -724,6 +727,7 @@ static void send_ac_msg_pend_notify_0_work(struct kthread_work *work) /* timer to detect modem stuck or hang */ hrtimer_start(&mod_stuck_timer_0, ktime_set(MOD_STUCK_TIMEOUT, 0), HRTIMER_MODE_REL); + spin_unlock_irqrestore(&start_timer_lock, flags); if (shrm_common_tx_state == SHRM_PTR_FREE) shrm_common_tx_state = SHRM_PTR_BUSY; @@ -732,6 +736,7 @@ static void send_ac_msg_pend_notify_0_work(struct kthread_work *work) static void send_ac_msg_pend_notify_1_work(struct kthread_work *work) { + unsigned long flags; struct shrm_dev *shrm = container_of(work, struct shrm_dev, send_ac_msg_pend_notify_1); @@ -759,6 +764,7 @@ static void send_ac_msg_pend_notify_1_work(struct kthread_work *work) return; } + spin_lock_irqsave(&start_timer_lock, flags); /* Trigger AcMsgPendingNotification to CMU */ writel((1<<GOP_AUDIO_AC_MSG_PENDING_NOTIFICATION_BIT), shrm->intr_base + GOP_SET_REGISTER_BASE); @@ -766,6 +772,7 @@ static void send_ac_msg_pend_notify_1_work(struct kthread_work *work) /* timer to detect modem stuck or hang */ hrtimer_start(&mod_stuck_timer_1, ktime_set(MOD_STUCK_TIMEOUT, 0), HRTIMER_MODE_REL); + spin_unlock_irqrestore(&start_timer_lock, flags); if (shrm_audio_tx_state == SHRM_PTR_FREE) shrm_audio_tx_state = SHRM_PTR_BUSY; @@ -1018,11 +1025,14 @@ irqreturn_t ca_wake_irq_handler(int irq, void *ctrlr) irqreturn_t ac_read_notif_0_irq_handler(int irq, void *ctrlr) { + unsigned long flags; struct shrm_dev *shrm = ctrlr; dev_dbg(shrm->dev, "%s IN\n", __func__); /* Cancel the modem stuck timer */ + spin_lock_irqsave(&start_timer_lock, flags); hrtimer_cancel(&mod_stuck_timer_0); + spin_unlock_irqrestore(&start_timer_lock, flags); if(atomic_read(&fifo_full)) hrtimer_cancel(&fifo_full_timer); @@ -1051,11 +1061,14 @@ irqreturn_t ac_read_notif_0_irq_handler(int irq, void *ctrlr) irqreturn_t ac_read_notif_1_irq_handler(int irq, void *ctrlr) { + unsigned long flags; struct shrm_dev *shrm = ctrlr; dev_dbg(shrm->dev, "%s IN+\n", __func__); /* Cancel the modem stuck timer */ + spin_lock_irqsave(&start_timer_lock, flags); hrtimer_cancel(&mod_stuck_timer_1); + spin_unlock_irqrestore(&start_timer_lock, flags); if(atomic_read(&fifo_full)) hrtimer_cancel(&fifo_full_timer); |