Merge branch 'linux-linaro-lsk-v4.4-android' of git://git.linaro.org/kernel/linux...
[firefly-linux-kernel-4.4.55.git] / drivers / staging / android / fiq_debugger / fiq_debugger.c
index 7f056831dbff923794f66d1fd1cc0a9e2adda84f..c9a38705f3ad402c1ea576273ade1570205ca292 100644 (file)
 #include <asm/fiq_glue.h>
 #endif
 
+#ifdef CONFIG_FIQ_DEBUGGER_UART_OVERLAY
+#include <linux/of.h>
+#endif
+
 #include <linux/uaccess.h>
 
 #include "fiq_debugger.h"
@@ -119,11 +123,13 @@ static bool initial_console_enable;
 #endif
 
 static bool fiq_kgdb_enable;
+static bool fiq_debugger_disable;
 
 module_param_named(no_sleep, initial_no_sleep, bool, 0644);
 module_param_named(debug_enable, initial_debug_enable, bool, 0644);
 module_param_named(console_enable, initial_console_enable, bool, 0644);
 module_param_named(kgdb_enable, fiq_kgdb_enable, bool, 0644);
+module_param_named(disable, fiq_debugger_disable, bool, 0644);
 
 #ifdef CONFIG_FIQ_DEBUGGER_WAKEUP_IRQ_ALWAYS_ON
 static inline
@@ -493,6 +499,8 @@ static bool fiq_debugger_fiq_exec(struct fiq_debugger_state *state,
                if (*cmd) {
                        char tmp_cmd[32];
                        strlcpy(tmp_cmd, cmd, sizeof(tmp_cmd));
+                       blocking_notifier_call_chain(&reboot_notifier_list,
+                                               SYS_RESTART, (char *)cmd);
                        machine_restart(tmp_cmd);
                } else {
                        machine_restart(NULL);
@@ -639,7 +647,7 @@ static bool fiq_debugger_handle_uart_interrupt(struct fiq_debugger_state *state,
        int count = 0;
        bool signal_helper = false;
 
-       if (this_cpu != state->current_cpu) {
+       if ((this_cpu != state->current_cpu) && (cpu_online(state->current_cpu))) {
                if (state->in_fiq)
                        return false;
 
@@ -657,6 +665,9 @@ static bool fiq_debugger_handle_uart_interrupt(struct fiq_debugger_state *state,
                return false;
        }
 
+       if (this_cpu != state->current_cpu)
+               state->current_cpu = this_cpu;
+
        state->in_fiq = true;
 
        while ((c = fiq_debugger_getc(state)) != FIQ_DEBUGGER_NO_CHAR) {
@@ -805,6 +816,13 @@ static void fiq_debugger_console_write(struct console *co,
        if (!state->console_enable && !state->syslog_dumping)
                return;
 
+#ifdef CONFIG_RK_CONSOLE_THREAD
+       if (state->pdata->console_write) {
+               state->pdata->console_write(state->pdev, s, count);
+               return;
+       }
+#endif
+
        fiq_debugger_uart_enable(state);
        spin_lock_irqsave(&state->console_lock, flags);
        while (count--) {
@@ -1201,10 +1219,40 @@ static struct platform_driver fiq_debugger_driver = {
        },
 };
 
+#if defined(CONFIG_FIQ_DEBUGGER_UART_OVERLAY)
+int fiq_debugger_uart_overlay(void)
+{
+       struct device_node *onp = of_find_node_by_path("/uart_overlay@0");
+       int ret;
+
+       if (!onp) {
+               pr_err("serial_debugger: uart overlay not found\n");
+               return -ENODEV;
+       }
+
+       ret = of_overlay_create(onp);
+       if (ret < 0) {
+               pr_err("serial_debugger: fail to create overlay: %d\n", ret);
+               of_node_put(onp);
+               return ret;
+       }
+
+       pr_info("serial_debugger: uart overlay applied\n");
+       return 0;
+}
+#endif
+
 static int __init fiq_debugger_init(void)
 {
+       if (fiq_debugger_disable) {
+               pr_err("serial_debugger: disabled\n");
+               return -ENODEV;
+       }
 #if defined(CONFIG_FIQ_DEBUGGER_CONSOLE)
        fiq_debugger_tty_init();
+#endif
+#if defined(CONFIG_FIQ_DEBUGGER_UART_OVERLAY)
+       fiq_debugger_uart_overlay();
 #endif
        return platform_driver_register(&fiq_debugger_driver);
 }