~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/arm/kernel/reboot.c

Version: ~ [ linux-5.13-rc2 ] ~ [ linux-5.12.4 ] ~ [ linux-5.11.21 ] ~ [ linux-5.10.37 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.119 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.190 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.232 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.268 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.268 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.18.140 ] ~ [ linux-3.16.85 ] ~ [ linux-3.14.79 ] ~ [ linux-3.12.74 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  *  Copyright (C) 1996-2000 Russell King - Converted to ARM.
  3  *  Original Copyright (C) 1995  Linus Torvalds
  4  * 
  5  * This program is free software; you can redistribute it and/or modify
  6  * it under the terms of the GNU General Public License version 2 as
  7  * published by the Free Software Foundation.
  8  */
  9 #include <linux/cpu.h>
 10 #include <linux/delay.h>
 11 #include <linux/reboot.h>
 12 
 13 #include <asm/cacheflush.h>
 14 #include <asm/idmap.h>
 15 
 16 #include "reboot.h"
 17 
 18 typedef void (*phys_reset_t)(unsigned long);
 19 
 20 /*
 21  * Function pointers to optional machine specific functions
 22  */
 23 void (*arm_pm_restart)(enum reboot_mode reboot_mode, const char *cmd);
 24 void (*pm_power_off)(void);
 25 EXPORT_SYMBOL(pm_power_off);
 26 
 27 /*
 28  * A temporary stack to use for CPU reset. This is static so that we
 29  * don't clobber it with the identity mapping. When running with this
 30  * stack, any references to the current task *will not work* so you
 31  * should really do as little as possible before jumping to your reset
 32  * code.
 33  */
 34 static u64 soft_restart_stack[16];
 35 
 36 static void __soft_restart(void *addr)
 37 {
 38         phys_reset_t phys_reset;
 39 
 40         /* Take out a flat memory mapping. */
 41         setup_mm_for_reboot();
 42 
 43         /* Clean and invalidate caches */
 44         flush_cache_all();
 45 
 46         /* Turn off caching */
 47         cpu_proc_fin();
 48 
 49         /* Push out any further dirty data, and ensure cache is empty */
 50         flush_cache_all();
 51 
 52         /* Switch to the identity mapping. */
 53         phys_reset = (phys_reset_t)virt_to_idmap(cpu_reset);
 54         phys_reset((unsigned long)addr);
 55 
 56         /* Should never get here. */
 57         BUG();
 58 }
 59 
 60 void _soft_restart(unsigned long addr, bool disable_l2)
 61 {
 62         u64 *stack = soft_restart_stack + ARRAY_SIZE(soft_restart_stack);
 63 
 64         /* Disable interrupts first */
 65         raw_local_irq_disable();
 66         local_fiq_disable();
 67 
 68         /* Disable the L2 if we're the last man standing. */
 69         if (disable_l2)
 70                 outer_disable();
 71 
 72         /* Change to the new stack and continue with the reset. */
 73         call_with_stack(__soft_restart, (void *)addr, (void *)stack);
 74 
 75         /* Should never get here. */
 76         BUG();
 77 }
 78 
 79 void soft_restart(unsigned long addr)
 80 {
 81         _soft_restart(addr, num_online_cpus() == 1);
 82 }
 83 
 84 /*
 85  * Called by kexec, immediately prior to machine_kexec().
 86  *
 87  * This must completely disable all secondary CPUs; simply causing those CPUs
 88  * to execute e.g. a RAM-based pin loop is not sufficient. This allows the
 89  * kexec'd kernel to use any and all RAM as it sees fit, without having to
 90  * avoid any code or data used by any SW CPU pin loop. The CPU hotplug
 91  * functionality embodied in disable_nonboot_cpus() to achieve this.
 92  */
 93 void machine_shutdown(void)
 94 {
 95         disable_nonboot_cpus();
 96 }
 97 
 98 /*
 99  * Halting simply requires that the secondary CPUs stop performing any
100  * activity (executing tasks, handling interrupts). smp_send_stop()
101  * achieves this.
102  */
103 void machine_halt(void)
104 {
105         local_irq_disable();
106         smp_send_stop();
107         while (1);
108 }
109 
110 /*
111  * Power-off simply requires that the secondary CPUs stop performing any
112  * activity (executing tasks, handling interrupts). smp_send_stop()
113  * achieves this. When the system power is turned off, it will take all CPUs
114  * with it.
115  */
116 void machine_power_off(void)
117 {
118         local_irq_disable();
119         smp_send_stop();
120 
121         if (pm_power_off)
122                 pm_power_off();
123 }
124 
125 /*
126  * Restart requires that the secondary CPUs stop performing any activity
127  * while the primary CPU resets the system. Systems with a single CPU can
128  * use soft_restart() as their machine descriptor's .restart hook, since that
129  * will cause the only available CPU to reset. Systems with multiple CPUs must
130  * provide a HW restart implementation, to ensure that all CPUs reset at once.
131  * This is required so that any code running after reset on the primary CPU
132  * doesn't have to co-ordinate with other CPUs to ensure they aren't still
133  * executing pre-reset code, and using RAM that the primary CPU's code wishes
134  * to use. Implementing such co-ordination would be essentially impossible.
135  */
136 void machine_restart(char *cmd)
137 {
138         local_irq_disable();
139         smp_send_stop();
140 
141         if (arm_pm_restart)
142                 arm_pm_restart(reboot_mode, cmd);
143         else
144                 do_kernel_restart(cmd);
145 
146         /* Give a grace period for failure to restart of 1s */
147         mdelay(1000);
148 
149         /* Whoops - the platform was unable to reboot. Tell the user! */
150         printk("Reboot failed -- System halted\n");
151         while (1);
152 }
153 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp