X-Git-Url: https://git.stricted.de/?p=GitHub%2Fmt8127%2Fandroid_kernel_alcatel_ttab.git;a=blobdiff_plain;f=arch%2Farm64%2Fkernel%2Fprocess.c;h=238c54a8d013de0b6153afb2cc7c4f16698f25fd;hp=46f02c3b5015ece9b1ca0ab4d57d9540a3288e67;hb=6fa3eb70c07b7ce2061fd6602159ac2d45a7dc3d;hpb=977b58e1dd6fc2a751fb427798bfb8256476c93e diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c index 46f02c3b5015..238c54a8d013 100644 --- a/arch/arm64/kernel/process.c +++ b/arch/arm64/kernel/process.c @@ -20,6 +20,7 @@ #include +#include #include #include #include @@ -40,8 +41,11 @@ #include #include #include +#include +#include #include #include +#include #include #include @@ -50,6 +54,8 @@ #include #include +extern void arch_reset(char mode, const char *cmd); + static void setup_restart(void) { /* @@ -84,22 +90,55 @@ EXPORT_SYMBOL_GPL(pm_power_off); 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) @@ -115,25 +154,103 @@ void machine_halt(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. */ @@ -141,6 +258,70 @@ void machine_restart(char *cmd) 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; @@ -156,6 +337,8 @@ void __show_regs(struct pt_regs *regs) if (i % 2 == 0) printk("\n"); } + if (!user_mode(regs)) + show_extra_register_data(regs, 128); printk("\n"); } @@ -184,7 +367,7 @@ void release_thread(struct task_struct *dead_task) 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; }