#include <stdarg.h>
+#include <linux/compat.h>
#include <linux/export.h>
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/uaccess.h>
#include <linux/random.h>
#include <linux/hw_breakpoint.h>
+#include <linux/cpuidle.h>
+#include <linux/leds.h>
#include <linux/personality.h>
#include <linux/notifier.h>
+#include <linux/mtk_ram_console.h>
#include <asm/compat.h>
#include <asm/cacheflush.h>
#include <asm/processor.h>
#include <asm/stacktrace.h>
+extern void arch_reset(char mode, const char *cmd);
+
static void setup_restart(void)
{
/*
void (*arm_pm_restart)(char str, const char *cmd);
EXPORT_SYMBOL_GPL(arm_pm_restart);
+/*
+ * This is our default idle handler.
+ */
+
+void (*arm_pm_idle)(void);
+
+static void default_idle(void)
+{
+ if (arm_pm_idle)
+ arm_pm_idle();
+ else
+ cpu_do_idle();
+ local_irq_enable();
+}
+
void arch_cpu_idle_prepare(void)
{
local_fiq_enable();
}
+void arch_cpu_idle_enter(void)
+{
+ idle_notifier_call_chain(IDLE_START);
+ ledtrig_cpu(CPU_LED_IDLE_START);
+#ifdef CONFIG_PL310_ERRATA_769419
+ wmb();
+#endif
+}
+
+void arch_cpu_idle_exit(void)
+{
+ ledtrig_cpu(CPU_LED_IDLE_END);
+ idle_notifier_call_chain(IDLE_END);
+}
+
+#ifdef CONFIG_HOTPLUG_CPU
+void arch_cpu_idle_dead(void)
+{
+ cpu_die();
+}
+#endif
+
/*
- * This is our default idle handler.
+ * Called from the core idle loop.
*/
void arch_cpu_idle(void)
{
- /*
- * This should do all the clock switching and wait for interrupt
- * tricks
- */
- cpu_do_idle();
- local_irq_enable();
+ if (cpuidle_idle_call())
+ default_idle();
}
void machine_shutdown(void)
while (1);
}
+extern int reboot_pid;
+//static int reboot_pid = 0;
+
void machine_power_off(void)
{
+ struct task_struct *tsk;
+ /* Disable interrupts first */
+ local_irq_disable();
+ local_fiq_disable();
+
machine_shutdown();
+ if(reboot_pid > 1)
+ {
+ tsk = find_task_by_vpid(reboot_pid);
+ if(tsk == NULL)
+ tsk = current;
+ dump_stack();
+ }
+ else
+ {
+ tsk = current;
+ }
+
+ if(tsk->real_parent)
+ {
+ if(tsk->real_parent->real_parent)
+ {
+ printk("machine_shutdown: start, Proess(%s:%d). father %s:%d. grandfather %s:%d.\n",
+ tsk->comm, tsk->pid,tsk->real_parent->comm,tsk->real_parent->pid,
+ tsk->real_parent->real_parent->comm,tsk->real_parent->real_parent->pid);
+ }
+ else
+ {
+ printk("machine_shutdown: start, Proess(%s:%d). father %s:%d.\n",
+ tsk->comm, tsk->pid,tsk->real_parent->comm,tsk->real_parent->pid);
+ }
+ }
+ else
+ {
+ printk("machine_shutdown: start, Proess(%s:%d)\n", tsk->comm, tsk->pid);
+ }
+
+#ifdef CONFIG_MTK_EMMC_SUPPORT
+ last_kmsg_store_to_emmc();
+#endif
if (pm_power_off)
pm_power_off();
}
void machine_restart(char *cmd)
{
- machine_shutdown();
+ struct task_struct *tsk;
/* Disable interrupts first */
local_irq_disable();
local_fiq_disable();
+
+ machine_shutdown();
+
+ if(reboot_pid > 1)
+ {
+ tsk = find_task_by_vpid(reboot_pid);
+ if(tsk == NULL)
+ tsk = current;
+ dump_stack();
+ }
+ else
+ {
+ tsk = current;
+ }
+
+ if(tsk->real_parent)
+ {
+ if(tsk->real_parent->real_parent)
+ {
+ printk("machine_shutdown: start, Proess(%s:%d). father %s:%d. grandfather %s:%d.\n",
+ tsk->comm, tsk->pid,tsk->real_parent->comm,tsk->real_parent->pid,
+ tsk->real_parent->real_parent->comm,tsk->real_parent->real_parent->pid);
+ }
+ else
+ {
+ printk("machine_shutdown: start, Proess(%s:%d). father %s:%d.\n",
+ tsk->comm, tsk->pid,tsk->real_parent->comm,tsk->real_parent->pid);
+ }
+ }
+ else
+ {
+ printk("machine_shutdown: start, Proess(%s:%d)\n", tsk->comm, tsk->pid);
+ }
/* Now call the architecture specific reboot code. */
if (arm_pm_restart)
arm_pm_restart('h', cmd);
-
+#ifndef CONFIG_MTK_FPGA
+ else
+ arch_reset('h', cmd);
+#endif
/*
* Whoops - the architecture was unable to reboot.
*/
while (1);
}
+/*
+ * dump a block of kernel memory from around the given address
+ */
+static void show_data(unsigned long addr, int nbytes, const char *name)
+{
+ int i, j;
+ int nlines;
+ u32 *p;
+
+ /*
+ * don't attempt to dump non-kernel addresses or
+ * values that are probably just small negative numbers
+ */
+ if (addr < PAGE_OFFSET || addr > -256UL)
+ return;
+
+ printk("\n%s: %#lx:\n", name, addr);
+
+ /*
+ * round address down to a 32 bit boundary
+ * and always dump a multiple of 32 bytes
+ */
+ p = (u32 *)(addr & ~(sizeof(u32) - 1));
+ nbytes += (addr & (sizeof(u32) - 1));
+ nlines = (nbytes + 31) / 32;
+
+
+ for (i = 0; i < nlines; i++) {
+ /*
+ * just display low 16 bits of address to keep
+ * each line of the dump < 80 characters
+ */
+ printk("%04lx ", (unsigned long)p & 0xffff);
+ for (j = 0; j < 8; j++) {
+ u32 data;
+ if (probe_kernel_address(p, data)) {
+ printk(" ********");
+ } else {
+ printk(" %08x", data);
+ }
+ ++p;
+ }
+ printk("\n");
+ }
+}
+
+static void show_extra_register_data(struct pt_regs *regs, int nbytes)
+{
+ mm_segment_t fs;
+ unsigned int i;
+
+ fs = get_fs();
+ set_fs(KERNEL_DS);
+ show_data(regs->pc - nbytes, nbytes * 2, "PC");
+ show_data(regs->regs[30] - nbytes, nbytes * 2, "LR");
+ show_data(regs->sp - nbytes, nbytes * 2, "SP");
+ for (i = 0; i < 30; i++) {
+ char name[4];
+ snprintf(name, sizeof(name), "X%u", i);
+ show_data(regs->regs[i] - nbytes, nbytes * 2, name);
+ }
+ set_fs(fs);
+}
+
void __show_regs(struct pt_regs *regs)
{
int i;
if (i % 2 == 0)
printk("\n");
}
+ if (!user_mode(regs))
+ show_extra_register_data(regs, 128);
printk("\n");
}
{
}
+static void tls_thread_flush(void)
+{
+ asm ("msr tpidr_el0, xzr");
+
+ if (is_compat_task()) {
+ current->thread.tp_value = 0;
+
+ /*
+ * We need to ensure ordering between the shadow state and the
+ * hardware state, so that we don't corrupt the hardware state
+ * with a stale shadow state during context switch.
+ */
+ barrier();
+ asm ("msr tpidrro_el0, xzr");
+ }
+}
+
void flush_thread(void)
{
fpsimd_flush_thread();
+ tls_thread_flush();
flush_ptrace_hw_breakpoint(current);
}
int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src)
{
- fpsimd_save_state(¤t->thread.fpsimd_state);
+ fpsimd_preserve_current_state();
*dst = *src;
return 0;
}