diff options
Diffstat (limited to 'arch/arm/common')
| -rw-r--r-- | arch/arm/common/Makefile | 2 | ||||
| -rw-r--r-- | arch/arm/common/mcpm_head.S | 41 |
2 files changed, 37 insertions, 6 deletions
diff --git a/arch/arm/common/Makefile b/arch/arm/common/Makefile index b070671033ae..9ec273188ccb 100644 --- a/arch/arm/common/Makefile +++ b/arch/arm/common/Makefile | |||
| @@ -11,4 +11,4 @@ obj-$(CONFIG_SHARP_PARAM) += sharpsl_param.o | |||
| 11 | obj-$(CONFIG_SHARP_SCOOP) += scoop.o | 11 | obj-$(CONFIG_SHARP_SCOOP) += scoop.o |
| 12 | obj-$(CONFIG_PCI_HOST_ITE8152) += it8152.o | 12 | obj-$(CONFIG_PCI_HOST_ITE8152) += it8152.o |
| 13 | obj-$(CONFIG_ARM_TIMER_SP804) += timer-sp.o | 13 | obj-$(CONFIG_ARM_TIMER_SP804) += timer-sp.o |
| 14 | obj-$(CONFIG_MCPM) += mcpm_head.o mcpm_entry.o | 14 | obj-$(CONFIG_MCPM) += mcpm_head.o mcpm_entry.o vlock.o |
diff --git a/arch/arm/common/mcpm_head.S b/arch/arm/common/mcpm_head.S index 7d729bd72674..8178705c4b24 100644 --- a/arch/arm/common/mcpm_head.S +++ b/arch/arm/common/mcpm_head.S | |||
| @@ -16,6 +16,8 @@ | |||
| 16 | #include <linux/linkage.h> | 16 | #include <linux/linkage.h> |
| 17 | #include <asm/mcpm.h> | 17 | #include <asm/mcpm.h> |
| 18 | 18 | ||
| 19 | #include "vlock.h" | ||
| 20 | |||
| 19 | .if MCPM_SYNC_CLUSTER_CPUS | 21 | .if MCPM_SYNC_CLUSTER_CPUS |
| 20 | .error "cpus must be the first member of struct mcpm_sync_struct" | 22 | .error "cpus must be the first member of struct mcpm_sync_struct" |
| 21 | .endif | 23 | .endif |
| @@ -69,10 +71,11 @@ ENTRY(mcpm_entry_point) | |||
| 69 | * position independent way. | 71 | * position independent way. |
| 70 | */ | 72 | */ |
| 71 | adr r5, 3f | 73 | adr r5, 3f |
| 72 | ldmia r5, {r6, r7, r8} | 74 | ldmia r5, {r6, r7, r8, r11} |
| 73 | add r6, r5, r6 @ r6 = mcpm_entry_vectors | 75 | add r6, r5, r6 @ r6 = mcpm_entry_vectors |
| 74 | ldr r7, [r5, r7] @ r7 = mcpm_power_up_setup_phys | 76 | ldr r7, [r5, r7] @ r7 = mcpm_power_up_setup_phys |
| 75 | add r8, r5, r8 @ r8 = mcpm_sync | 77 | add r8, r5, r8 @ r8 = mcpm_sync |
| 78 | add r11, r5, r11 @ r11 = first_man_locks | ||
| 76 | 79 | ||
| 77 | mov r0, #MCPM_SYNC_CLUSTER_SIZE | 80 | mov r0, #MCPM_SYNC_CLUSTER_SIZE |
| 78 | mla r8, r0, r10, r8 @ r8 = sync cluster base | 81 | mla r8, r0, r10, r8 @ r8 = sync cluster base |
| @@ -86,13 +89,22 @@ ENTRY(mcpm_entry_point) | |||
| 86 | @ At this point, the cluster cannot unexpectedly enter the GOING_DOWN | 89 | @ At this point, the cluster cannot unexpectedly enter the GOING_DOWN |
| 87 | @ state, because there is at least one active CPU (this CPU). | 90 | @ state, because there is at least one active CPU (this CPU). |
| 88 | 91 | ||
| 89 | @ Note: the following is racy as another CPU might be testing | 92 | mov r0, #VLOCK_SIZE |
| 90 | @ the same flag at the same moment. That'll be fixed later. | 93 | mla r11, r0, r10, r11 @ r11 = cluster first man lock |
| 94 | mov r0, r11 | ||
| 95 | mov r1, r9 @ cpu | ||
| 96 | bl vlock_trylock @ implies DMB | ||
| 97 | |||
| 98 | cmp r0, #0 @ failed to get the lock? | ||
| 99 | bne mcpm_setup_wait @ wait for cluster setup if so | ||
| 100 | |||
| 91 | ldrb r0, [r8, #MCPM_SYNC_CLUSTER_CLUSTER] | 101 | ldrb r0, [r8, #MCPM_SYNC_CLUSTER_CLUSTER] |
| 92 | cmp r0, #CLUSTER_UP @ cluster already up? | 102 | cmp r0, #CLUSTER_UP @ cluster already up? |
| 93 | bne mcpm_setup @ if not, set up the cluster | 103 | bne mcpm_setup @ if not, set up the cluster |
| 94 | 104 | ||
| 95 | @ Otherwise, skip setup: | 105 | @ Otherwise, release the first man lock and skip setup: |
| 106 | mov r0, r11 | ||
| 107 | bl vlock_unlock | ||
| 96 | b mcpm_setup_complete | 108 | b mcpm_setup_complete |
| 97 | 109 | ||
| 98 | mcpm_setup: | 110 | mcpm_setup: |
| @@ -142,6 +154,19 @@ mcpm_setup_leave: | |||
| 142 | dsb | 154 | dsb |
| 143 | sev | 155 | sev |
| 144 | 156 | ||
| 157 | mov r0, r11 | ||
| 158 | bl vlock_unlock @ implies DMB | ||
| 159 | b mcpm_setup_complete | ||
| 160 | |||
| 161 | @ In the contended case, non-first men wait here for cluster setup | ||
| 162 | @ to complete: | ||
| 163 | mcpm_setup_wait: | ||
| 164 | ldrb r0, [r8, #MCPM_SYNC_CLUSTER_CLUSTER] | ||
| 165 | cmp r0, #CLUSTER_UP | ||
| 166 | wfene | ||
| 167 | bne mcpm_setup_wait | ||
| 168 | dmb | ||
| 169 | |||
| 145 | mcpm_setup_complete: | 170 | mcpm_setup_complete: |
| 146 | @ If a platform-specific CPU setup hook is needed, it is | 171 | @ If a platform-specific CPU setup hook is needed, it is |
| 147 | @ called from here. | 172 | @ called from here. |
| @@ -173,11 +198,17 @@ mcpm_entry_gated: | |||
| 173 | 3: .word mcpm_entry_vectors - . | 198 | 3: .word mcpm_entry_vectors - . |
| 174 | .word mcpm_power_up_setup_phys - 3b | 199 | .word mcpm_power_up_setup_phys - 3b |
| 175 | .word mcpm_sync - 3b | 200 | .word mcpm_sync - 3b |
| 201 | .word first_man_locks - 3b | ||
| 176 | 202 | ||
| 177 | ENDPROC(mcpm_entry_point) | 203 | ENDPROC(mcpm_entry_point) |
| 178 | 204 | ||
| 179 | .bss | 205 | .bss |
| 180 | .align 5 | 206 | |
| 207 | .align CACHE_WRITEBACK_ORDER | ||
| 208 | .type first_man_locks, #object | ||
| 209 | first_man_locks: | ||
| 210 | .space VLOCK_SIZE * MAX_NR_CLUSTERS | ||
| 211 | .align CACHE_WRITEBACK_ORDER | ||
| 181 | 212 | ||
| 182 | .type mcpm_entry_vectors, #object | 213 | .type mcpm_entry_vectors, #object |
| 183 | ENTRY(mcpm_entry_vectors) | 214 | ENTRY(mcpm_entry_vectors) |
