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>
This commit is contained in:
Dima Zavin 2011-10-05 14:08:20 -07:00
parent 83b72704b0
commit efde655c8c
2 changed files with 43 additions and 13 deletions

View File

@ -73,7 +73,7 @@ struct fiq_debugger_state {
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_force_irq(struct fiq_debugger_state *state)
}
}
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 @@ static void sleep_timer_expired(unsigned long data)
{
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 @@ static void handle_wakeup(struct fiq_debugger_state *state)
{
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 @@ static void debug_console_write(struct console *co,
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 @@ int fiq_tty_write(struct tty_struct *tty, const unsigned char *buf, int count)
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 @@ static int fiq_debugger_probe(struct platform_device *pdev)
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 @@ static int fiq_debugger_probe(struct platform_device *pdev)
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);

View File

@ -27,6 +27,13 @@
#define FIQ_DEBUGGER_SIGNAL_IRQ_NAME "signal"
#define FIQ_DEBUGGER_WAKEUP_IRQ_NAME "wakeup"
/**
* struct fiq_debugger_pdata - fiq debugger platform data
* @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.
*/
struct fiq_debugger_pdata {
int (*uart_init)(struct platform_device *pdev);
void (*uart_free)(struct platform_device *pdev);
@ -34,6 +41,8 @@ struct fiq_debugger_pdata {
int (*uart_getc)(struct platform_device *pdev);
void (*uart_putc)(struct platform_device *pdev, unsigned int c);
void (*uart_flush)(struct platform_device *pdev);
void (*uart_enable)(struct platform_device *pdev);
void (*uart_disable)(struct platform_device *pdev);
void (*fiq_enable)(struct platform_device *pdev, unsigned int fiq,
bool enable);