Merge remote-tracking branches 'regulator/fix/ad5398', 'regulator/fix/da9210', 'regul...
[cascardo/linux.git] / arch / arm / mach-shmobile / headsmp.S
1 /*
2  * SMP support for R-Mobile / SH-Mobile
3  *
4  * Copyright (C) 2010  Magnus Damm
5  * Copyright (C) 2010  Takashi Yoshii
6  *
7  * Based on vexpress, Copyright (c) 2003 ARM Limited, All Rights Reserved
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License version 2 as
11  * published by the Free Software Foundation.
12  */
13 #include <linux/init.h>
14 #include <linux/linkage.h>
15 #include <linux/threads.h>
16 #include <asm/assembler.h>
17 #include <asm/memory.h>
18
19 /*
20  * Reset vector for secondary CPUs.
21  * This will be mapped at address 0 by SBAR register.
22  * We need _long_ jump to the physical address.
23  */
24         .arm
25         .align  12
26 ENTRY(shmobile_boot_vector)
27         ldr     r1, 1f
28         bx      r1
29
30 ENDPROC(shmobile_boot_vector)
31
32         .align  2
33         .globl  shmobile_boot_fn
34 shmobile_boot_fn:
35 1:      .space  4
36         .globl  shmobile_boot_size
37 shmobile_boot_size:
38         .long   . - shmobile_boot_vector
39
40 /*
41  * Per-CPU SMP boot function/argument selection code based on MPIDR
42  */
43
44 ENTRY(shmobile_smp_boot)
45         mrc     p15, 0, r1, c0, c0, 5           @ r1 = MPIDR
46         and     r0, r1, #0xffffff               @ MPIDR_HWID_BITMASK
47                                                 @ r0 = cpu_logical_map() value
48         mov     r1, #0                          @ r1 = CPU index
49         adr     r2, 1f
50         ldmia   r2, {r5, r6, r7}
51         add     r5, r5, r2                      @ array of per-cpu mpidr values
52         add     r6, r6, r2                      @ array of per-cpu functions
53         add     r7, r7, r2                      @ array of per-cpu arguments
54
55 shmobile_smp_boot_find_mpidr:
56         ldr     r8, [r5, r1, lsl #2]
57         cmp     r8, r0
58         bne     shmobile_smp_boot_next
59
60         ldr     r9, [r6, r1, lsl #2]
61         cmp     r9, #0
62         bne     shmobile_smp_boot_found
63
64 shmobile_smp_boot_next:
65         add     r1, r1, #1
66         cmp     r1, #NR_CPUS
67         blo     shmobile_smp_boot_find_mpidr
68
69         b       shmobile_smp_sleep
70
71 shmobile_smp_boot_found:
72         ldr     r0, [r7, r1, lsl #2]
73         ret     r9
74 ENDPROC(shmobile_smp_boot)
75
76 ENTRY(shmobile_smp_sleep)
77         wfi
78         b       shmobile_smp_boot
79 ENDPROC(shmobile_smp_sleep)
80
81         .align  2
82 1:      .long   shmobile_smp_mpidr - .
83         .long   shmobile_smp_fn - 1b
84         .long   shmobile_smp_arg - 1b
85
86         .bss
87         .globl  shmobile_smp_mpidr
88 shmobile_smp_mpidr:
89         .space  NR_CPUS * 4
90         .globl  shmobile_smp_fn
91 shmobile_smp_fn:
92         .space  NR_CPUS * 4
93         .globl  shmobile_smp_arg
94 shmobile_smp_arg:
95         .space  NR_CPUS * 4