MIPS: OCTEON: Improve _machine_halt implementation.
authorDavid Daney <david.daney@cavium.com>
Fri, 24 May 2013 16:23:02 +0000 (16:23 +0000)
committerRalf Baechle <ralf@linux-mips.org>
Thu, 6 Jun 2013 14:11:26 +0000 (16:11 +0200)
As noted by Wladislav Wiebe:
   $ halt
   ..
   Sent SIGKILL to all processes
   Requesting system halt
   [66.729373] System halted.
   [66.733244]
   [66.734761] =====================================
   [66.739473] [ BUG: lock held at task exit time! ]
   [66.744188] 3.8.7-0-sampleversion-fct #49 Tainted: G           O
   [66.750202] -------------------------------------
   [66.754913] init/21479 is exiting with locks still held!
   [66.760234] 1 lock held by init/21479:
   [66.763990]  #0:  (reboot_mutex){+.+...}, at: [<ffffffff801776c8>] SyS_reboot+0xe0/0x218
   [66.772165]
   [66.772165] stack backtrace:
   [66.776532] Call Trace:
   [66.778992] [<ffffffff805780a8>] dump_stack+0x8/0x34
   [66.783972] [<ffffffff801618b0>] do_exit+0x610/0xa70
   [66.788948] [<ffffffff801777a8>] SyS_reboot+0x1c0/0x218
   [66.794186] [<ffffffff8013d6a4>] handle_sys64+0x44/0x64

This is an alternative fix to the one sent by Wladislav.  We kill the
watchdog for each CPU and then spin in WAIT with interrupts disabled.
This is the lowest power mode for the OCTEON.  If we were to spin with
interrupts enabled, we would get a continual stream of warning messages
and backtraces from the lockup detector, so I chose to disable
interrupts.

Signed-off-by: David Daney <david.daney@cavium.com>
Cc: Maxim Uvarov <muvarov@gmail.com>
Cc: Wladislav Wiebe <wladislav.kw@gmail.com>
Cc: linux-mips@linux-mips.org
Cc: David Daney <david.daney@cavium.com>
Patchwork: https://patchwork.linux-mips.org/patch/5324/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
arch/mips/cavium-octeon/setup.c

index b0baa299f899b3c2322c0a4346cc4947dcfc2457..01b1b3f94feb77b115f6911771236961ff3e151c 100644 (file)
@@ -428,13 +428,16 @@ static void octeon_restart(char *command)
  */
 static void octeon_kill_core(void *arg)
 {
-       mb();
-       if (octeon_is_simulation()) {
-               /* The simulator needs the watchdog to stop for dead cores */
-               cvmx_write_csr(CVMX_CIU_WDOGX(cvmx_get_core_num()), 0);
+       if (octeon_is_simulation())
                /* A break instruction causes the simulator stop a core */
-               asm volatile ("sync\nbreak");
-       }
+               asm volatile ("break" ::: "memory");
+
+       local_irq_disable();
+       /* Disable watchdog on this core. */
+       cvmx_write_csr(CVMX_CIU_WDOGX(cvmx_get_core_num()), 0);
+       /* Spin in a low power mode. */
+       while (true)
+               asm volatile ("wait" ::: "memory");
 }
 
 
This page took 0.032292 seconds and 5 git commands to generate.