123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160 |
- #include <linux/cpu.h>
- #include <linux/delay.h>
- #include <linux/reboot.h>
- #include <asm/cacheflush.h>
- #include <asm/idmap.h>
- #include <asm/virt.h>
- #include "reboot.h"
- typedef void (*phys_reset_t)(unsigned long, bool);
- void (*arm_pm_restart)(enum reboot_mode reboot_mode, const char *cmd);
- void (*pm_power_off)(void);
- EXPORT_SYMBOL(pm_power_off);
- static u64 soft_restart_stack[16];
- static void __soft_restart(void *addr)
- {
- phys_reset_t phys_reset;
- bool hvc = false;
-
- setup_mm_for_reboot();
-
- flush_cache_all();
-
- cpu_proc_fin();
-
- flush_cache_all();
-
- phys_reset = (phys_reset_t)virt_to_idmap(cpu_reset);
- #ifdef CONFIG_ARM_VIRT_EXT
-
- hvc = is_hyp_mode_available();
- #endif
- phys_reset((unsigned long)addr, hvc);
-
- BUG();
- }
- void _soft_restart(unsigned long addr, bool disable_l2)
- {
- u64 *stack = soft_restart_stack + ARRAY_SIZE(soft_restart_stack);
-
- raw_local_irq_disable();
- local_fiq_disable();
-
- if (disable_l2)
- outer_disable();
-
- call_with_stack(__soft_restart, (void *)addr, (void *)stack);
-
- BUG();
- }
- void soft_restart(unsigned long addr)
- {
- _soft_restart(addr, num_online_cpus() == 1);
- }
- void machine_shutdown(void)
- {
- disable_nonboot_cpus();
- }
- void machine_halt(void)
- {
- local_irq_disable();
- smp_send_stop();
- while (1);
- }
- void machine_power_off(void)
- {
- local_irq_disable();
- smp_send_stop();
- if (pm_power_off)
- pm_power_off();
- }
- void machine_restart(char *cmd)
- {
- local_irq_disable();
- smp_send_stop();
- if (arm_pm_restart)
- arm_pm_restart(reboot_mode, cmd);
- else
- do_kernel_restart(cmd);
-
- mdelay(1000);
-
- printk("Reboot failed -- System halted\n");
- while (1);
- }
|