summaryrefslogtreecommitdiff
path: root/arch/arm/mach-tegra/tegra_bb.c
diff options
context:
space:
mode:
authorHervé Fache <hfache@nvidia.com>2013-06-07 14:43:31 +0200
committerDan Willemsen <dwillemsen@nvidia.com>2013-09-14 13:38:04 -0700
commit342ba503a3ae4286e1361c2729aaa47f82da7328 (patch)
tree048bbcdebc941db046208356971da00ec1060583 /arch/arm/mach-tegra/tegra_bb.c
parent527ae5a2899c08553793d950722939e2f723e91e (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.c21
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;
}