ARM: common: fiq_debugger: add uart_enable/disable platform callbacks

This allows the platform specific drivers to properly enable
and disable the uart at the appropriate times. On some platforms, just
managing the clock is not enough.

Change-Id: I5feaab04cfe313a4a9470ca274838676b9684201
Signed-off-by: Dima Zavin <dima@android.com>
diff --git a/arch/arm/common/fiq_debugger.c b/arch/arm/common/fiq_debugger.c
index 4c04cec..6804b25 100644
--- a/arch/arm/common/fiq_debugger.c
+++ b/arch/arm/common/fiq_debugger.c
@@ -73,7 +73,7 @@
 	bool debug_enable;
 	bool ignore_next_wakeup_irq;
 	struct timer_list sleep_timer;
-	bool uart_clk_enabled;
+	bool uart_enabled;
 	struct wake_lock debugger_wake_lock;
 	bool console_enable;
 	int current_cpu;
@@ -152,6 +152,22 @@
 	}
 }
 
+static void debug_uart_enable(struct fiq_debugger_state *state)
+{
+	if (state->clk)
+		clk_enable(state->clk);
+	if (state->pdata->uart_enable)
+		state->pdata->uart_enable(state->pdev);
+}
+
+static void debug_uart_disable(struct fiq_debugger_state *state)
+{
+	if (state->pdata->uart_disable)
+		state->pdata->uart_disable(state->pdev);
+	if (state->clk)
+		clk_disable(state->clk);
+}
+
 static void debug_uart_flush(struct fiq_debugger_state *state)
 {
 	if (state->pdata->uart_flush)
@@ -564,15 +580,14 @@
 {
 	struct fiq_debugger_state *state = (struct fiq_debugger_state *)data;
 
-	if (state->uart_clk_enabled && !state->no_sleep) {
+	if (state->uart_enabled && !state->no_sleep) {
 		if (state->debug_enable && !state->console_enable) {
 			state->debug_enable = false;
 			debug_printf_nfiq(state, "suspending fiq debugger\n");
 		}
 		state->ignore_next_wakeup_irq = true;
-		if (state->clk)
-			clk_disable(state->clk);
-		state->uart_clk_enabled = false;
+		debug_uart_disable(state);
+		state->uart_enabled = false;
 		enable_wakeup_irq(state);
 	}
 	wake_unlock(&state->debugger_wake_lock);
@@ -582,11 +597,10 @@
 {
 	if (state->wakeup_irq >= 0 && state->ignore_next_wakeup_irq) {
 		state->ignore_next_wakeup_irq = false;
-	} else if (!state->uart_clk_enabled) {
+	} else if (!state->uart_enabled) {
 		wake_lock(&state->debugger_wake_lock);
-		if (state->clk)
-			clk_enable(state->clk);
-		state->uart_clk_enabled = true;
+		debug_uart_enable(state);
+		state->uart_enabled = true;
 		disable_wakeup_irq(state);
 		mod_timer(&state->sleep_timer, jiffies + HZ / 2);
 	}
@@ -806,12 +820,14 @@
 	if (!state->console_enable)
 		return;
 
+	debug_uart_enable(state);
 	while (count--) {
 		if (*s == '\n')
 			state->pdata->uart_putc(state->pdev, '\r');
 		state->pdata->uart_putc(state->pdev, *s++);
 	}
 	debug_uart_flush(state);
+	debug_uart_disable(state);
 }
 
 static struct console fiq_debugger_console = {
@@ -848,12 +864,10 @@
 	if (!state->console_enable)
 		return count;
 
-	if (state->clk)
-		clk_enable(state->clk);
+	debug_uart_enable(state);
 	for (i = 0; i < count; i++)
 		state->pdata->uart_putc(state->pdev, *buf++);
-	if (state->clk)
-		clk_disable(state->clk);
+	debug_uart_disable(state);
 
 	return count;
 }
@@ -928,6 +942,9 @@
 
 	if (!pdata->uart_getc || !pdata->uart_putc)
 		return -EINVAL;
+	if ((pdata->uart_enable && !pdata->uart_disable) ||
+	    (!pdata->uart_enable && pdata->uart_disable))
+		return -EINVAL;
 
 	fiq = platform_get_irq_byname(pdev, "fiq");
 	uart_irq = platform_get_irq_byname(pdev, "uart_irq");
@@ -964,6 +981,10 @@
 	if (IS_ERR(state->clk))
 		state->clk = NULL;
 
+	/* do not call pdata->uart_enable here since uart_init may still
+	 * need to do some initialization before uart_enable can work.
+	 * So, only try to manage the clock during init.
+	 */
 	if (state->clk)
 		clk_enable(state->clk);