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:
parent
3dfc05409f
commit
ee4630d01e
1 changed files with 21 additions and 4 deletions
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue