summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArun Murthy <arun.murthy@stericsson.com>2012-02-08 17:06:31 +0530
committerPhilippe Langlais <philippe.langlais@stericsson.com>2012-06-05 10:40:28 +0200
commit4019263b82f4b6f1e988f9efafc05ab564bf5769 (patch)
treec344afe1252d82e28805dbb954152b9c8dfacf44
parente5167e878c133bd5f1c3ac5f207084355a43b234 (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.c13
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);