diff options
author | Huacai Chen <chenhc@lemote.com> | 2014-03-21 06:44:08 -0400 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2014-03-31 12:17:12 -0400 |
commit | 300459d558725cdada5ddebbe52c24ef6e1853d3 (patch) | |
tree | fb93b1d6c2845af29cce7c06ae35a3b88b7f6431 /arch/mips/loongson/common | |
parent | 0e476d91244ec6a9f6be3eb1963627340d031f99 (diff) |
MIPS: Loongson 3: Add Loongson-3 SMP support
IPI registers of Loongson-3 include IPI_SET, IPI_CLEAR, IPI_STATUS,
IPI_EN and IPI_MAILBOX_BUF. Each bit of IPI_STATUS indicate a type of
IPI and IPI_EN indicate whether the IPI is enabled. The sender write 1
to IPI_SET bits generate IPIs in IPI_STATUS, and receiver write 1 to
bits of IPI_CLEAR to clear IPIs. IPI_MAILBOX_BUF are used to deliver
more information about IPIs.
Why we change code in arch/mips/loongson/common/setup.c?
If without this change, when SMP configured, system cannot boot since
it hang at printk() in cgroup_init_early(). The root cause is:
console_trylock()
\-->down_trylock(&console_sem)
\-->raw_spin_unlock_irqrestore(&sem->lock, flags)
\-->_raw_spin_unlock_irqrestore()(SMP/UP have different versions)
\-->__raw_spin_unlock_irqrestore() (following is the SMP case)
\-->do_raw_spin_unlock()
\-->arch_spin_unlock()
\-->nudge_writes()
\-->mb()
\-->wbflush()
\-->__wbflush()
In previous code __wbflush() is initialized in plat_mem_setup(), but
cgroup_init_early() is called before plat_mem_setup(). Therefore, In
this patch we make changes to avoid boot failure.
Signed-off-by: Huacai Chen <chenhc@lemote.com>
Signed-off-by: Hongliang Tao <taohl@lemote.com>
Signed-off-by: Hua Yan <yanh@lemote.com>
Tested-by: Alex Smith <alex.smith@imgtec.com>
Reviewed-by: Alex Smith <alex.smith@imgtec.com>
Cc: John Crispin <john@phrozen.org>
Cc: Steven J. Hill <Steven.Hill@imgtec.com>
Cc: Aurelien Jarno <aurelien@aurel32.net>
Cc: linux-mips@linux-mips.org
Cc: Fuxin Zhang <zhangfx@lemote.com>
Cc: Zhangjin Wu <wuzhangjin@gmail.com>
Patchwork: https://patchwork.linux-mips.org/patch/6638
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips/loongson/common')
-rw-r--r-- | arch/mips/loongson/common/init.c | 2 | ||||
-rw-r--r-- | arch/mips/loongson/common/setup.c | 8 |
2 files changed, 5 insertions, 5 deletions
diff --git a/arch/mips/loongson/common/init.c b/arch/mips/loongson/common/init.c index 81ba3b4a8f30..f37fe5413b73 100644 --- a/arch/mips/loongson/common/init.c +++ b/arch/mips/loongson/common/init.c | |||
@@ -9,6 +9,7 @@ | |||
9 | */ | 9 | */ |
10 | 10 | ||
11 | #include <linux/bootmem.h> | 11 | #include <linux/bootmem.h> |
12 | #include <asm/smp-ops.h> | ||
12 | 13 | ||
13 | #include <loongson.h> | 14 | #include <loongson.h> |
14 | 15 | ||
@@ -33,6 +34,7 @@ void __init prom_init(void) | |||
33 | 34 | ||
34 | /*init the uart base address */ | 35 | /*init the uart base address */ |
35 | prom_init_uart_base(); | 36 | prom_init_uart_base(); |
37 | register_smp_ops(&loongson3_smp_ops); | ||
36 | } | 38 | } |
37 | 39 | ||
38 | void __init prom_free_prom_memory(void) | 40 | void __init prom_free_prom_memory(void) |
diff --git a/arch/mips/loongson/common/setup.c b/arch/mips/loongson/common/setup.c index 8223f8acfd59..bb4ac922e47a 100644 --- a/arch/mips/loongson/common/setup.c +++ b/arch/mips/loongson/common/setup.c | |||
@@ -18,9 +18,6 @@ | |||
18 | #include <linux/screen_info.h> | 18 | #include <linux/screen_info.h> |
19 | #endif | 19 | #endif |
20 | 20 | ||
21 | void (*__wbflush)(void); | ||
22 | EXPORT_SYMBOL(__wbflush); | ||
23 | |||
24 | static void wbflush_loongson(void) | 21 | static void wbflush_loongson(void) |
25 | { | 22 | { |
26 | asm(".set\tpush\n\t" | 23 | asm(".set\tpush\n\t" |
@@ -32,10 +29,11 @@ static void wbflush_loongson(void) | |||
32 | ".set mips0\n\t"); | 29 | ".set mips0\n\t"); |
33 | } | 30 | } |
34 | 31 | ||
32 | void (*__wbflush)(void) = wbflush_loongson; | ||
33 | EXPORT_SYMBOL(__wbflush); | ||
34 | |||
35 | void __init plat_mem_setup(void) | 35 | void __init plat_mem_setup(void) |
36 | { | 36 | { |
37 | __wbflush = wbflush_loongson; | ||
38 | |||
39 | #ifdef CONFIG_VT | 37 | #ifdef CONFIG_VT |
40 | #if defined(CONFIG_VGA_CONSOLE) | 38 | #if defined(CONFIG_VGA_CONSOLE) |
41 | conswitchp = &vga_con; | 39 | conswitchp = &vga_con; |