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;
}
}
+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)
{
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);
{
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);
}
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 = {
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;
}
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");
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);
#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);
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);