PM / devfreq: bimc-bwmon: Update irq handling in suspend/resume

Change the sequence of registering and freeing the interrupt
handler in suspend/resume. Freeirq needs a guarantee that the
IRQ can't come anymore before we call it. So, we disable the IRQ
before calling freeirq.And register the handler before enabling
the irq to avoid the interrupt getting unhandled.

Change-Id: I3945202d049e16f64a16e456f914f7602b763c89
Signed-off-by: Hanumath Prasad <hpprasad@codeaurora.org>
This commit is contained in:
Hanumath Prasad 2015-07-07 17:48:58 +05:30 committed by David Keitel
parent 3dfc05409f
commit ee4630d01e

View file

@ -66,6 +66,12 @@ static void mon_enable(struct bwmon *m)
static void mon_disable(struct bwmon *m)
{
writel_relaxed(0x0, MON_EN(m));
/*
* mon_disable() and mon_irq_clear(),
* If latter goes first and count happen to trigger irq, we would
* have the irq line high but no one handling it.
*/
mb();
}
static void mon_clear(struct bwmon *m)
@ -92,6 +98,11 @@ static void mon_irq_enable(struct bwmon *m)
val = readl_relaxed(MON_INT_EN(m));
val |= 0x1;
writel_relaxed(val, MON_INT_EN(m));
/*
* make Sure irq enable complete for local and global
* to avoid race with other monitor calls
*/
mb();
}
static void mon_irq_disable(struct bwmon *m)
@ -107,6 +118,11 @@ static void mon_irq_disable(struct bwmon *m)
val = readl_relaxed(MON_INT_EN(m));
val &= ~0x1;
writel_relaxed(val, MON_INT_EN(m));
/*
* make Sure irq disable complete for local and global
* to avoid race with other monitor calls
*/
mb();
}
static unsigned int mon_irq_status(struct bwmon *m)
@ -264,9 +280,9 @@ static void stop_bw_hwmon(struct bw_hwmon *hw)
{
struct bwmon *m = to_bwmon(hw);
mon_irq_disable(m);
free_irq(m->irq, m);
mon_disable(m);
mon_irq_disable(m);
mon_clear(m);
mon_irq_clear(m);
}
@ -275,9 +291,9 @@ static int suspend_bw_hwmon(struct bw_hwmon *hw)
{
struct bwmon *m = to_bwmon(hw);
mon_irq_disable(m);
free_irq(m->irq, m);
mon_disable(m);
mon_irq_disable(m);
mon_irq_clear(m);
return 0;
@ -289,8 +305,6 @@ static int resume_bw_hwmon(struct bw_hwmon *hw)
int ret;
mon_clear(m);
mon_irq_enable(m);
mon_enable(m);
ret = request_threaded_irq(m->irq, NULL, bwmon_intr_handler,
IRQF_ONESHOT | IRQF_SHARED,
dev_name(m->dev), m);
@ -300,6 +314,9 @@ static int resume_bw_hwmon(struct bw_hwmon *hw)
return ret;
}
mon_irq_enable(m);
mon_enable(m);
return 0;
}