diff options
author | Hervé Fache <hfache@nvidia.com> | 2013-06-07 14:43:31 +0200 |
---|---|---|
committer | Dan Willemsen <dwillemsen@nvidia.com> | 2013-09-14 13:38:04 -0700 |
commit | 342ba503a3ae4286e1361c2729aaa47f82da7328 (patch) | |
tree | 048bbcdebc941db046208356971da00ec1060583 /arch/arm/mach-tegra/tegra_bb.c | |
parent | 527ae5a2899c08553793d950722939e2f723e91e (diff) |
ARM: tegra: bbc: call pm_wakeup_event() in IRQ if going to suspend
If an IRQ is fired as we are going to suspend then we want to abort
and make sure voltage and frequency remain high enough for BB to
operate.
The suspend function must not ack the IRQ as the handler shall be
fired and do it.
Bug 1294872
Change-Id: I20e3872b58814402e5ee5945bb6d91c2651eaacb
Signed-off-by: Hervé Fache <hfache@nvidia.com>
Reviewed-on: http://git-master/r/239765
(cherry picked from commit 022b42d27f9dcd3614cd44d297326c8778c66840)
Reviewed-on: http://git-master/r/256176
Reviewed-by: Automatic_Commit_Validation_User
Reviewed-by: Bharat Nihalani <bnihalani@nvidia.com>
Diffstat (limited to 'arch/arm/mach-tegra/tegra_bb.c')
-rw-r--r-- | arch/arm/mach-tegra/tegra_bb.c | 21 |
1 files changed, 12 insertions, 9 deletions
diff --git a/arch/arm/mach-tegra/tegra_bb.c b/arch/arm/mach-tegra/tegra_bb.c index 1684f821be36..28efbb29a40c 100644 --- a/arch/arm/mach-tegra/tegra_bb.c +++ b/arch/arm/mach-tegra/tegra_bb.c @@ -145,6 +145,7 @@ struct tegra_bb { struct clk *emc_clk; struct device *proxy_dev; struct notifier_block pm_notifier; + bool is_suspending; }; @@ -789,6 +790,10 @@ static irqreturn_t tegra_bb_isr_handler(int irq, void *data) int sts; disable_irq_nosync(irq); +#ifdef CONFIG_PM + if (bb->is_suspending) + pm_wakeup_event(bb->dev, 0); +#endif spin_lock_irqsave(&bb->lock, irq_flags); /* read/clear INT status */ @@ -1051,6 +1056,9 @@ static int tegra_bb_pm_notifier_event(struct notifier_block *this, switch (event) { case PM_SUSPEND_PREPARE: + /* make sure IRQ will send a pm wake event */ + bb->is_suspending = true; + /* inform tegra_common_suspend about EMC requirement */ tegra_lp1bb_suspend_emc_rate(bb->emc_min_freq, BBC_MC_MIN_FREQ); @@ -1061,6 +1069,9 @@ static int tegra_bb_pm_notifier_event(struct notifier_block *this, return NOTIFY_OK; case PM_POST_SUSPEND: + /* no need for IRQ to send a pm wake events anymore */ + bb->is_suspending = false; + if (sts && !mem_req_soon) { pr_debug("bbc is inactive, remove floor\n"); clk_set_rate(bb->emc_clk, 0); @@ -1352,23 +1363,15 @@ static int tegra_bb_probe(struct platform_device *pdev) bb->pm_notifier.notifier_call = tegra_bb_pm_notifier_event; register_pm_notifier(&bb->pm_notifier); #endif + bb->is_suspending = false; return 0; } #ifdef CONFIG_PM static int tegra_bb_suspend(struct device *dev) { - void __iomem *fctrl = IO_ADDRESS(TEGRA_FLOW_CTRL_BASE); - int sts; - dev_dbg(dev, "%s\n", __func__); - /* Be sure to ack any pending irq from BB */ - sts = readl(fctrl + FLOW_CTLR_IPC_FLOW_IPC_STS_0); - if (sts & (1 << FLOW_CTLR_IPC_FLOW_IPC_STS_0_BB2AP_INT0_STS_SHIFT)) { - writel(1 << FLOW_CTLR_IPC_FLOW_IPC_CLR_0_BB2AP_INT0_STS_SHIFT, - fctrl + FLOW_CTLR_IPC_FLOW_IPC_CLR_0); - } return 0; } |