blob: b0a8f89cc9b69fd602796124460ecd122a232b26 [file] [log] [blame]
Michael Hennerich2714d9a2007-10-11 00:29:49 +08001/*
2 * arch/blackfin/kernel/reboot.c - handle shutdown/reboot
3 *
4 * Copyright 2004-2007 Analog Devices Inc.
5 *
6 * Licensed under the GPL-2 or later.
7 */
8
9#include <linux/interrupt.h>
10#include <asm/bfin-global.h>
11#include <asm/reboot.h>
12#include <asm/system.h>
13
Mike Frysinger6a42a912008-04-23 08:01:31 +080014/* A system soft reset makes external memory unusable so force
15 * this function into L1. We use the compiler ssync here rather
16 * than SSYNC() because it's safe (no interrupts and such) and
17 * we save some L1. We do not need to force sanity in the SYSCR
18 * register as the BMODE selection bit is cleared by the soft
19 * reset while the Core B bit (on dual core parts) is cleared by
20 * the core reset.
Michael Hennerich2714d9a2007-10-11 00:29:49 +080021 */
22__attribute__((l1_text))
23void bfin_reset(void)
24{
Mike Frysinger6a42a912008-04-23 08:01:31 +080025 /* Wait for completion of "system" events such as cache line
26 * line fills so that we avoid infinite stalls later on as
27 * much as possible. This code is in L1, so it won't trigger
28 * any such event after this point in time.
29 */
30 __builtin_bfin_ssync();
Michael Hennerich2714d9a2007-10-11 00:29:49 +080031
32 while (1) {
Mike Frysinger6a42a912008-04-23 08:01:31 +080033 /* Initiate System software reset. */
Michael Hennerich2714d9a2007-10-11 00:29:49 +080034 bfin_write_SWRST(0x7);
Michael Hennerich444ad822008-01-22 18:38:02 +080035
Mike Frysinger6a42a912008-04-23 08:01:31 +080036 /* Due to the way reset is handled in the hardware, we need
Mike Frysingerfffe53b2008-10-08 14:46:09 +080037 * to delay for 10 SCLKS. The only reliable way to do this is
38 * to calculate the CCLK/SCLK ratio and multiply 10. For now,
Mike Frysinger6a42a912008-04-23 08:01:31 +080039 * we'll assume worse case which is a 1:15 ratio.
40 */
41 asm(
42 "LSETUP (1f, 1f) LC0 = %0\n"
43 "1: nop;"
44 :
Mike Frysingerfffe53b2008-10-08 14:46:09 +080045 : "a" (15 * 10)
Mike Frysinger6a42a912008-04-23 08:01:31 +080046 : "LC0", "LB0", "LT0"
47 );
Michael Hennerich444ad822008-01-22 18:38:02 +080048
Mike Frysinger6a42a912008-04-23 08:01:31 +080049 /* Clear System software reset */
Michael Hennerich2714d9a2007-10-11 00:29:49 +080050 bfin_write_SWRST(0);
Mike Frysinger6a42a912008-04-23 08:01:31 +080051
52 /* Wait for the SWRST write to complete. Cannot rely on SSYNC
53 * though as the System state is all reset now.
54 */
55 asm(
56 "LSETUP (1f, 1f) LC1 = %0\n"
57 "1: nop;"
58 :
59 : "a" (15 * 1)
60 : "LC1", "LB1", "LT1"
61 );
62
63 /* Issue core reset */
Michael Hennerich2714d9a2007-10-11 00:29:49 +080064 asm("raise 1");
65 }
66}
67
68__attribute__((weak))
69void native_machine_restart(char *cmd)
70{
71}
72
73void machine_restart(char *cmd)
74{
75 native_machine_restart(cmd);
76 local_irq_disable();
77 bfin_reset();
78}
79
80__attribute__((weak))
81void native_machine_halt(void)
82{
83 idle_with_irq_disabled();
84}
85
86void machine_halt(void)
87{
88 native_machine_halt();
89}
90
91__attribute__((weak))
92void native_machine_power_off(void)
93{
94 idle_with_irq_disabled();
95}
96
97void machine_power_off(void)
98{
99 native_machine_power_off();
100}