From f4aea2122af88a6f940463efe124ccd00e026baa Mon Sep 17 00:00:00 2001
From: Dima Zavin <dima@android.com>
Date: Mon, 10 Oct 2011 15:24:34 -0700
Subject: [PATCH] ARM: common: fiq_debugger: add suspend/resume handlers

Change-Id: If6eb75059fdf4867eb9a974d60b9d50e5e3350d4
Signed-off-by: Dima Zavin <dima@android.com>
---
 arch/arm/common/fiq_debugger.c      | 35 +++++++++++++++++++++++++++--
 arch/arm/include/asm/fiq_debugger.h |  9 ++++++++
 2 files changed, 42 insertions(+), 2 deletions(-)

diff --git a/arch/arm/common/fiq_debugger.c b/arch/arm/common/fiq_debugger.c
index 6804b25f0810..7b037beb66d2 100644
--- a/arch/arm/common/fiq_debugger.c
+++ b/arch/arm/common/fiq_debugger.c
@@ -932,6 +932,26 @@ err:
 }
 #endif
 
+static int fiq_debugger_dev_suspend(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct fiq_debugger_state *state = platform_get_drvdata(pdev);
+
+	if (state->pdata->uart_dev_suspend)
+		return state->pdata->uart_dev_suspend(pdev);
+	return 0;
+}
+
+static int fiq_debugger_dev_resume(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct fiq_debugger_state *state = platform_get_drvdata(pdev);
+
+	if (state->pdata->uart_dev_resume)
+		return state->pdata->uart_dev_resume(pdev);
+	return 0;
+}
+
 static int fiq_debugger_probe(struct platform_device *pdev)
 {
 	int ret;
@@ -970,6 +990,8 @@ static int fiq_debugger_probe(struct platform_device *pdev)
 	state->signal_irq = platform_get_irq_byname(pdev, "signal");
 	state->wakeup_irq = platform_get_irq_byname(pdev, "wakeup");
 
+	platform_set_drvdata(pdev, state);
+
 	if (state->wakeup_irq < 0 && debug_have_fiq(state))
 		state->no_sleep = true;
 	state->ignore_next_wakeup_irq = !state->no_sleep;
@@ -1068,13 +1090,22 @@ err_uart_init:
 	if (state->clk)
 		clk_put(state->clk);
 	wake_lock_destroy(&state->debugger_wake_lock);
+	platform_set_drvdata(pdev, NULL);
 	kfree(state);
 	return ret;
 }
 
+static const struct dev_pm_ops fiq_debugger_dev_pm_ops = {
+	.suspend	= fiq_debugger_dev_suspend,
+	.resume		= fiq_debugger_dev_resume,
+};
+
 static struct platform_driver fiq_debugger_driver = {
-	.probe = fiq_debugger_probe,
-	.driver.name = "fiq_debugger",
+	.probe	= fiq_debugger_probe,
+	.driver	= {
+		.name	= "fiq_debugger",
+		.pm	= &fiq_debugger_dev_pm_ops,
+	},
 };
 
 static int __init fiq_debugger_init(void)
diff --git a/arch/arm/include/asm/fiq_debugger.h b/arch/arm/include/asm/fiq_debugger.h
index 39a7c1612868..4d274883ba6a 100644
--- a/arch/arm/include/asm/fiq_debugger.h
+++ b/arch/arm/include/asm/fiq_debugger.h
@@ -29,10 +29,16 @@
 
 /**
  * struct fiq_debugger_pdata - fiq debugger platform data
+ * @uart_resume:	used to restore uart state right before enabling
+ *			the fiq.
  * @uart_enable:	Do the work necessary to communicate with the uart
  *			hw (enable clocks, etc.). This must be ref-counted.
  * @uart_disable:	Do the work necessary to disable the uart hw
  *			(disable clocks, etc.). This must be ref-counted.
+ * @uart_dev_suspend:	called during PM suspend, generally not needed
+ *			for real fiq mode debugger.
+ * @uart_dev_resume:	called during PM resume, generally not needed
+ *			for real fiq mode debugger.
  */
 struct fiq_debugger_pdata {
 	int (*uart_init)(struct platform_device *pdev);
@@ -44,6 +50,9 @@ struct fiq_debugger_pdata {
 	void (*uart_enable)(struct platform_device *pdev);
 	void (*uart_disable)(struct platform_device *pdev);
 
+	int (*uart_dev_suspend)(struct platform_device *pdev);
+	int (*uart_dev_resume)(struct platform_device *pdev);
+
 	void (*fiq_enable)(struct platform_device *pdev, unsigned int fiq,
 								bool enable);
 	void (*fiq_ack)(struct platform_device *pdev, unsigned int fiq);
-- 
2.34.1