#include <linux/tty.h>
#include <linux/tty_flip.h>
#include <linux/wakelock.h>
+#include <linux/ptrace.h>
+
+#ifdef CONFIG_FIQ_DEBUGGER_TRUST_ZONE
+#include <linux/rockchip/rockchip_sip.h>
+#endif
#ifdef CONFIG_FIQ_GLUE
#include <asm/fiq_glue.h>
#endif
+#ifdef CONFIG_FIQ_DEBUGGER_UART_OVERLAY
+#include <linux/of.h>
+#endif
+
#include <linux/uaccess.h>
-#include <linux/rockchip/grf.h>
-#include <linux/rockchip/iomap.h>
-#include <linux/rockchip/cpu.h>
#include "fiq_debugger.h"
#include "fiq_debugger_priv.h"
#include "fiq_debugger_ringbuf.h"
-#ifdef CONFIG_RK29_WATCHDOG
-extern void rk29_wdt_keepalive(void);
-#define wdt_keepalive() rk29_wdt_keepalive()
-#else
-#define wdt_keepalive() do {} while (0)
-#endif
#define DEBUG_MAX 64
#define CMD_COUNT 0x0f
#define MAX_UNHANDLED_FIQ_COUNT 1000000
int debug_count;
#ifdef CONFIG_ARCH_ROCKCHIP
- char cmd_buf[CMD_COUNT+1][DEBUG_MAX];
+ char cmd_buf[CMD_COUNT + 1][DEBUG_MAX];
int back_pointer;
int current_pointer;
#endif
+
bool no_sleep;
bool debug_enable;
bool ignore_next_wakeup_irq;
static bool initial_console_enable;
#endif
-#ifdef CONFIG_FIQ_DEBUGGER_EL3_TO_EL1
+#ifdef CONFIG_FIQ_DEBUGGER_TRUST_ZONE
static struct fiq_debugger_state *state_tf;
#endif
static bool fiq_kgdb_enable;
-
-static unsigned long jif = 0, recv_count0 = 0, recv_count1 = 0;
+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);
-
-void gic_set_irq_secure(struct irq_data *d);
-void gic_set_irq_priority(struct irq_data *d, u8 pri);
+module_param_named(disable, fiq_debugger_disable, bool, 0644);
#ifdef CONFIG_FIQ_DEBUGGER_WAKEUP_IRQ_ALWAYS_ON
static inline
return (state->fiq >= 0);
}
-#if defined(CONFIG_FIQ_GLUE) || defined(CONFIG_FIQ_DEBUGGER_EL3_TO_EL1)
+#if defined(CONFIG_FIQ_GLUE) || defined(CONFIG_FIQ_DEBUGGER_TRUST_ZONE)
static void fiq_debugger_force_irq(struct fiq_debugger_state *state)
{
unsigned int irq = state->signal_irq;
return;
if (irq < 0)
return;
+
if (state->pdata->force_irq) {
state->pdata->force_irq(state->pdev, irq);
} else {
struct irq_chip *chip = irq_get_chip(irq);
+
if (chip && chip->irq_retrigger)
chip->irq_retrigger(irq_get_irq_data(irq));
}
static void fiq_debugger_dump_kernel_log(struct fiq_debugger_state *state)
{
-#ifdef CONFIG_ARCH_ROCKCHIP
- char buf[968];
-#else
char buf[512];
-#endif
size_t len;
struct kmsg_dumper dumper = { .active = true };
sizeof(buf) - 1, &len)) {
buf[len] = 0;
fiq_debugger_puts(state, buf);
-#ifdef CONFIG_ARCH_ROCKCHIP
- wdt_keepalive();
-#endif
- }
-}
-
-#ifdef CONFIG_RK_LAST_LOG
-#include <linux/ctype.h>
-extern char *rk_last_log_get(unsigned *size);
-static void fiq_debugger_dump_last_kernel_log(struct fiq_debugger_state *state)
-{
- unsigned size, i, c;
- char *s = rk_last_log_get(&size);
-
- for (i = 0; i < size; i++) {
- if (i % 1024 == 0)
- wdt_keepalive();
- c = s[i];
- if (c == '\n') {
- state->pdata->uart_putc(state->pdev, '\r');
- state->pdata->uart_putc(state->pdev, c);
- } else if (isascii(c) && isprint(c)) {
- state->pdata->uart_putc(state->pdev, c);
- }
}
}
-#endif
static void fiq_debugger_printf(struct fiq_debugger_output *output,
const char *fmt, ...)
static void fiq_debugger_dump_irqs(struct fiq_debugger_state *state)
{
int n;
- unsigned int cpu;
struct irq_desc *desc;
fiq_debugger_printf(&state->output,
(act && act->name) ? act->name : "???");
state->last_irqs[n] = kstat_irqs(n);
}
-
-#ifdef CONFIG_ARCH_ROCKCHIP
- for (n = 16; n < 32; n++) {
- desc = irq_to_desc(n);
- if (!desc)
- continue;
- for (cpu = 0; cpu < NR_CPUS; cpu++) {
- unsigned int irqs = kstat_irqs_cpu(n, cpu);
- struct irqaction *act = desc->action;
- const char *name = (act && act->name) ? act->name : "???";
- if (!irqs)
- continue;
- fiq_debugger_printf(&state->output,
- "%5d: %10u %11u %s (CPU%d)\n", n,
- irqs, irqs - state->last_local_irqs[cpu][n],
- name, cpu);
- state->last_local_irqs[cpu][n] = irqs;
- }
- }
- for (n = 0; n < NR_IPI; n++) {
-#define S(x,s) [x] = s
-#ifdef CONFIG_ARM
- enum ipi_msg_type {
- IPI_WAKEUP,
- IPI_TIMER,
- IPI_RESCHEDULE,
- IPI_CALL_FUNC,
- IPI_CALL_FUNC_SINGLE,
- IPI_CPU_STOP,
- IPI_COMPLETION,
- IPI_CPU_BACKTRACE,
- };
- static const char *ipi_types[NR_IPI] = {
- S(IPI_WAKEUP, "CPU wakeup"),
- S(IPI_TIMER, "Timer broadcast"),
- S(IPI_RESCHEDULE, "Rescheduling"),
- S(IPI_CALL_FUNC, "Function call"),
- S(IPI_CALL_FUNC_SINGLE, "Single function call"),
- S(IPI_CPU_STOP, "CPU stop"),
- S(IPI_COMPLETION, "Completion"),
- S(IPI_CPU_BACKTRACE, "CPU backtrace"),
- };
-#elif defined(CONFIG_ARM64)
- enum ipi_msg_type {
- IPI_RESCHEDULE,
- IPI_CALL_FUNC,
- IPI_CALL_FUNC_SINGLE,
- IPI_CPU_STOP,
- IPI_TIMER,
- };
- static const char *ipi_types[NR_IPI] = {
- S(IPI_RESCHEDULE, "Rescheduling"),
- S(IPI_CALL_FUNC, "Function call"),
- S(IPI_CALL_FUNC_SINGLE, "Single function call"),
- S(IPI_CPU_STOP, "CPU stop"),
- S(IPI_TIMER, "Timer broadcast"),
- };
-#endif
-#undef S
- for (cpu = 0; cpu < NR_CPUS; cpu++) {
- unsigned int irqs = __get_irq_stat(cpu, ipi_irqs[n]);
- if (irqs == 0)
- continue;
- fiq_debugger_printf(&state->output,
- "%5d: %10u %11u %s (CPU%d)\n",
- n, irqs, irqs - state->last_local_irqs[cpu][n],
- ipi_types[n], cpu);
- state->last_local_irqs[cpu][n] = irqs;
- }
- }
-#endif
}
static void fiq_debugger_do_ps(struct fiq_debugger_state *state)
static void fiq_debugger_irq_exec(struct fiq_debugger_state *state, char *cmd)
{
int invalid_cmd = 0;
+
if (!strcmp(cmd, "ps"))
fiq_debugger_do_ps(state);
if (!strcmp(cmd, "sysrq"))
}
if (invalid_cmd == 0) {
- state->current_pointer = (state->current_pointer-1) & CMD_COUNT;
+ state->current_pointer =
+ (state->current_pointer - 1) & CMD_COUNT;
if (strcmp(state->cmd_buf[state->current_pointer], state->debug_buf)) {
- state->current_pointer = (state->current_pointer+1) & CMD_COUNT;
+ state->current_pointer =
+ (state->current_pointer + 1) & CMD_COUNT;
memset(state->cmd_buf[state->current_pointer], 0, DEBUG_MAX);
strcpy(state->cmd_buf[state->current_pointer], state->debug_buf);
}
memset(state->debug_buf, 0, DEBUG_MAX);
- state->current_pointer = (state->current_pointer+1) & CMD_COUNT;
+ state->current_pointer = (state->current_pointer + 1) & CMD_COUNT;
state->back_pointer = state->current_pointer;
}
#endif
{"reboot"},
{"irqs"},
{"kmsg"},
-#ifdef CONFIG_RK_LAST_LOG
- {"last_kmsg"},
-#endif
{"version"},
{"sleep"},
{"nosleep"},
};
#endif
-
static void fiq_debugger_help(struct fiq_debugger_state *state)
{
fiq_debugger_printf(&state->output,
" pc PC status\n"
" regs Register dump\n"
" allregs Extended Register dump\n"
- " bt Stack trace\n");
- fiq_debugger_printf(&state->output,
+ " bt Stack trace\n"
" reboot [<c>] Reboot with command <c>\n"
" reset [<c>] Hard reset with command <c>\n"
- " irqs Interupt status\n"
+ " irqs Interupt status\n");
+ fiq_debugger_printf(&state->output,
" kmsg Kernel log\n"
" version Kernel version\n");
-#ifdef CONFIG_RK_LAST_LOG
- fiq_debugger_printf(&state->output,
- " last_kmsg Last kernel log\n");
-#endif
fiq_debugger_printf(&state->output,
" sleep Allow sleep while in FIQ\n"
" nosleep Disable sleep while in FIQ\n"
cpumask_clear(&cpumask);
cpumask_set_cpu(get_cpu(), &cpumask);
+ put_cpu();
irq_set_affinity(state->uart_irq, &cpumask);
}
static void fiq_debugger_switch_cpu(struct fiq_debugger_state *state, int cpu)
{
+ if (!cpu_online(cpu)) {
+ fiq_debugger_printf(&state->output, "cpu %d offline\n", cpu);
+ return;
+ }
+
if (!fiq_debugger_have_fiq(state))
smp_call_function_single(cpu, fiq_debugger_take_affinity, state,
false);
#ifdef CONFIG_ARCH_ROCKCHIP
else {
-#ifdef CONFIG_FIQ_DEBUGGER_EL3_TO_EL1
- if (state->pdata->switch_cpu)
- state->pdata->switch_cpu(state->pdev, cpu);
-#else
- struct cpumask cpumask;
-
- if (!cpu_online(cpu)) {
- fiq_debugger_printf(&state->output, "cpu %d offline\n", cpu);
+#ifdef CONFIG_FIQ_DEBUGGER_TRUST_ZONE
+ if (sip_fiq_debugger_is_enabled()) {
+ if (state->pdata->switch_cpu) {
+ state->pdata->switch_cpu(state->pdev, cpu);
+ state->current_cpu = cpu;
+ }
return;
}
+#else
+ struct cpumask cpumask;
cpumask_clear(&cpumask);
cpumask_set_cpu(cpu, &cpumask);
} else if (!strcmp(cmd, "allregs")) {
fiq_debugger_dump_allregs(&state->output, regs);
} else if (!strcmp(cmd, "bt")) {
- fiq_debugger_dump_stacktrace(&state->output, regs, 100, svc_sp);
+ if (!user_mode((struct pt_regs *)regs))
+ fiq_debugger_dump_stacktrace(&state->output, regs,
+ 100, svc_sp);
+ else
+ fiq_debugger_printf(&state->output, "User mode\n");
} else if (!strncmp(cmd, "reset", 5)) {
cmd += 5;
while (*cmd == ' ')
fiq_debugger_dump_irqs(state);
} else if (!strcmp(cmd, "kmsg")) {
fiq_debugger_dump_kernel_log(state);
-#ifdef CONFIG_RK_LAST_LOG
- } else if (!strcmp(cmd, "last_kmsg")) {
- fiq_debugger_dump_last_kernel_log(state);
-#endif
} else if (!strcmp(cmd, "version")) {
fiq_debugger_printf(&state->output, "%s\n", linux_banner);
} else if (!strcmp(cmd, "sleep")) {
fiq_debugger_printf(&state->output, "console mode\n");
fiq_debugger_uart_flush(state);
state->console_enable = true;
-#ifdef CONFIG_FIQ_DEBUGGER_EL3_TO_EL1
- if (state->pdata->enable_debug)
- state->pdata->enable_debug(state->pdev, false);
+#ifdef CONFIG_FIQ_DEBUGGER_TRUST_ZONE
+ if (sip_fiq_debugger_is_enabled()) {
+ if (state->pdata->enable_debug)
+ state->pdata->enable_debug(state->pdev, false);
+ }
#endif
} else if (!strcmp(cmd, "cpu")) {
fiq_debugger_printf(&state->output, "cpu %d\n", state->current_cpu);
} else if (!strncmp(cmd, "cpu ", 4)) {
unsigned long cpu = 0;
- if (strict_strtoul(cmd + 4, 10, &cpu) == 0)
+ if (kstrtoul(cmd + 4, 10, &cpu) == 0)
fiq_debugger_switch_cpu(state, cpu);
else
fiq_debugger_printf(&state->output, "invalid cpu\n");
+
fiq_debugger_printf(&state->output, "cpu %d\n", state->current_cpu);
} else {
if (state->debug_busy) {
{
char *s;
int i = 0;
+
if (c == 'A') {
- state->back_pointer = (state->back_pointer-1) & CMD_COUNT;
+ state->back_pointer = (state->back_pointer - 1) & CMD_COUNT;
if (state->back_pointer != state->current_pointer) {
s = state->cmd_buf[state->back_pointer];
if (*s != 0) {
- for(i = 0; i < strlen(state->debug_buf)-1; i++) {
+ for (i = 0; i < strlen(state->debug_buf) - 1; i++) {
state->pdata->uart_putc(state->pdev, 8);
state->pdata->uart_putc(state->pdev, ' ');
state->pdata->uart_putc(state->pdev, 8);
state->debug_count = strlen(state->debug_buf);
fiq_debugger_printf(&state->output, state->debug_buf);
} else {
- state->back_pointer = (state->back_pointer+1) & CMD_COUNT;
+ state->back_pointer = (state->back_pointer + 1) & CMD_COUNT;
}
} else {
- state->back_pointer = (state->back_pointer+1) & CMD_COUNT;
+ state->back_pointer = (state->back_pointer + 1) & CMD_COUNT;
}
} else if (c == 'B') {
-
if (state->back_pointer != state->current_pointer) {
- state->back_pointer = (state->back_pointer+1) & CMD_COUNT;
- if(state->back_pointer == state->current_pointer){
+ state->back_pointer = (state->back_pointer + 1) & CMD_COUNT;
+ if (state->back_pointer == state->current_pointer) {
goto cmd_clear;
} else {
s = state->cmd_buf[state->back_pointer];
if (*s != 0) {
- for(i = 0; i < strlen(state->debug_buf)-1; i++) {
+ for (i = 0; i < strlen(state->debug_buf) - 1; i++) {
state->pdata->uart_putc(state->pdev, 8);
state->pdata->uart_putc(state->pdev, ' ');
state->pdata->uart_putc(state->pdev, 8);
}
} else {
cmd_clear:
- for(i = 0; i < strlen(state->debug_buf)-1; i++) {
+ for (i = 0; i < strlen(state->debug_buf) - 1; i++) {
state->pdata->uart_putc(state->pdev, 8);
state->pdata->uart_putc(state->pdev, ' ');
state->pdata->uart_putc(state->pdev, 8);
static void fiq_debugger_cmd_tab(struct fiq_debugger_state *state)
{
- int i,j;
+ int i, j;
int count = 0;
- for (i = 0; i < ARRAY_SIZE(cmd_buf); i++) {
+ for (i = 0; i < ARRAY_SIZE(cmd_buf); i++)
cmd_buf[i][15] = 1;
- }
for (j = 1; j <= strlen(state->debug_buf); j++) {
count = 0;
for (i = 0; i < ARRAY_SIZE(cmd_buf); i++) {
if (cmd_buf[i][15] == 1) {
- if (strncmp(state->debug_buf, cmd_buf[i], j)) {
+ if (strncmp(state->debug_buf, cmd_buf[i], j))
cmd_buf[i][15] = 0;
- } else {
+ else
count++;
- }
}
}
if (count == 0)
break;
}
- for(j = 0; j < strlen(state->debug_buf); j++) {
+ for (j = 0; j < strlen(state->debug_buf); j++) {
state->pdata->uart_putc(state->pdev, 8);
state->pdata->uart_putc(state->pdev, ' ');
state->pdata->uart_putc(state->pdev, 8);
strcpy(state->debug_buf, cmd_buf[i]);
state->debug_count = strlen(state->debug_buf);
fiq_debugger_printf(&state->output, state->debug_buf);
-
}
}
static int last_c;
int count = 0;
bool signal_helper = false;
- unsigned long ms = 0;
- if (this_cpu != state->current_cpu) {
+ if ((this_cpu != state->current_cpu) &&
+ (cpu_online(state->current_cpu))) {
if (state->in_fiq)
return false;
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) {
- recv_count0++;
- if((recv_count0 - recv_count1) > 128) {
- ms = jiffies_to_msecs(jiffies - jif);
- if(ms < 1000) {
- if(cpu_is_rk3288()){
- writel_relaxed((0x00c0 << 16),
- RK_GRF_VIRT + RK3288_GRF_UOC0_CON3);
- }
- }
- jif = jiffies;
- recv_count1 = recv_count0;
- }
- count++;
+ count++;
if (!state->debug_enable) {
if ((c == 13) || (c == 10)) {
state->debug_enable = true;
else
fiq_debugger_puts(state,
"irq debugger mode\n");
-
state->debug_count = 0;
#ifdef CONFIG_ARCH_ROCKCHIP
fiq_debugger_puts(state, "Enter ? to get command help\n");
state->back_pointer = CMD_COUNT;
state->current_pointer = CMD_COUNT;
- memset(state->cmd_buf, 0, (CMD_COUNT+1)*DEBUG_MAX);
+ memset(state->cmd_buf, 0, (CMD_COUNT + 1) * DEBUG_MAX);
#endif
-#ifdef CONFIG_FIQ_DEBUGGER_EL3_TO_EL1
- if (state->pdata->enable_debug)
- state->pdata->enable_debug(state->pdev, true);
+#ifdef CONFIG_FIQ_DEBUGGER_TRUST_ZONE
+ if (sip_fiq_debugger_is_enabled()) {
+ if (state->pdata->enable_debug)
+ state->pdata->enable_debug(state->pdev,
+ true);
+ }
#endif
fiq_debugger_prompt(state);
+ fiq_debugger_ringbuf_push(state->tty_rbuf, 8);
+ fiq_debugger_ringbuf_push(state->tty_rbuf, 8);
#ifdef CONFIG_FIQ_DEBUGGER_CONSOLE
} else if (state->console_enable && state->tty_rbuf) {
fiq_debugger_ringbuf_push(state->tty_rbuf, c);
state->pdata->uart_putc(state->pdev, 8);
}
fiq_debugger_cmd_check_back(state, c);
- //tab
} else if (c == 9) {
fiq_debugger_cmd_tab(state);
#endif
signal_helper |=
fiq_debugger_fiq_exec(state,
state->debug_buf,
- regs, svc_sp);
+ regs, svc_sp);
#ifdef CONFIG_ARCH_ROCKCHIP
if (signal_helper == false) {
- state->current_pointer = (state->current_pointer-1) & CMD_COUNT;
+ state->current_pointer =
+ (state->current_pointer - 1) & CMD_COUNT;
if (strcmp(state->cmd_buf[state->current_pointer], state->debug_buf)) {
- state->current_pointer = (state->current_pointer+1) & CMD_COUNT;
+ state->current_pointer =
+ (state->current_pointer + 1) & CMD_COUNT;
memset(state->cmd_buf[state->current_pointer], 0, DEBUG_MAX);
strcpy(state->cmd_buf[state->current_pointer], state->debug_buf);
}
memset(state->debug_buf, 0, DEBUG_MAX);
- state->current_pointer = (state->current_pointer+1) & CMD_COUNT;
- state->back_pointer = state->current_pointer;
+ state->current_pointer =
+ (state->current_pointer + 1) & CMD_COUNT;
+ state->back_pointer =
+ state->current_pointer;
}
#endif
} else {
#ifdef CONFIG_FIQ_GLUE
static void fiq_debugger_fiq(struct fiq_glue_handler *h,
- void *regs, void *svc_sp)
+ const struct pt_regs *regs, void *svc_sp)
{
struct fiq_debugger_state *state =
container_of(h, struct fiq_debugger_state, handler);
unsigned int this_cpu = THREAD_INFO(svc_sp)->cpu;
bool need_irq;
- /* RK2928 USB-UART function, otg dp/dm default in uart status;
- * connect with otg cable&usb device, dp/dm will be hi-z status
- * and make uart controller enter infinite fiq loop
- */
-#ifdef CONFIG_RK_USB_UART
- if (cpu_is_rk3188()) {
- if (!(readl_relaxed(RK_GRF_VIRT + RK3188_GRF_SOC_STATUS0) & (1 << 13)) ||
- (readl_relaxed(RK_GRF_VIRT + RK3188_GRF_SOC_STATUS0) & (1 << 10))) {
- /* id low or bvalid high, enter usb phy */
- writel_relaxed((0x0300 << 16), RK_GRF_VIRT + RK3188_GRF_UOC0_CON0);
- }
- } else if (cpu_is_rk3288()) {
- if (!(readl_relaxed(RK_GRF_VIRT + RK3288_GRF_SOC_STATUS2) & (1 << 17)) ||
- (readl_relaxed(RK_GRF_VIRT + RK3288_GRF_SOC_STATUS2) & (1 << 14))) {
- /* id low or bvalid high, enter usb phy */
- writel_relaxed((0x00c0 << 16), RK_GRF_VIRT + RK3288_GRF_UOC0_CON3);
- }
- }
-#endif
need_irq = fiq_debugger_handle_uart_interrupt(state, this_cpu, regs,
svc_sp);
if (need_irq)
}
#endif
+#ifdef CONFIG_FIQ_DEBUGGER_TRUST_ZONE
+void fiq_debugger_fiq(void *regs, u32 cpu)
+{
+ struct fiq_debugger_state *state = state_tf;
+ bool need_irq;
+
+ if (!state)
+ return;
+
+ if (!user_mode((struct pt_regs *)regs))
+ need_irq = fiq_debugger_handle_uart_interrupt(state,
+ smp_processor_id(),
+ regs, current_thread_info());
+ else
+ need_irq = fiq_debugger_handle_uart_interrupt(state, cpu,
+ regs, current_thread_info());
+ if (need_irq)
+ fiq_debugger_force_irq(state);
+}
+#endif
+
/*
* When not using FIQs, we only use this single interrupt as an entry point.
* This just effectively takes over the UART interrupt and does all the work
return IRQ_HANDLED;
}
-#ifdef CONFIG_FIQ_DEBUGGER_EL3_TO_EL1
-void fiq_debugger_fiq(void *regs)
-{
- struct fiq_debugger_state *state = state_tf;
- bool need_irq;
-
- if (!state)
- return;
- need_irq = fiq_debugger_handle_uart_interrupt(state, smp_processor_id(),
- regs,
- current_thread_info());
- if (need_irq)
- fiq_debugger_force_irq(state);
-}
-#endif
-
/*
* If FIQs are used, not everything can happen in fiq context.
* FIQ handler does what it can and then signals this interrupt to finish the
state->console_enable = initial_console_enable;
state->fiq = fiq;
-#ifdef CONFIG_FIQ_DEBUGGER_EL3_TO_EL1
- if (fiq > 0)
- state->uart_irq = fiq;
- else
- state->uart_irq = uart_irq;
-#else
state->uart_irq = uart_irq;
-#endif
-
state->signal_irq = platform_get_irq_byname(pdev, "signal");
state->wakeup_irq = platform_get_irq_byname(pdev, "wakeup");
"<hit enter %sto activate fiq debugger>\n",
state->no_sleep ? "" : "twice ");
-#ifdef CONFIG_FIQ_GLUE
if (fiq_debugger_have_fiq(state)) {
+#ifdef CONFIG_FIQ_GLUE
+#ifdef CONFIG_FIQ_DEBUGGER_TRUST_ZONE
+ if (sip_fiq_debugger_is_enabled()) {
+ } else
+#endif
+ {
state->handler.fiq = fiq_debugger_fiq;
state->handler.resume = fiq_debugger_resume;
ret = fiq_glue_register_handler(&state->handler);
goto err_register_irq;
}
#ifdef CONFIG_ARCH_ROCKCHIP
- //set state->fiq to secure state, so fiq is avalable
+ /* set state->fiq to secure state, so fiq is available */
gic_set_irq_secure(irq_get_irq_data(state->fiq));
- //set state->fiq priority a little higher than other interrupts (normal is 0xa0)
+ /*
+ * set state->fiq priority a little higher than other
+ * interrupts (normal is 0xa0)
+ */
gic_set_irq_priority(irq_get_irq_data(state->fiq), 0x90);
#endif
pdata->fiq_enable(pdev, state->fiq, 1);
- } else
+ }
#endif
- {
+ } else {
ret = request_irq(state->uart_irq, fiq_debugger_uart_irq,
IRQF_NO_SUSPEND, "debug", state);
if (ret) {
if (state->wakeup_irq >= 0) {
ret = request_irq(state->wakeup_irq,
fiq_debugger_wakeup_irq_handler,
- IRQF_TRIGGER_FALLING | IRQF_DISABLED,
+ IRQF_TRIGGER_FALLING,
"debug-wakeup", state);
if (ret) {
pr_err("serial_debugger: "
if (state->no_sleep)
fiq_debugger_handle_wakeup(state);
-#ifdef CONFIG_FIQ_DEBUGGER_EL3_TO_EL1
+#ifdef CONFIG_FIQ_DEBUGGER_TRUST_ZONE
state_tf = state;
#endif
},
};
+#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);
}