Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ae2948c6 authored by Hanumath Prasad's avatar Hanumath Prasad Committed by Gerrit - the friendly Code Review server
Browse files

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: default avatarHanumath Prasad <hpprasad@codeaurora.org>
parent 75d530af
Loading
Loading
Loading
Loading
+21 −4
Original line number Diff line number Diff line
@@ -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;
}