From 51edc65d8ce26804d87b99d8cf365ae98ba6ad11 Mon Sep 17 00:00:00 2001 From: Mark Salyzyn Date: Thu, 29 Aug 2019 10:24:34 -0700 Subject: [PATCH] [RAMEN9610-20877]ANDROID: fiq_debugger: remove This represents a rollup of a series of reverts, simplified are modifications to remove fiq_glue and fiq_debugger references in: arch/arm/common/Kconfig arch/arm/common/Makefile drivers/staGing/android/Kconfig drivers/staGing/android/Makefile And deletion of: arch/arm/common/fiq_glue.S arch/arm/common/fiq_glue_setup.c drivers/staGing/android/fiq_debugger/ Signed-off-by: Mark Salyzyn Bug: 32402555 Bug: 36101220 Change-Id: I3f74b1ff5e4971d619bcb37a911fed68fbb538d5 --- arch/arm/common/Kconfig | 4 - arch/arm/common/Makefile | 1 - arch/arm/common/fiq_glue.S | 118 -- arch/arm/common/fiq_glue_setup.c | 147 -- drivers/staging/android/Kconfig | 2 - drivers/staging/android/Makefile | 1 - drivers/staging/android/fiq_debugger/Kconfig | 58 - drivers/staging/android/fiq_debugger/Makefile | 4 - .../android/fiq_debugger/fiq_debugger.c | 1246 ----------------- .../android/fiq_debugger/fiq_debugger.h | 64 - .../android/fiq_debugger/fiq_debugger_arm.c | 240 ---- .../android/fiq_debugger/fiq_debugger_arm64.c | 201 --- .../android/fiq_debugger/fiq_debugger_priv.h | 37 - .../fiq_debugger/fiq_debugger_ringbuf.h | 94 -- .../android/fiq_debugger/fiq_watchdog.c | 56 - .../android/fiq_debugger/fiq_watchdog.h | 20 - 16 files changed, 2293 deletions(-) delete mode 100644 arch/arm/common/fiq_glue.S delete mode 100644 arch/arm/common/fiq_glue_setup.c delete mode 100644 drivers/staging/android/fiq_debugger/Kconfig delete mode 100644 drivers/staging/android/fiq_debugger/Makefile delete mode 100644 drivers/staging/android/fiq_debugger/fiq_debugger.c delete mode 100644 drivers/staging/android/fiq_debugger/fiq_debugger.h delete mode 100644 drivers/staging/android/fiq_debugger/fiq_debugger_arm.c delete mode 100644 drivers/staging/android/fiq_debugger/fiq_debugger_arm64.c delete mode 100644 drivers/staging/android/fiq_debugger/fiq_debugger_priv.h delete mode 100644 drivers/staging/android/fiq_debugger/fiq_debugger_ringbuf.h delete mode 100644 drivers/staging/android/fiq_debugger/fiq_watchdog.c delete mode 100644 drivers/staging/android/fiq_debugger/fiq_watchdog.h diff --git a/arch/arm/common/Kconfig b/arch/arm/common/Kconfig index f07f47943bf3..e5ad0708849a 100644 --- a/arch/arm/common/Kconfig +++ b/arch/arm/common/Kconfig @@ -15,7 +15,3 @@ config SHARP_PARAM config SHARP_SCOOP bool - -config FIQ_GLUE - bool - select FIQ diff --git a/arch/arm/common/Makefile b/arch/arm/common/Makefile index 10b506469c95..70b4a14ed993 100644 --- a/arch/arm/common/Makefile +++ b/arch/arm/common/Makefile @@ -5,7 +5,6 @@ obj-y += firmware.o -obj-$(CONFIG_FIQ_GLUE) += fiq_glue.o fiq_glue_setup.o obj-$(CONFIG_SA1111) += sa1111.o obj-$(CONFIG_DMABOUNCE) += dmabounce.o obj-$(CONFIG_SHARP_LOCOMO) += locomo.o diff --git a/arch/arm/common/fiq_glue.S b/arch/arm/common/fiq_glue.S deleted file mode 100644 index 24b42cec4813..000000000000 --- a/arch/arm/common/fiq_glue.S +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright (C) 2008 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include - - .text - - .global fiq_glue_end - - /* fiq stack: r0-r15,cpsr,spsr of interrupted mode */ - -ENTRY(fiq_glue) - /* store pc, cpsr from previous mode, reserve space for spsr */ - mrs r12, spsr - sub lr, lr, #4 - subs r10, #1 - bne nested_fiq - - str r12, [sp, #-8]! - str lr, [sp, #-4]! - - /* store r8-r14 from previous mode */ - sub sp, sp, #(7 * 4) - stmia sp, {r8-r14}^ - nop - - /* store r0-r7 from previous mode */ - stmfd sp!, {r0-r7} - - /* setup func(data,regs) arguments */ - mov r0, r9 - mov r1, sp - mov r3, r8 - - mov r7, sp - - /* Get sp and lr from non-user modes */ - and r4, r12, #MODE_MASK - cmp r4, #USR_MODE - beq fiq_from_usr_mode - - mov r7, sp - orr r4, r4, #(PSR_I_BIT | PSR_F_BIT) - msr cpsr_c, r4 - str sp, [r7, #(4 * 13)] - str lr, [r7, #(4 * 14)] - mrs r5, spsr - str r5, [r7, #(4 * 17)] - - cmp r4, #(SVC_MODE | PSR_I_BIT | PSR_F_BIT) - /* use fiq stack if we reenter this mode */ - subne sp, r7, #(4 * 3) - -fiq_from_usr_mode: - msr cpsr_c, #(SVC_MODE | PSR_I_BIT | PSR_F_BIT) - mov r2, sp - sub sp, r7, #12 - stmfd sp!, {r2, ip, lr} - /* call func(data,regs) */ - blx r3 - ldmfd sp, {r2, ip, lr} - mov sp, r2 - - /* restore/discard saved state */ - cmp r4, #USR_MODE - beq fiq_from_usr_mode_exit - - msr cpsr_c, r4 - ldr sp, [r7, #(4 * 13)] - ldr lr, [r7, #(4 * 14)] - msr spsr_cxsf, r5 - -fiq_from_usr_mode_exit: - msr cpsr_c, #(FIQ_MODE | PSR_I_BIT | PSR_F_BIT) - - ldmfd sp!, {r0-r7} - ldr lr, [sp, #(4 * 7)] - ldr r12, [sp, #(4 * 8)] - add sp, sp, #(10 * 4) -exit_fiq: - msr spsr_cxsf, r12 - add r10, #1 - cmp r11, #0 - moveqs pc, lr - bx r11 /* jump to custom fiq return function */ - -nested_fiq: - orr r12, r12, #(PSR_F_BIT) - b exit_fiq - -fiq_glue_end: - -ENTRY(fiq_glue_setup) /* func, data, sp, smc call number */ - stmfd sp!, {r4} - mrs r4, cpsr - msr cpsr_c, #(FIQ_MODE | PSR_I_BIT | PSR_F_BIT) - movs r8, r0 - mov r9, r1 - mov sp, r2 - mov r11, r3 - moveq r10, #0 - movne r10, #1 - msr cpsr_c, r4 - ldmfd sp!, {r4} - bx lr - diff --git a/arch/arm/common/fiq_glue_setup.c b/arch/arm/common/fiq_glue_setup.c deleted file mode 100644 index 8cb1b611c6d5..000000000000 --- a/arch/arm/common/fiq_glue_setup.c +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Copyright (C) 2010 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include -#include -#include -#include -#include - -extern unsigned char fiq_glue, fiq_glue_end; -extern void fiq_glue_setup(void *func, void *data, void *sp, - fiq_return_handler_t fiq_return_handler); - -static struct fiq_handler fiq_debbuger_fiq_handler = { - .name = "fiq_glue", -}; -DEFINE_PER_CPU(void *, fiq_stack); -static struct fiq_glue_handler *current_handler; -static fiq_return_handler_t fiq_return_handler; -static DEFINE_MUTEX(fiq_glue_lock); - -static void fiq_glue_setup_helper(void *info) -{ - struct fiq_glue_handler *handler = info; - fiq_glue_setup(handler->fiq, handler, - __get_cpu_var(fiq_stack) + THREAD_START_SP, - fiq_return_handler); -} - -int fiq_glue_register_handler(struct fiq_glue_handler *handler) -{ - int ret; - int cpu; - - if (!handler || !handler->fiq) - return -EINVAL; - - mutex_lock(&fiq_glue_lock); - if (fiq_stack) { - ret = -EBUSY; - goto err_busy; - } - - for_each_possible_cpu(cpu) { - void *stack; - stack = (void *)__get_free_pages(GFP_KERNEL, THREAD_SIZE_ORDER); - if (WARN_ON(!stack)) { - ret = -ENOMEM; - goto err_alloc_fiq_stack; - } - per_cpu(fiq_stack, cpu) = stack; - } - - ret = claim_fiq(&fiq_debbuger_fiq_handler); - if (WARN_ON(ret)) - goto err_claim_fiq; - - current_handler = handler; - on_each_cpu(fiq_glue_setup_helper, handler, true); - set_fiq_handler(&fiq_glue, &fiq_glue_end - &fiq_glue); - - mutex_unlock(&fiq_glue_lock); - return 0; - -err_claim_fiq: -err_alloc_fiq_stack: - for_each_possible_cpu(cpu) { - __free_pages(per_cpu(fiq_stack, cpu), THREAD_SIZE_ORDER); - per_cpu(fiq_stack, cpu) = NULL; - } -err_busy: - mutex_unlock(&fiq_glue_lock); - return ret; -} - -static void fiq_glue_update_return_handler(void (*fiq_return)(void)) -{ - fiq_return_handler = fiq_return; - if (current_handler) - on_each_cpu(fiq_glue_setup_helper, current_handler, true); -} - -int fiq_glue_set_return_handler(void (*fiq_return)(void)) -{ - int ret; - - mutex_lock(&fiq_glue_lock); - if (fiq_return_handler) { - ret = -EBUSY; - goto err_busy; - } - fiq_glue_update_return_handler(fiq_return); - ret = 0; -err_busy: - mutex_unlock(&fiq_glue_lock); - - return ret; -} -EXPORT_SYMBOL(fiq_glue_set_return_handler); - -int fiq_glue_clear_return_handler(void (*fiq_return)(void)) -{ - int ret; - - mutex_lock(&fiq_glue_lock); - if (WARN_ON(fiq_return_handler != fiq_return)) { - ret = -EINVAL; - goto err_inval; - } - fiq_glue_update_return_handler(NULL); - ret = 0; -err_inval: - mutex_unlock(&fiq_glue_lock); - - return ret; -} -EXPORT_SYMBOL(fiq_glue_clear_return_handler); - -/** - * fiq_glue_resume - Restore fiqs after suspend or low power idle states - * - * This must be called before calling local_fiq_enable after returning from a - * power state where the fiq mode registers were lost. If a driver provided - * a resume hook when it registered the handler it will be called. - */ - -void fiq_glue_resume(void) -{ - if (!current_handler) - return; - fiq_glue_setup(current_handler->fiq, current_handler, - __get_cpu_var(fiq_stack) + THREAD_START_SP, - fiq_return_handler); - if (current_handler->resume) - current_handler->resume(current_handler); -} - diff --git a/drivers/staging/android/Kconfig b/drivers/staging/android/Kconfig index 5db9d25a4fe9..12daf47d9d76 100644 --- a/drivers/staging/android/Kconfig +++ b/drivers/staging/android/Kconfig @@ -35,8 +35,6 @@ config ANDROID_LOW_MEMORY_KILLER source "drivers/staging/android/ion/Kconfig" -source "drivers/staging/android/fiq_debugger/Kconfig" - endif # if ANDROID endmenu diff --git a/drivers/staging/android/Makefile b/drivers/staging/android/Makefile index 191ac4bdefa3..766a635e0bbf 100644 --- a/drivers/staging/android/Makefile +++ b/drivers/staging/android/Makefile @@ -1,7 +1,6 @@ ccflags-y += -I$(src) # needed for trace events obj-y += ion/ -obj-$(CONFIG_FIQ_DEBUGGER) += fiq_debugger/ obj-$(CONFIG_ASHMEM) += ashmem.o obj-$(CONFIG_ANDROID_VSOC) += vsoc.o diff --git a/drivers/staging/android/fiq_debugger/Kconfig b/drivers/staging/android/fiq_debugger/Kconfig deleted file mode 100644 index 60fc224d4efc..000000000000 --- a/drivers/staging/android/fiq_debugger/Kconfig +++ /dev/null @@ -1,58 +0,0 @@ -config FIQ_DEBUGGER - bool "FIQ Mode Serial Debugger" - default n - depends on ARM || ARM64 - help - The FIQ serial debugger can accept commands even when the - kernel is unresponsive due to being stuck with interrupts - disabled. - -config FIQ_DEBUGGER_NO_SLEEP - bool "Keep serial debugger active" - depends on FIQ_DEBUGGER - default n - help - Enables the serial debugger at boot. Passing - fiq_debugger.no_sleep on the kernel commandline will - override this config option. - -config FIQ_DEBUGGER_WAKEUP_IRQ_ALWAYS_ON - bool "Don't disable wakeup IRQ when debugger is active" - depends on FIQ_DEBUGGER - default n - help - Don't disable the wakeup irq when enabling the uart clock. This will - cause extra interrupts, but it makes the serial debugger usable with - on some MSM radio builds that ignore the uart clock request in power - collapse. - -config FIQ_DEBUGGER_CONSOLE - bool "Console on FIQ Serial Debugger port" - depends on FIQ_DEBUGGER - default n - help - Enables a console so that printk messages are displayed on - the debugger serial port as the occur. - -config FIQ_DEBUGGER_CONSOLE_DEFAULT_ENABLE - bool "Put the FIQ debugger into console mode by default" - depends on FIQ_DEBUGGER_CONSOLE - default n - help - If enabled, this puts the fiq debugger into console mode by default. - Otherwise, the fiq debugger will start out in debug mode. - -config FIQ_DEBUGGER_UART_OVERLAY - bool "Install uart DT overlay" - depends on FIQ_DEBUGGER - select OF_OVERLAY - default n - help - If enabled, fiq debugger is calling fiq_debugger_uart_overlay() - that will apply overlay uart_overlay@0 to disable proper uart. - -config FIQ_WATCHDOG - bool - select FIQ_DEBUGGER - select PSTORE_RAM - default n diff --git a/drivers/staging/android/fiq_debugger/Makefile b/drivers/staging/android/fiq_debugger/Makefile deleted file mode 100644 index a7ca4871cad3..000000000000 --- a/drivers/staging/android/fiq_debugger/Makefile +++ /dev/null @@ -1,4 +0,0 @@ -obj-y += fiq_debugger.o -obj-$(CONFIG_ARM) += fiq_debugger_arm.o -obj-$(CONFIG_ARM64) += fiq_debugger_arm64.o -obj-$(CONFIG_FIQ_WATCHDOG) += fiq_watchdog.o diff --git a/drivers/staging/android/fiq_debugger/fiq_debugger.c b/drivers/staging/android/fiq_debugger/fiq_debugger.c deleted file mode 100644 index f6a806219f84..000000000000 --- a/drivers/staging/android/fiq_debugger/fiq_debugger.c +++ /dev/null @@ -1,1246 +0,0 @@ -/* - * drivers/staging/android/fiq_debugger.c - * - * Serial Debugger Interface accessed through an FIQ interrupt. - * - * Copyright (C) 2008 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef CONFIG_FIQ_GLUE -#include -#endif - -#ifdef CONFIG_FIQ_DEBUGGER_UART_OVERLAY -#include -#endif - -#include - -#include "fiq_debugger.h" -#include "fiq_debugger_priv.h" -#include "fiq_debugger_ringbuf.h" - -#define DEBUG_MAX 64 -#define MAX_UNHANDLED_FIQ_COUNT 1000000 - -#define MAX_FIQ_DEBUGGER_PORTS 4 - -struct fiq_debugger_state { -#ifdef CONFIG_FIQ_GLUE - struct fiq_glue_handler handler; -#endif - struct fiq_debugger_output output; - - int fiq; - int uart_irq; - int signal_irq; - int wakeup_irq; - bool wakeup_irq_no_set_wake; - struct clk *clk; - struct fiq_debugger_pdata *pdata; - struct platform_device *pdev; - - char debug_cmd[DEBUG_MAX]; - int debug_busy; - int debug_abort; - - char debug_buf[DEBUG_MAX]; - int debug_count; - - bool no_sleep; - bool debug_enable; - bool ignore_next_wakeup_irq; - struct timer_list sleep_timer; - spinlock_t sleep_timer_lock; - bool uart_enabled; - struct wakeup_source debugger_wake_src; - bool console_enable; - int current_cpu; - atomic_t unhandled_fiq_count; - bool in_fiq; - - struct work_struct work; - spinlock_t work_lock; - char work_cmd[DEBUG_MAX]; - -#ifdef CONFIG_FIQ_DEBUGGER_CONSOLE - spinlock_t console_lock; - struct console console; - struct tty_port tty_port; - struct fiq_debugger_ringbuf *tty_rbuf; - bool syslog_dumping; -#endif - - unsigned int last_irqs[NR_IRQS]; - unsigned int last_local_timer_irqs[NR_CPUS]; -}; - -#ifdef CONFIG_FIQ_DEBUGGER_CONSOLE -struct tty_driver *fiq_tty_driver; -#endif - -#ifdef CONFIG_FIQ_DEBUGGER_NO_SLEEP -static bool initial_no_sleep = true; -#else -static bool initial_no_sleep; -#endif - -#ifdef CONFIG_FIQ_DEBUGGER_CONSOLE_DEFAULT_ENABLE -static bool initial_debug_enable = true; -static bool initial_console_enable = true; -#else -static bool initial_debug_enable; -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 -void fiq_debugger_enable_wakeup_irq(struct fiq_debugger_state *state) {} -static inline -void fiq_debugger_disable_wakeup_irq(struct fiq_debugger_state *state) {} -#else -static inline -void fiq_debugger_enable_wakeup_irq(struct fiq_debugger_state *state) -{ - if (state->wakeup_irq < 0) - return; - enable_irq(state->wakeup_irq); - if (!state->wakeup_irq_no_set_wake) - enable_irq_wake(state->wakeup_irq); -} -static inline -void fiq_debugger_disable_wakeup_irq(struct fiq_debugger_state *state) -{ - if (state->wakeup_irq < 0) - return; - disable_irq_nosync(state->wakeup_irq); - if (!state->wakeup_irq_no_set_wake) - disable_irq_wake(state->wakeup_irq); -} -#endif - -static inline bool fiq_debugger_have_fiq(struct fiq_debugger_state *state) -{ - return (state->fiq >= 0); -} - -#ifdef CONFIG_FIQ_GLUE -static void fiq_debugger_force_irq(struct fiq_debugger_state *state) -{ - unsigned int irq = state->signal_irq; - - if (WARN_ON(!fiq_debugger_have_fiq(state))) - 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)); - } -} -#endif - -static void fiq_debugger_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 fiq_debugger_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 fiq_debugger_uart_flush(struct fiq_debugger_state *state) -{ - if (state->pdata->uart_flush) - state->pdata->uart_flush(state->pdev); -} - -static void fiq_debugger_putc(struct fiq_debugger_state *state, char c) -{ - state->pdata->uart_putc(state->pdev, c); -} - -static void fiq_debugger_puts(struct fiq_debugger_state *state, char *s) -{ - unsigned c; - while ((c = *s++)) { - if (c == '\n') - fiq_debugger_putc(state, '\r'); - fiq_debugger_putc(state, c); - } -} - -static void fiq_debugger_prompt(struct fiq_debugger_state *state) -{ - fiq_debugger_puts(state, "debug> "); -} - -static void fiq_debugger_dump_kernel_log(struct fiq_debugger_state *state) -{ - char buf[512]; - size_t len; - struct kmsg_dumper dumper = { .active = true }; - - - kmsg_dump_rewind_nolock(&dumper); - while (kmsg_dump_get_line_nolock(&dumper, true, buf, - sizeof(buf) - 1, &len)) { - buf[len] = 0; - fiq_debugger_puts(state, buf); - } -} - -static void fiq_debugger_printf(struct fiq_debugger_output *output, - const char *fmt, ...) -{ - struct fiq_debugger_state *state; - char buf[256]; - va_list ap; - - state = container_of(output, struct fiq_debugger_state, output); - va_start(ap, fmt); - vsnprintf(buf, sizeof(buf), fmt, ap); - va_end(ap); - - fiq_debugger_puts(state, buf); -} - -/* Safe outside fiq context */ -static int fiq_debugger_printf_nfiq(void *cookie, const char *fmt, ...) -{ - struct fiq_debugger_state *state = cookie; - char buf[256]; - va_list ap; - unsigned long irq_flags; - - va_start(ap, fmt); - vsnprintf(buf, 128, fmt, ap); - va_end(ap); - - local_irq_save(irq_flags); - fiq_debugger_puts(state, buf); - fiq_debugger_uart_flush(state); - local_irq_restore(irq_flags); - return state->debug_abort; -} - -static void fiq_debugger_dump_irqs(struct fiq_debugger_state *state) -{ - int n; - struct irq_desc *desc; - - fiq_debugger_printf(&state->output, - "irqnr total since-last status name\n"); - for_each_irq_desc(n, desc) { - struct irqaction *act = desc->action; - if (!act && !kstat_irqs(n)) - continue; - fiq_debugger_printf(&state->output, "%5d: %10u %11u %8x %s\n", n, - kstat_irqs(n), - kstat_irqs(n) - state->last_irqs[n], - desc->status_use_accessors, - (act && act->name) ? act->name : "???"); - state->last_irqs[n] = kstat_irqs(n); - } -} - -static void fiq_debugger_do_ps(struct fiq_debugger_state *state) -{ - struct task_struct *g; - struct task_struct *p; - unsigned task_state; - static const char stat_nam[] = "RSDTtZX"; - - fiq_debugger_printf(&state->output, "pid ppid prio task pc\n"); - read_lock(&tasklist_lock); - do_each_thread(g, p) { - task_state = p->state ? __ffs(p->state) + 1 : 0; - fiq_debugger_printf(&state->output, - "%5d %5d %4d ", p->pid, p->parent->pid, p->prio); - fiq_debugger_printf(&state->output, "%-13.13s %c", p->comm, - task_state >= sizeof(stat_nam) ? '?' : stat_nam[task_state]); - if (task_state == TASK_RUNNING) - fiq_debugger_printf(&state->output, " running\n"); - else - fiq_debugger_printf(&state->output, " %08lx\n", - thread_saved_pc(p)); - } while_each_thread(g, p); - read_unlock(&tasklist_lock); -} - -#ifdef CONFIG_FIQ_DEBUGGER_CONSOLE -static void fiq_debugger_begin_syslog_dump(struct fiq_debugger_state *state) -{ - state->syslog_dumping = true; -} - -static void fiq_debugger_end_syslog_dump(struct fiq_debugger_state *state) -{ - state->syslog_dumping = false; -} -#else -extern int do_syslog(int type, char __user *bug, int count); -static void fiq_debugger_begin_syslog_dump(struct fiq_debugger_state *state) -{ - do_syslog(5 /* clear */, NULL, 0); -} - -static void fiq_debugger_end_syslog_dump(struct fiq_debugger_state *state) -{ - fiq_debugger_dump_kernel_log(state); -} -#endif - -static void fiq_debugger_do_sysrq(struct fiq_debugger_state *state, char rq) -{ - if ((rq == 'g' || rq == 'G') && !fiq_kgdb_enable) { - fiq_debugger_printf(&state->output, "sysrq-g blocked\n"); - return; - } - fiq_debugger_begin_syslog_dump(state); - handle_sysrq(rq); - fiq_debugger_end_syslog_dump(state); -} - -#ifdef CONFIG_KGDB -static void fiq_debugger_do_kgdb(struct fiq_debugger_state *state) -{ - if (!fiq_kgdb_enable) { - fiq_debugger_printf(&state->output, "kgdb through fiq debugger not enabled\n"); - return; - } - - fiq_debugger_printf(&state->output, "enabling console and triggering kgdb\n"); - state->console_enable = true; - handle_sysrq('g'); -} -#endif - -static void fiq_debugger_schedule_work(struct fiq_debugger_state *state, - char *cmd) -{ - unsigned long flags; - - spin_lock_irqsave(&state->work_lock, flags); - if (state->work_cmd[0] != '\0') { - fiq_debugger_printf(&state->output, "work command processor busy\n"); - spin_unlock_irqrestore(&state->work_lock, flags); - return; - } - - strlcpy(state->work_cmd, cmd, sizeof(state->work_cmd)); - spin_unlock_irqrestore(&state->work_lock, flags); - - schedule_work(&state->work); -} - -static void fiq_debugger_work(struct work_struct *work) -{ - struct fiq_debugger_state *state; - char work_cmd[DEBUG_MAX]; - char *cmd; - unsigned long flags; - - state = container_of(work, struct fiq_debugger_state, work); - - spin_lock_irqsave(&state->work_lock, flags); - - strlcpy(work_cmd, state->work_cmd, sizeof(work_cmd)); - state->work_cmd[0] = '\0'; - - spin_unlock_irqrestore(&state->work_lock, flags); - - cmd = work_cmd; - if (!strncmp(cmd, "reboot", 6)) { - cmd += 6; - while (*cmd == ' ') - cmd++; - if (*cmd != '\0') - kernel_restart(cmd); - else - kernel_restart(NULL); - } else { - fiq_debugger_printf(&state->output, "unknown work command '%s'\n", - work_cmd); - } -} - -/* This function CANNOT be called in FIQ context */ -static void fiq_debugger_irq_exec(struct fiq_debugger_state *state, char *cmd) -{ - if (!strcmp(cmd, "ps")) - fiq_debugger_do_ps(state); - if (!strcmp(cmd, "sysrq")) - fiq_debugger_do_sysrq(state, 'h'); - if (!strncmp(cmd, "sysrq ", 6)) - fiq_debugger_do_sysrq(state, cmd[6]); -#ifdef CONFIG_KGDB - if (!strcmp(cmd, "kgdb")) - fiq_debugger_do_kgdb(state); -#endif - if (!strncmp(cmd, "reboot", 6)) - fiq_debugger_schedule_work(state, cmd); -} - -static void fiq_debugger_help(struct fiq_debugger_state *state) -{ - fiq_debugger_printf(&state->output, - "FIQ Debugger commands:\n" - " pc PC status\n" - " regs Register dump\n" - " allregs Extended Register dump\n" - " bt Stack trace\n" - " reboot [] Reboot with command \n" - " reset [] Hard reset with command \n" - " irqs Interupt status\n" - " kmsg Kernel log\n" - " version Kernel version\n"); - fiq_debugger_printf(&state->output, - " sleep Allow sleep while in FIQ\n" - " nosleep Disable sleep while in FIQ\n" - " console Switch terminal to console\n" - " cpu Current CPU\n" - " cpu Switch to CPU\n"); - fiq_debugger_printf(&state->output, - " ps Process list\n" - " sysrq sysrq options\n" - " sysrq Execute sysrq with \n"); -#ifdef CONFIG_KGDB - fiq_debugger_printf(&state->output, - " kgdb Enter kernel debugger\n"); -#endif -} - -static void fiq_debugger_take_affinity(void *info) -{ - struct fiq_debugger_state *state = info; - struct cpumask cpumask; - - cpumask_clear(&cpumask); - cpumask_set_cpu(get_cpu(), &cpumask); - - irq_set_affinity(state->uart_irq, &cpumask); -} - -static void fiq_debugger_switch_cpu(struct fiq_debugger_state *state, int cpu) -{ - if (!fiq_debugger_have_fiq(state)) - smp_call_function_single(cpu, fiq_debugger_take_affinity, state, - false); - state->current_cpu = cpu; -} - -static bool fiq_debugger_fiq_exec(struct fiq_debugger_state *state, - const char *cmd, const struct pt_regs *regs, - void *svc_sp) -{ - bool signal_helper = false; - - if (!strcmp(cmd, "help") || !strcmp(cmd, "?")) { - fiq_debugger_help(state); - } else if (!strcmp(cmd, "pc")) { - fiq_debugger_dump_pc(&state->output, regs); - } else if (!strcmp(cmd, "regs")) { - fiq_debugger_dump_regs(&state->output, regs); - } 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); - } else if (!strncmp(cmd, "reset", 5)) { - cmd += 5; - while (*cmd == ' ') - cmd++; - if (*cmd) { - char tmp_cmd[32]; - strlcpy(tmp_cmd, cmd, sizeof(tmp_cmd)); - machine_restart(tmp_cmd); - } else { - machine_restart(NULL); - } - } else if (!strcmp(cmd, "irqs")) { - fiq_debugger_dump_irqs(state); - } else if (!strcmp(cmd, "kmsg")) { - fiq_debugger_dump_kernel_log(state); - } else if (!strcmp(cmd, "version")) { - fiq_debugger_printf(&state->output, "%s\n", linux_banner); - } else if (!strcmp(cmd, "sleep")) { - state->no_sleep = false; - fiq_debugger_printf(&state->output, "enabling sleep\n"); - } else if (!strcmp(cmd, "nosleep")) { - state->no_sleep = true; - fiq_debugger_printf(&state->output, "disabling sleep\n"); - } else if (!strcmp(cmd, "console")) { - fiq_debugger_printf(&state->output, "console mode\n"); - fiq_debugger_uart_flush(state); - state->console_enable = true; - } 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 (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) { - fiq_debugger_printf(&state->output, - "command processor busy. trying to abort.\n"); - state->debug_abort = -1; - } else { - strcpy(state->debug_cmd, cmd); - state->debug_busy = 1; - } - - return true; - } - if (!state->console_enable) - fiq_debugger_prompt(state); - - return signal_helper; -} - -static void fiq_debugger_sleep_timer_expired(unsigned long data) -{ - struct fiq_debugger_state *state = (struct fiq_debugger_state *)data; - unsigned long flags; - - spin_lock_irqsave(&state->sleep_timer_lock, flags); - if (state->uart_enabled && !state->no_sleep) { - if (state->debug_enable && !state->console_enable) { - state->debug_enable = false; - fiq_debugger_printf_nfiq(state, - "suspending fiq debugger\n"); - } - state->ignore_next_wakeup_irq = true; - fiq_debugger_uart_disable(state); - state->uart_enabled = false; - fiq_debugger_enable_wakeup_irq(state); - } - __pm_relax(&state->debugger_wake_src); - spin_unlock_irqrestore(&state->sleep_timer_lock, flags); -} - -static void fiq_debugger_handle_wakeup(struct fiq_debugger_state *state) -{ - unsigned long flags; - - spin_lock_irqsave(&state->sleep_timer_lock, flags); - if (state->wakeup_irq >= 0 && state->ignore_next_wakeup_irq) { - state->ignore_next_wakeup_irq = false; - } else if (!state->uart_enabled) { - __pm_stay_awake(&state->debugger_wake_src); - fiq_debugger_uart_enable(state); - state->uart_enabled = true; - fiq_debugger_disable_wakeup_irq(state); - mod_timer(&state->sleep_timer, jiffies + HZ / 2); - } - spin_unlock_irqrestore(&state->sleep_timer_lock, flags); -} - -static irqreturn_t fiq_debugger_wakeup_irq_handler(int irq, void *dev) -{ - struct fiq_debugger_state *state = dev; - - if (!state->no_sleep) - fiq_debugger_puts(state, "WAKEUP\n"); - fiq_debugger_handle_wakeup(state); - - return IRQ_HANDLED; -} - -static -void fiq_debugger_handle_console_irq_context(struct fiq_debugger_state *state) -{ -#if defined(CONFIG_FIQ_DEBUGGER_CONSOLE) - if (state->tty_port.ops) { - int i; - int count = fiq_debugger_ringbuf_level(state->tty_rbuf); - for (i = 0; i < count; i++) { - int c = fiq_debugger_ringbuf_peek(state->tty_rbuf, 0); - tty_insert_flip_char(&state->tty_port, c, TTY_NORMAL); - if (!fiq_debugger_ringbuf_consume(state->tty_rbuf, 1)) - pr_warn("fiq tty failed to consume byte\n"); - } - tty_flip_buffer_push(&state->tty_port); - } -#endif -} - -static void fiq_debugger_handle_irq_context(struct fiq_debugger_state *state) -{ - if (!state->no_sleep) { - unsigned long flags; - - spin_lock_irqsave(&state->sleep_timer_lock, flags); - __pm_stay_awake(&state->debugger_wake_src); - mod_timer(&state->sleep_timer, jiffies + HZ * 5); - spin_unlock_irqrestore(&state->sleep_timer_lock, flags); - } - fiq_debugger_handle_console_irq_context(state); - if (state->debug_busy) { - fiq_debugger_irq_exec(state, state->debug_cmd); - if (!state->console_enable) - fiq_debugger_prompt(state); - state->debug_busy = 0; - } -} - -static int fiq_debugger_getc(struct fiq_debugger_state *state) -{ - return state->pdata->uart_getc(state->pdev); -} - -static bool fiq_debugger_handle_uart_interrupt(struct fiq_debugger_state *state, - int this_cpu, const struct pt_regs *regs, void *svc_sp) -{ - int c; - static int last_c; - int count = 0; - bool signal_helper = false; - - if (this_cpu != state->current_cpu) { - if (state->in_fiq) - return false; - - if (atomic_inc_return(&state->unhandled_fiq_count) != - MAX_UNHANDLED_FIQ_COUNT) - return false; - - fiq_debugger_printf(&state->output, - "fiq_debugger: cpu %d not responding, " - "reverting to cpu %d\n", state->current_cpu, - this_cpu); - - atomic_set(&state->unhandled_fiq_count, 0); - fiq_debugger_switch_cpu(state, this_cpu); - return false; - } - - state->in_fiq = true; - - while ((c = fiq_debugger_getc(state)) != FIQ_DEBUGGER_NO_CHAR) { - count++; - if (!state->debug_enable) { - if ((c == 13) || (c == 10)) { - state->debug_enable = true; - state->debug_count = 0; - fiq_debugger_prompt(state); - } - } else if (c == FIQ_DEBUGGER_BREAK) { - state->console_enable = false; - fiq_debugger_puts(state, "fiq debugger mode\n"); - state->debug_count = 0; - fiq_debugger_prompt(state); -#ifdef CONFIG_FIQ_DEBUGGER_CONSOLE - } else if (state->console_enable && state->tty_rbuf) { - fiq_debugger_ringbuf_push(state->tty_rbuf, c); - signal_helper = true; -#endif - } else if ((c >= ' ') && (c < 127)) { - if (state->debug_count < (DEBUG_MAX - 1)) { - state->debug_buf[state->debug_count++] = c; - fiq_debugger_putc(state, c); - } - } else if ((c == 8) || (c == 127)) { - if (state->debug_count > 0) { - state->debug_count--; - fiq_debugger_putc(state, 8); - fiq_debugger_putc(state, ' '); - fiq_debugger_putc(state, 8); - } - } else if ((c == 13) || (c == 10)) { - if (c == '\r' || (c == '\n' && last_c != '\r')) { - fiq_debugger_putc(state, '\r'); - fiq_debugger_putc(state, '\n'); - } - if (state->debug_count) { - state->debug_buf[state->debug_count] = 0; - state->debug_count = 0; - signal_helper |= - fiq_debugger_fiq_exec(state, - state->debug_buf, - regs, svc_sp); - } else { - fiq_debugger_prompt(state); - } - } - last_c = c; - } - if (!state->console_enable) - fiq_debugger_uart_flush(state); - if (state->pdata->fiq_ack) - state->pdata->fiq_ack(state->pdev, state->fiq); - - /* poke sleep timer if necessary */ - if (state->debug_enable && !state->no_sleep) - signal_helper = true; - - atomic_set(&state->unhandled_fiq_count, 0); - state->in_fiq = false; - - return signal_helper; -} - -#ifdef CONFIG_FIQ_GLUE -static void fiq_debugger_fiq(struct fiq_glue_handler *h, - 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; - - need_irq = fiq_debugger_handle_uart_interrupt(state, this_cpu, regs, - svc_sp); - 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 - * in this context. - */ -static irqreturn_t fiq_debugger_uart_irq(int irq, void *dev) -{ - struct fiq_debugger_state *state = dev; - bool not_done; - - fiq_debugger_handle_wakeup(state); - - /* handle the debugger irq in regular context */ - not_done = fiq_debugger_handle_uart_interrupt(state, smp_processor_id(), - get_irq_regs(), - current_thread_info()); - if (not_done) - fiq_debugger_handle_irq_context(state); - - return IRQ_HANDLED; -} - -/* - * 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 - * job in irq context. - */ -static irqreturn_t fiq_debugger_signal_irq(int irq, void *dev) -{ - struct fiq_debugger_state *state = dev; - - if (state->pdata->force_irq_ack) - state->pdata->force_irq_ack(state->pdev, state->signal_irq); - - fiq_debugger_handle_irq_context(state); - - return IRQ_HANDLED; -} - -#ifdef CONFIG_FIQ_GLUE -static void fiq_debugger_resume(struct fiq_glue_handler *h) -{ - struct fiq_debugger_state *state = - container_of(h, struct fiq_debugger_state, handler); - if (state->pdata->uart_resume) - state->pdata->uart_resume(state->pdev); -} -#endif - -#if defined(CONFIG_FIQ_DEBUGGER_CONSOLE) -struct tty_driver *fiq_debugger_console_device(struct console *co, int *index) -{ - *index = co->index; - return fiq_tty_driver; -} - -static void fiq_debugger_console_write(struct console *co, - const char *s, unsigned int count) -{ - struct fiq_debugger_state *state; - unsigned long flags; - - state = container_of(co, struct fiq_debugger_state, console); - - if (!state->console_enable && !state->syslog_dumping) - return; - - fiq_debugger_uart_enable(state); - spin_lock_irqsave(&state->console_lock, flags); - while (count--) { - if (*s == '\n') - fiq_debugger_putc(state, '\r'); - fiq_debugger_putc(state, *s++); - } - fiq_debugger_uart_flush(state); - spin_unlock_irqrestore(&state->console_lock, flags); - fiq_debugger_uart_disable(state); -} - -static struct console fiq_debugger_console = { - .name = "ttyFIQ", - .device = fiq_debugger_console_device, - .write = fiq_debugger_console_write, - .flags = CON_PRINTBUFFER | CON_ANYTIME | CON_ENABLED, -}; - -int fiq_tty_open(struct tty_struct *tty, struct file *filp) -{ - int line = tty->index; - struct fiq_debugger_state **states = tty->driver->driver_state; - struct fiq_debugger_state *state = states[line]; - - return tty_port_open(&state->tty_port, tty, filp); -} - -void fiq_tty_close(struct tty_struct *tty, struct file *filp) -{ - tty_port_close(tty->port, tty, filp); -} - -int fiq_tty_write(struct tty_struct *tty, const unsigned char *buf, int count) -{ - int i; - int line = tty->index; - struct fiq_debugger_state **states = tty->driver->driver_state; - struct fiq_debugger_state *state = states[line]; - - if (!state->console_enable) - return count; - - fiq_debugger_uart_enable(state); - spin_lock_irq(&state->console_lock); - for (i = 0; i < count; i++) - fiq_debugger_putc(state, *buf++); - spin_unlock_irq(&state->console_lock); - fiq_debugger_uart_disable(state); - - return count; -} - -int fiq_tty_write_room(struct tty_struct *tty) -{ - return 16; -} - -#ifdef CONFIG_CONSOLE_POLL -static int fiq_tty_poll_init(struct tty_driver *driver, int line, char *options) -{ - return 0; -} - -static int fiq_tty_poll_get_char(struct tty_driver *driver, int line) -{ - struct fiq_debugger_state **states = driver->driver_state; - struct fiq_debugger_state *state = states[line]; - int c = NO_POLL_CHAR; - - fiq_debugger_uart_enable(state); - if (fiq_debugger_have_fiq(state)) { - int count = fiq_debugger_ringbuf_level(state->tty_rbuf); - if (count > 0) { - c = fiq_debugger_ringbuf_peek(state->tty_rbuf, 0); - fiq_debugger_ringbuf_consume(state->tty_rbuf, 1); - } - } else { - c = fiq_debugger_getc(state); - if (c == FIQ_DEBUGGER_NO_CHAR) - c = NO_POLL_CHAR; - } - fiq_debugger_uart_disable(state); - - return c; -} - -static void fiq_tty_poll_put_char(struct tty_driver *driver, int line, char ch) -{ - struct fiq_debugger_state **states = driver->driver_state; - struct fiq_debugger_state *state = states[line]; - fiq_debugger_uart_enable(state); - fiq_debugger_putc(state, ch); - fiq_debugger_uart_disable(state); -} -#endif - -static const struct tty_port_operations fiq_tty_port_ops; - -static const struct tty_operations fiq_tty_driver_ops = { - .write = fiq_tty_write, - .write_room = fiq_tty_write_room, - .open = fiq_tty_open, - .close = fiq_tty_close, -#ifdef CONFIG_CONSOLE_POLL - .poll_init = fiq_tty_poll_init, - .poll_get_char = fiq_tty_poll_get_char, - .poll_put_char = fiq_tty_poll_put_char, -#endif -}; - -static int fiq_debugger_tty_init(void) -{ - int ret; - struct fiq_debugger_state **states = NULL; - - states = kzalloc(sizeof(*states) * MAX_FIQ_DEBUGGER_PORTS, GFP_KERNEL); - if (!states) { - pr_err("Failed to allocate fiq debugger state structres\n"); - return -ENOMEM; - } - - fiq_tty_driver = alloc_tty_driver(MAX_FIQ_DEBUGGER_PORTS); - if (!fiq_tty_driver) { - pr_err("Failed to allocate fiq debugger tty\n"); - ret = -ENOMEM; - goto err_free_state; - } - - fiq_tty_driver->owner = THIS_MODULE; - fiq_tty_driver->driver_name = "fiq-debugger"; - fiq_tty_driver->name = "ttyFIQ"; - fiq_tty_driver->type = TTY_DRIVER_TYPE_SERIAL; - fiq_tty_driver->subtype = SERIAL_TYPE_NORMAL; - fiq_tty_driver->init_termios = tty_std_termios; - fiq_tty_driver->flags = TTY_DRIVER_REAL_RAW | - TTY_DRIVER_DYNAMIC_DEV; - fiq_tty_driver->driver_state = states; - - fiq_tty_driver->init_termios.c_cflag = - B115200 | CS8 | CREAD | HUPCL | CLOCAL; - fiq_tty_driver->init_termios.c_ispeed = 115200; - fiq_tty_driver->init_termios.c_ospeed = 115200; - - tty_set_operations(fiq_tty_driver, &fiq_tty_driver_ops); - - ret = tty_register_driver(fiq_tty_driver); - if (ret) { - pr_err("Failed to register fiq tty: %d\n", ret); - goto err_free_tty; - } - - pr_info("Registered FIQ tty driver\n"); - return 0; - -err_free_tty: - put_tty_driver(fiq_tty_driver); - fiq_tty_driver = NULL; -err_free_state: - kfree(states); - return ret; -} - -static int fiq_debugger_tty_init_one(struct fiq_debugger_state *state) -{ - int ret; - struct device *tty_dev; - struct fiq_debugger_state **states = fiq_tty_driver->driver_state; - - states[state->pdev->id] = state; - - state->tty_rbuf = fiq_debugger_ringbuf_alloc(1024); - if (!state->tty_rbuf) { - pr_err("Failed to allocate fiq debugger ringbuf\n"); - ret = -ENOMEM; - goto err; - } - - tty_port_init(&state->tty_port); - state->tty_port.ops = &fiq_tty_port_ops; - - tty_dev = tty_port_register_device(&state->tty_port, fiq_tty_driver, - state->pdev->id, &state->pdev->dev); - if (IS_ERR(tty_dev)) { - pr_err("Failed to register fiq debugger tty device\n"); - ret = PTR_ERR(tty_dev); - goto err; - } - - device_set_wakeup_capable(tty_dev, 1); - - pr_info("Registered fiq debugger ttyFIQ%d\n", state->pdev->id); - - return 0; - -err: - fiq_debugger_ringbuf_free(state->tty_rbuf); - state->tty_rbuf = NULL; - return ret; -} -#endif - -static int fiq_debugger_dev_suspend(struct device *dev) -{ - struct platform_device *pdev = to_platform_device(dev); - struct fiq_debugger_state *state = platform_get_drvdata(pdev); - - if (state->pdata->uart_dev_suspend) - return state->pdata->uart_dev_suspend(pdev); - return 0; -} - -static int fiq_debugger_dev_resume(struct device *dev) -{ - struct platform_device *pdev = to_platform_device(dev); - struct fiq_debugger_state *state = platform_get_drvdata(pdev); - - if (state->pdata->uart_dev_resume) - return state->pdata->uart_dev_resume(pdev); - return 0; -} - -static int fiq_debugger_probe(struct platform_device *pdev) -{ - int ret; - struct fiq_debugger_pdata *pdata = dev_get_platdata(&pdev->dev); - struct fiq_debugger_state *state; - int fiq; - int uart_irq; - - if (pdev->id >= MAX_FIQ_DEBUGGER_PORTS) - return -EINVAL; - - 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"); - - /* uart_irq mode and fiq mode are mutually exclusive, but one of them - * is required */ - if ((uart_irq < 0 && fiq < 0) || (uart_irq >= 0 && fiq >= 0)) - return -EINVAL; - if (fiq >= 0 && !pdata->fiq_enable) - return -EINVAL; - - state = kzalloc(sizeof(*state), GFP_KERNEL); - state->output.printf = fiq_debugger_printf; - setup_timer(&state->sleep_timer, fiq_debugger_sleep_timer_expired, - (unsigned long)state); - state->pdata = pdata; - state->pdev = pdev; - state->no_sleep = initial_no_sleep; - state->debug_enable = initial_debug_enable; - state->console_enable = initial_console_enable; - - state->fiq = fiq; - state->uart_irq = uart_irq; - state->signal_irq = platform_get_irq_byname(pdev, "signal"); - state->wakeup_irq = platform_get_irq_byname(pdev, "wakeup"); - - INIT_WORK(&state->work, fiq_debugger_work); - spin_lock_init(&state->work_lock); - - platform_set_drvdata(pdev, state); - - spin_lock_init(&state->sleep_timer_lock); - - if (state->wakeup_irq < 0 && fiq_debugger_have_fiq(state)) - state->no_sleep = true; - state->ignore_next_wakeup_irq = !state->no_sleep; - - wakeup_source_init(&state->debugger_wake_src, "serial-debug"); - - state->clk = clk_get(&pdev->dev, NULL); - 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); - - if (pdata->uart_init) { - ret = pdata->uart_init(pdev); - if (ret) - goto err_uart_init; - } - - fiq_debugger_printf_nfiq(state, - "\n", - state->no_sleep ? "" : "twice "); - -#ifdef CONFIG_FIQ_GLUE - if (fiq_debugger_have_fiq(state)) { - state->handler.fiq = fiq_debugger_fiq; - state->handler.resume = fiq_debugger_resume; - ret = fiq_glue_register_handler(&state->handler); - if (ret) { - pr_err("%s: could not install fiq handler\n", __func__); - goto err_register_irq; - } - - pdata->fiq_enable(pdev, state->fiq, 1); - } else -#endif - { - ret = request_irq(state->uart_irq, fiq_debugger_uart_irq, - IRQF_NO_SUSPEND, "debug", state); - if (ret) { - pr_err("%s: could not install irq handler\n", __func__); - goto err_register_irq; - } - - /* for irq-only mode, we want this irq to wake us up, if it - * can. - */ - enable_irq_wake(state->uart_irq); - } - - if (state->clk) - clk_disable(state->clk); - - if (state->signal_irq >= 0) { - ret = request_irq(state->signal_irq, fiq_debugger_signal_irq, - IRQF_TRIGGER_RISING, "debug-signal", state); - if (ret) - pr_err("serial_debugger: could not install signal_irq"); - } - - if (state->wakeup_irq >= 0) { - ret = request_irq(state->wakeup_irq, - fiq_debugger_wakeup_irq_handler, - IRQF_TRIGGER_FALLING, - "debug-wakeup", state); - if (ret) { - pr_err("serial_debugger: " - "could not install wakeup irq\n"); - state->wakeup_irq = -1; - } else { - ret = enable_irq_wake(state->wakeup_irq); - if (ret) { - pr_err("serial_debugger: " - "could not enable wakeup\n"); - state->wakeup_irq_no_set_wake = true; - } - } - } - if (state->no_sleep) - fiq_debugger_handle_wakeup(state); - -#if defined(CONFIG_FIQ_DEBUGGER_CONSOLE) - spin_lock_init(&state->console_lock); - state->console = fiq_debugger_console; - state->console.index = pdev->id; - if (!console_set_on_cmdline) - add_preferred_console(state->console.name, - state->console.index, NULL); - register_console(&state->console); - fiq_debugger_tty_init_one(state); -#endif - return 0; - -err_register_irq: - if (pdata->uart_free) - pdata->uart_free(pdev); -err_uart_init: - if (state->clk) - clk_disable(state->clk); - if (state->clk) - clk_put(state->clk); - wakeup_source_trash(&state->debugger_wake_src); - platform_set_drvdata(pdev, NULL); - kfree(state); - return ret; -} - -static const struct dev_pm_ops fiq_debugger_dev_pm_ops = { - .suspend = fiq_debugger_dev_suspend, - .resume = fiq_debugger_dev_resume, -}; - -static struct platform_driver fiq_debugger_driver = { - .probe = fiq_debugger_probe, - .driver = { - .name = "fiq_debugger", - .pm = &fiq_debugger_dev_pm_ops, - }, -}; - -#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); -} - -postcore_initcall(fiq_debugger_init); diff --git a/drivers/staging/android/fiq_debugger/fiq_debugger.h b/drivers/staging/android/fiq_debugger/fiq_debugger.h deleted file mode 100644 index c9ec4f8db086..000000000000 --- a/drivers/staging/android/fiq_debugger/fiq_debugger.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * drivers/staging/android/fiq_debugger/fiq_debugger.h - * - * Copyright (C) 2010 Google, Inc. - * Author: Colin Cross - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#ifndef _ARCH_ARM_MACH_TEGRA_FIQ_DEBUGGER_H_ -#define _ARCH_ARM_MACH_TEGRA_FIQ_DEBUGGER_H_ - -#include - -#define FIQ_DEBUGGER_NO_CHAR NO_POLL_CHAR -#define FIQ_DEBUGGER_BREAK 0x00ff0100 - -#define FIQ_DEBUGGER_FIQ_IRQ_NAME "fiq" -#define FIQ_DEBUGGER_SIGNAL_IRQ_NAME "signal" -#define FIQ_DEBUGGER_WAKEUP_IRQ_NAME "wakeup" - -/** - * struct fiq_debugger_pdata - fiq debugger platform data - * @uart_resume: used to restore uart state right before enabling - * the fiq. - * @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. - * @uart_dev_suspend: called during PM suspend, generally not needed - * for real fiq mode debugger. - * @uart_dev_resume: called during PM resume, generally not needed - * for real fiq mode debugger. - */ -struct fiq_debugger_pdata { - int (*uart_init)(struct platform_device *pdev); - void (*uart_free)(struct platform_device *pdev); - int (*uart_resume)(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); - - int (*uart_dev_suspend)(struct platform_device *pdev); - int (*uart_dev_resume)(struct platform_device *pdev); - - void (*fiq_enable)(struct platform_device *pdev, unsigned int fiq, - bool enable); - void (*fiq_ack)(struct platform_device *pdev, unsigned int fiq); - - void (*force_irq)(struct platform_device *pdev, unsigned int irq); - void (*force_irq_ack)(struct platform_device *pdev, unsigned int irq); -}; - -#endif diff --git a/drivers/staging/android/fiq_debugger/fiq_debugger_arm.c b/drivers/staging/android/fiq_debugger/fiq_debugger_arm.c deleted file mode 100644 index 8b3e0137be1a..000000000000 --- a/drivers/staging/android/fiq_debugger/fiq_debugger_arm.c +++ /dev/null @@ -1,240 +0,0 @@ -/* - * Copyright (C) 2014 Google, Inc. - * Author: Colin Cross - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include - -#include - -#include "fiq_debugger_priv.h" - -static char *mode_name(unsigned cpsr) -{ - switch (cpsr & MODE_MASK) { - case USR_MODE: return "USR"; - case FIQ_MODE: return "FIQ"; - case IRQ_MODE: return "IRQ"; - case SVC_MODE: return "SVC"; - case ABT_MODE: return "ABT"; - case UND_MODE: return "UND"; - case SYSTEM_MODE: return "SYS"; - default: return "???"; - } -} - -void fiq_debugger_dump_pc(struct fiq_debugger_output *output, - const struct pt_regs *regs) -{ - output->printf(output, " pc %08x cpsr %08x mode %s\n", - regs->ARM_pc, regs->ARM_cpsr, mode_name(regs->ARM_cpsr)); -} - -void fiq_debugger_dump_regs(struct fiq_debugger_output *output, - const struct pt_regs *regs) -{ - output->printf(output, - " r0 %08x r1 %08x r2 %08x r3 %08x\n", - regs->ARM_r0, regs->ARM_r1, regs->ARM_r2, regs->ARM_r3); - output->printf(output, - " r4 %08x r5 %08x r6 %08x r7 %08x\n", - regs->ARM_r4, regs->ARM_r5, regs->ARM_r6, regs->ARM_r7); - output->printf(output, - " r8 %08x r9 %08x r10 %08x r11 %08x mode %s\n", - regs->ARM_r8, regs->ARM_r9, regs->ARM_r10, regs->ARM_fp, - mode_name(regs->ARM_cpsr)); - output->printf(output, - " ip %08x sp %08x lr %08x pc %08x cpsr %08x\n", - regs->ARM_ip, regs->ARM_sp, regs->ARM_lr, regs->ARM_pc, - regs->ARM_cpsr); -} - -struct mode_regs { - unsigned long sp_svc; - unsigned long lr_svc; - unsigned long spsr_svc; - - unsigned long sp_abt; - unsigned long lr_abt; - unsigned long spsr_abt; - - unsigned long sp_und; - unsigned long lr_und; - unsigned long spsr_und; - - unsigned long sp_irq; - unsigned long lr_irq; - unsigned long spsr_irq; - - unsigned long r8_fiq; - unsigned long r9_fiq; - unsigned long r10_fiq; - unsigned long r11_fiq; - unsigned long r12_fiq; - unsigned long sp_fiq; - unsigned long lr_fiq; - unsigned long spsr_fiq; -}; - -static void __naked get_mode_regs(struct mode_regs *regs) -{ - asm volatile ( - "mrs r1, cpsr\n" - "msr cpsr_c, #0xd3 @(SVC_MODE | PSR_I_BIT | PSR_F_BIT)\n" - "stmia r0!, {r13 - r14}\n" - "mrs r2, spsr\n" - "msr cpsr_c, #0xd7 @(ABT_MODE | PSR_I_BIT | PSR_F_BIT)\n" - "stmia r0!, {r2, r13 - r14}\n" - "mrs r2, spsr\n" - "msr cpsr_c, #0xdb @(UND_MODE | PSR_I_BIT | PSR_F_BIT)\n" - "stmia r0!, {r2, r13 - r14}\n" - "mrs r2, spsr\n" - "msr cpsr_c, #0xd2 @(IRQ_MODE | PSR_I_BIT | PSR_F_BIT)\n" - "stmia r0!, {r2, r13 - r14}\n" - "mrs r2, spsr\n" - "msr cpsr_c, #0xd1 @(FIQ_MODE | PSR_I_BIT | PSR_F_BIT)\n" - "stmia r0!, {r2, r8 - r14}\n" - "mrs r2, spsr\n" - "stmia r0!, {r2}\n" - "msr cpsr_c, r1\n" - "bx lr\n"); -} - - -void fiq_debugger_dump_allregs(struct fiq_debugger_output *output, - const struct pt_regs *regs) -{ - struct mode_regs mode_regs; - unsigned long mode = regs->ARM_cpsr & MODE_MASK; - - fiq_debugger_dump_regs(output, regs); - get_mode_regs(&mode_regs); - - output->printf(output, - "%csvc: sp %08x lr %08x spsr %08x\n", - mode == SVC_MODE ? '*' : ' ', - mode_regs.sp_svc, mode_regs.lr_svc, mode_regs.spsr_svc); - output->printf(output, - "%cabt: sp %08x lr %08x spsr %08x\n", - mode == ABT_MODE ? '*' : ' ', - mode_regs.sp_abt, mode_regs.lr_abt, mode_regs.spsr_abt); - output->printf(output, - "%cund: sp %08x lr %08x spsr %08x\n", - mode == UND_MODE ? '*' : ' ', - mode_regs.sp_und, mode_regs.lr_und, mode_regs.spsr_und); - output->printf(output, - "%cirq: sp %08x lr %08x spsr %08x\n", - mode == IRQ_MODE ? '*' : ' ', - mode_regs.sp_irq, mode_regs.lr_irq, mode_regs.spsr_irq); - output->printf(output, - "%cfiq: r8 %08x r9 %08x r10 %08x r11 %08x r12 %08x\n", - mode == FIQ_MODE ? '*' : ' ', - mode_regs.r8_fiq, mode_regs.r9_fiq, mode_regs.r10_fiq, - mode_regs.r11_fiq, mode_regs.r12_fiq); - output->printf(output, - " fiq: sp %08x lr %08x spsr %08x\n", - mode_regs.sp_fiq, mode_regs.lr_fiq, mode_regs.spsr_fiq); -} - -struct stacktrace_state { - struct fiq_debugger_output *output; - unsigned int depth; -}; - -static int report_trace(struct stackframe *frame, void *d) -{ - struct stacktrace_state *sts = d; - - if (sts->depth) { - sts->output->printf(sts->output, - " pc: %p (%pF), lr %p (%pF), sp %p, fp %p\n", - frame->pc, frame->pc, frame->lr, frame->lr, - frame->sp, frame->fp); - sts->depth--; - return 0; - } - sts->output->printf(sts->output, " ...\n"); - - return sts->depth == 0; -} - -struct frame_tail { - struct frame_tail *fp; - unsigned long sp; - unsigned long lr; -} __attribute__((packed)); - -static struct frame_tail *user_backtrace(struct fiq_debugger_output *output, - struct frame_tail *tail) -{ - struct frame_tail buftail[2]; - - /* Also check accessibility of one struct frame_tail beyond */ - if (!access_ok(VERIFY_READ, tail, sizeof(buftail))) { - output->printf(output, " invalid frame pointer %p\n", - tail); - return NULL; - } - if (__copy_from_user_inatomic(buftail, tail, sizeof(buftail))) { - output->printf(output, - " failed to copy frame pointer %p\n", tail); - return NULL; - } - - output->printf(output, " %p\n", buftail[0].lr); - - /* frame pointers should strictly progress back up the stack - * (towards higher addresses) */ - if (tail >= buftail[0].fp) - return NULL; - - return buftail[0].fp-1; -} - -void fiq_debugger_dump_stacktrace(struct fiq_debugger_output *output, - const struct pt_regs *regs, unsigned int depth, void *ssp) -{ - struct frame_tail *tail; - struct thread_info *real_thread_info = THREAD_INFO(ssp); - struct stacktrace_state sts; - - sts.depth = depth; - sts.output = output; - *current_thread_info() = *real_thread_info; - - if (!current) - output->printf(output, "current NULL\n"); - else - output->printf(output, "pid: %d comm: %s\n", - current->pid, current->comm); - fiq_debugger_dump_regs(output, regs); - - if (!user_mode(regs)) { - struct stackframe frame; - frame.fp = regs->ARM_fp; - frame.sp = regs->ARM_sp; - frame.lr = regs->ARM_lr; - frame.pc = regs->ARM_pc; - output->printf(output, - " pc: %p (%pF), lr %p (%pF), sp %p, fp %p\n", - regs->ARM_pc, regs->ARM_pc, regs->ARM_lr, regs->ARM_lr, - regs->ARM_sp, regs->ARM_fp); - walk_stackframe(&frame, report_trace, &sts); - return; - } - - tail = ((struct frame_tail *) regs->ARM_fp) - 1; - while (depth-- && tail && !((unsigned long) tail & 3)) - tail = user_backtrace(output, tail); -} diff --git a/drivers/staging/android/fiq_debugger/fiq_debugger_arm64.c b/drivers/staging/android/fiq_debugger/fiq_debugger_arm64.c deleted file mode 100644 index c53f4980bab9..000000000000 --- a/drivers/staging/android/fiq_debugger/fiq_debugger_arm64.c +++ /dev/null @@ -1,201 +0,0 @@ -/* - * Copyright (C) 2014 Google, Inc. - * Author: Colin Cross - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include - -#include "fiq_debugger_priv.h" - -static char *mode_name(const struct pt_regs *regs) -{ - if (compat_user_mode(regs)) { - return "USR"; - } else { - switch (processor_mode(regs)) { - case PSR_MODE_EL0t: return "EL0t"; - case PSR_MODE_EL1t: return "EL1t"; - case PSR_MODE_EL1h: return "EL1h"; - case PSR_MODE_EL2t: return "EL2t"; - case PSR_MODE_EL2h: return "EL2h"; - default: return "???"; - } - } -} - -void fiq_debugger_dump_pc(struct fiq_debugger_output *output, - const struct pt_regs *regs) -{ - output->printf(output, " pc %016lx cpsr %08lx mode %s\n", - regs->pc, regs->pstate, mode_name(regs)); -} - -void fiq_debugger_dump_regs_aarch32(struct fiq_debugger_output *output, - const struct pt_regs *regs) -{ - output->printf(output, " r0 %08x r1 %08x r2 %08x r3 %08x\n", - regs->compat_usr(0), regs->compat_usr(1), - regs->compat_usr(2), regs->compat_usr(3)); - output->printf(output, " r4 %08x r5 %08x r6 %08x r7 %08x\n", - regs->compat_usr(4), regs->compat_usr(5), - regs->compat_usr(6), regs->compat_usr(7)); - output->printf(output, " r8 %08x r9 %08x r10 %08x r11 %08x\n", - regs->compat_usr(8), regs->compat_usr(9), - regs->compat_usr(10), regs->compat_usr(11)); - output->printf(output, " ip %08x sp %08x lr %08x pc %08x\n", - regs->compat_usr(12), regs->compat_sp, - regs->compat_lr, regs->pc); - output->printf(output, " cpsr %08x (%s)\n", - regs->pstate, mode_name(regs)); -} - -void fiq_debugger_dump_regs_aarch64(struct fiq_debugger_output *output, - const struct pt_regs *regs) -{ - - output->printf(output, " x0 %016lx x1 %016lx\n", - regs->regs[0], regs->regs[1]); - output->printf(output, " x2 %016lx x3 %016lx\n", - regs->regs[2], regs->regs[3]); - output->printf(output, " x4 %016lx x5 %016lx\n", - regs->regs[4], regs->regs[5]); - output->printf(output, " x6 %016lx x7 %016lx\n", - regs->regs[6], regs->regs[7]); - output->printf(output, " x8 %016lx x9 %016lx\n", - regs->regs[8], regs->regs[9]); - output->printf(output, " x10 %016lx x11 %016lx\n", - regs->regs[10], regs->regs[11]); - output->printf(output, " x12 %016lx x13 %016lx\n", - regs->regs[12], regs->regs[13]); - output->printf(output, " x14 %016lx x15 %016lx\n", - regs->regs[14], regs->regs[15]); - output->printf(output, " x16 %016lx x17 %016lx\n", - regs->regs[16], regs->regs[17]); - output->printf(output, " x18 %016lx x19 %016lx\n", - regs->regs[18], regs->regs[19]); - output->printf(output, " x20 %016lx x21 %016lx\n", - regs->regs[20], regs->regs[21]); - output->printf(output, " x22 %016lx x23 %016lx\n", - regs->regs[22], regs->regs[23]); - output->printf(output, " x24 %016lx x25 %016lx\n", - regs->regs[24], regs->regs[25]); - output->printf(output, " x26 %016lx x27 %016lx\n", - regs->regs[26], regs->regs[27]); - output->printf(output, " x28 %016lx x29 %016lx\n", - regs->regs[28], regs->regs[29]); - output->printf(output, " x30 %016lx sp %016lx\n", - regs->regs[30], regs->sp); - output->printf(output, " pc %016lx cpsr %08x (%s)\n", - regs->pc, regs->pstate, mode_name(regs)); -} - -void fiq_debugger_dump_regs(struct fiq_debugger_output *output, - const struct pt_regs *regs) -{ - if (compat_user_mode(regs)) - fiq_debugger_dump_regs_aarch32(output, regs); - else - fiq_debugger_dump_regs_aarch64(output, regs); -} - -#define READ_SPECIAL_REG(x) ({ \ - u64 val; \ - asm volatile ("mrs %0, " # x : "=r"(val)); \ - val; \ -}) - -void fiq_debugger_dump_allregs(struct fiq_debugger_output *output, - const struct pt_regs *regs) -{ - u32 pstate = READ_SPECIAL_REG(CurrentEl); - bool in_el2 = (pstate & PSR_MODE_MASK) >= PSR_MODE_EL2t; - - fiq_debugger_dump_regs(output, regs); - - output->printf(output, " sp_el0 %016lx\n", - READ_SPECIAL_REG(sp_el0)); - - if (in_el2) - output->printf(output, " sp_el1 %016lx\n", - READ_SPECIAL_REG(sp_el1)); - - output->printf(output, " elr_el1 %016lx\n", - READ_SPECIAL_REG(elr_el1)); - - output->printf(output, " spsr_el1 %08lx\n", - READ_SPECIAL_REG(spsr_el1)); - - if (in_el2) { - output->printf(output, " spsr_irq %08lx\n", - READ_SPECIAL_REG(spsr_irq)); - output->printf(output, " spsr_abt %08lx\n", - READ_SPECIAL_REG(spsr_abt)); - output->printf(output, " spsr_und %08lx\n", - READ_SPECIAL_REG(spsr_und)); - output->printf(output, " spsr_fiq %08lx\n", - READ_SPECIAL_REG(spsr_fiq)); - output->printf(output, " spsr_el2 %08lx\n", - READ_SPECIAL_REG(elr_el2)); - output->printf(output, " spsr_el2 %08lx\n", - READ_SPECIAL_REG(spsr_el2)); - } -} - -struct stacktrace_state { - struct fiq_debugger_output *output; - unsigned int depth; -}; - -static int report_trace(struct stackframe *frame, void *d) -{ - struct stacktrace_state *sts = d; - - if (sts->depth) { - sts->output->printf(sts->output, "%pF:\n", frame->pc); - sts->output->printf(sts->output, - " pc %016lx fp %016lx\n", - frame->pc, frame->fp); - sts->depth--; - return 0; - } - sts->output->printf(sts->output, " ...\n"); - - return sts->depth == 0; -} - -void fiq_debugger_dump_stacktrace(struct fiq_debugger_output *output, - const struct pt_regs *regs, unsigned int depth, void *ssp) -{ - struct thread_info *real_thread_info = THREAD_INFO(ssp); - struct stacktrace_state sts; - - sts.depth = depth; - sts.output = output; - *current_thread_info() = *real_thread_info; - - if (!current) - output->printf(output, "current NULL\n"); - else - output->printf(output, "pid: %d comm: %s\n", - current->pid, current->comm); - fiq_debugger_dump_regs(output, regs); - - if (!user_mode(regs)) { - struct stackframe frame; - frame.fp = regs->regs[29]; - frame.pc = regs->pc; - output->printf(output, "\n"); - walk_stackframe(current, &frame, report_trace, &sts); - } -} diff --git a/drivers/staging/android/fiq_debugger/fiq_debugger_priv.h b/drivers/staging/android/fiq_debugger/fiq_debugger_priv.h deleted file mode 100644 index d5d051f727a8..000000000000 --- a/drivers/staging/android/fiq_debugger/fiq_debugger_priv.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (C) 2014 Google, Inc. - * Author: Colin Cross - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#ifndef _FIQ_DEBUGGER_PRIV_H_ -#define _FIQ_DEBUGGER_PRIV_H_ - -#define THREAD_INFO(sp) ((struct thread_info *) \ - ((unsigned long)(sp) & ~(THREAD_SIZE - 1))) - -struct fiq_debugger_output { - void (*printf)(struct fiq_debugger_output *output, const char *fmt, ...); -}; - -struct pt_regs; - -void fiq_debugger_dump_pc(struct fiq_debugger_output *output, - const struct pt_regs *regs); -void fiq_debugger_dump_regs(struct fiq_debugger_output *output, - const struct pt_regs *regs); -void fiq_debugger_dump_allregs(struct fiq_debugger_output *output, - const struct pt_regs *regs); -void fiq_debugger_dump_stacktrace(struct fiq_debugger_output *output, - const struct pt_regs *regs, unsigned int depth, void *ssp); - -#endif diff --git a/drivers/staging/android/fiq_debugger/fiq_debugger_ringbuf.h b/drivers/staging/android/fiq_debugger/fiq_debugger_ringbuf.h deleted file mode 100644 index 10c3c5d09098..000000000000 --- a/drivers/staging/android/fiq_debugger/fiq_debugger_ringbuf.h +++ /dev/null @@ -1,94 +0,0 @@ -/* - * drivers/staging/android/fiq_debugger/fiq_debugger_ringbuf.h - * - * simple lockless ringbuffer - * - * Copyright (C) 2010 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include -#include - -struct fiq_debugger_ringbuf { - int len; - int head; - int tail; - u8 buf[]; -}; - - -static inline struct fiq_debugger_ringbuf *fiq_debugger_ringbuf_alloc(int len) -{ - struct fiq_debugger_ringbuf *rbuf; - - rbuf = kzalloc(sizeof(*rbuf) + len, GFP_KERNEL); - if (rbuf == NULL) - return NULL; - - rbuf->len = len; - rbuf->head = 0; - rbuf->tail = 0; - smp_mb(); - - return rbuf; -} - -static inline void fiq_debugger_ringbuf_free(struct fiq_debugger_ringbuf *rbuf) -{ - kfree(rbuf); -} - -static inline int fiq_debugger_ringbuf_level(struct fiq_debugger_ringbuf *rbuf) -{ - int level = rbuf->head - rbuf->tail; - - if (level < 0) - level = rbuf->len + level; - - return level; -} - -static inline int fiq_debugger_ringbuf_room(struct fiq_debugger_ringbuf *rbuf) -{ - return rbuf->len - fiq_debugger_ringbuf_level(rbuf) - 1; -} - -static inline u8 -fiq_debugger_ringbuf_peek(struct fiq_debugger_ringbuf *rbuf, int i) -{ - return rbuf->buf[(rbuf->tail + i) % rbuf->len]; -} - -static inline int -fiq_debugger_ringbuf_consume(struct fiq_debugger_ringbuf *rbuf, int count) -{ - count = min(count, fiq_debugger_ringbuf_level(rbuf)); - - rbuf->tail = (rbuf->tail + count) % rbuf->len; - smp_mb(); - - return count; -} - -static inline int -fiq_debugger_ringbuf_push(struct fiq_debugger_ringbuf *rbuf, u8 datum) -{ - if (fiq_debugger_ringbuf_room(rbuf) == 0) - return 0; - - rbuf->buf[rbuf->head] = datum; - smp_mb(); - rbuf->head = (rbuf->head + 1) % rbuf->len; - smp_mb(); - - return 1; -} diff --git a/drivers/staging/android/fiq_debugger/fiq_watchdog.c b/drivers/staging/android/fiq_debugger/fiq_watchdog.c deleted file mode 100644 index 194b54138417..000000000000 --- a/drivers/staging/android/fiq_debugger/fiq_watchdog.c +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (C) 2014 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include - -#include "fiq_watchdog.h" -#include "fiq_debugger_priv.h" - -static DEFINE_RAW_SPINLOCK(fiq_watchdog_lock); - -static void fiq_watchdog_printf(struct fiq_debugger_output *output, - const char *fmt, ...) -{ - char buf[256]; - va_list ap; - int len; - - va_start(ap, fmt); - len = vscnprintf(buf, sizeof(buf), fmt, ap); - va_end(ap); - - ramoops_console_write_buf(buf, len); -} - -struct fiq_debugger_output fiq_watchdog_output = { - .printf = fiq_watchdog_printf, -}; - -void fiq_watchdog_triggered(const struct pt_regs *regs, void *svc_sp) -{ - char msg[24]; - int len; - - raw_spin_lock(&fiq_watchdog_lock); - - len = scnprintf(msg, sizeof(msg), "watchdog fiq cpu %d\n", - THREAD_INFO(svc_sp)->cpu); - ramoops_console_write_buf(msg, len); - - fiq_debugger_dump_stacktrace(&fiq_watchdog_output, regs, 100, svc_sp); - - raw_spin_unlock(&fiq_watchdog_lock); -} diff --git a/drivers/staging/android/fiq_debugger/fiq_watchdog.h b/drivers/staging/android/fiq_debugger/fiq_watchdog.h deleted file mode 100644 index c6b507f8d976..000000000000 --- a/drivers/staging/android/fiq_debugger/fiq_watchdog.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright (C) 2014 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#ifndef _FIQ_WATCHDOG_H_ -#define _FIQ_WATCHDOG_H_ - -void fiq_watchdog_triggered(const struct pt_regs *regs, void *svc_sp); - -#endif -- 2.20.1