mirror of
https://github.com/AetherDroid/android_kernel_samsung_on5xelte.git
synced 2025-09-08 09:08:05 -04:00
Fixed MTP to work with TWRP
This commit is contained in:
commit
f6dfaef42e
50820 changed files with 20846062 additions and 0 deletions
233
arch/arm/common/mcpm_head.S
Normal file
233
arch/arm/common/mcpm_head.S
Normal file
|
@ -0,0 +1,233 @@
|
|||
/*
|
||||
* arch/arm/common/mcpm_head.S -- kernel entry point for multi-cluster PM
|
||||
*
|
||||
* Created by: Nicolas Pitre, March 2012
|
||||
* Copyright: (C) 2012-2013 Linaro Limited
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
*
|
||||
* Refer to Documentation/arm/cluster-pm-race-avoidance.txt
|
||||
* for details of the synchronisation algorithms used here.
|
||||
*/
|
||||
|
||||
#include <linux/linkage.h>
|
||||
#include <asm/mcpm.h>
|
||||
#include <asm/assembler.h>
|
||||
|
||||
#include "vlock.h"
|
||||
|
||||
.if MCPM_SYNC_CLUSTER_CPUS
|
||||
.error "cpus must be the first member of struct mcpm_sync_struct"
|
||||
.endif
|
||||
|
||||
.macro pr_dbg string
|
||||
#if defined(CONFIG_DEBUG_LL) && defined(DEBUG)
|
||||
b 1901f
|
||||
1902: .asciz "CPU"
|
||||
1903: .asciz " cluster"
|
||||
1904: .asciz ": \string"
|
||||
.align
|
||||
1901: adr r0, 1902b
|
||||
bl printascii
|
||||
mov r0, r9
|
||||
bl printhex2
|
||||
adr r0, 1903b
|
||||
bl printascii
|
||||
mov r0, r10
|
||||
bl printhex2
|
||||
adr r0, 1904b
|
||||
bl printascii
|
||||
#endif
|
||||
.endm
|
||||
|
||||
.arm
|
||||
.align
|
||||
|
||||
ENTRY(mcpm_entry_point)
|
||||
|
||||
ARM_BE8(setend be)
|
||||
THUMB( adr r12, BSYM(1f) )
|
||||
THUMB( bx r12 )
|
||||
THUMB( .thumb )
|
||||
1:
|
||||
mrc p15, 0, r0, c0, c0, 5 @ MPIDR
|
||||
ubfx r9, r0, #0, #8 @ r9 = cpu
|
||||
ubfx r10, r0, #8, #8 @ r10 = cluster
|
||||
mov r3, #MAX_CPUS_PER_CLUSTER
|
||||
mla r4, r3, r10, r9 @ r4 = canonical CPU index
|
||||
cmp r4, #(MAX_CPUS_PER_CLUSTER * MAX_NR_CLUSTERS)
|
||||
blo 2f
|
||||
|
||||
/* We didn't expect this CPU. Try to cheaply make it quiet. */
|
||||
1: wfi
|
||||
wfe
|
||||
b 1b
|
||||
|
||||
2: pr_dbg "kernel mcpm_entry_point\n"
|
||||
|
||||
/*
|
||||
* MMU is off so we need to get to various variables in a
|
||||
* position independent way.
|
||||
*/
|
||||
adr r5, 3f
|
||||
ldmia r5, {r0, r6, r7, r8, r11}
|
||||
add r0, r5, r0 @ r0 = mcpm_entry_early_pokes
|
||||
add r6, r5, r6 @ r6 = mcpm_entry_vectors
|
||||
ldr r7, [r5, r7] @ r7 = mcpm_power_up_setup_phys
|
||||
add r8, r5, r8 @ r8 = mcpm_sync
|
||||
add r11, r5, r11 @ r11 = first_man_locks
|
||||
|
||||
@ Perform an early poke, if any
|
||||
add r0, r0, r4, lsl #3
|
||||
ldmia r0, {r0, r1}
|
||||
teq r0, #0
|
||||
strne r1, [r0]
|
||||
|
||||
mov r0, #MCPM_SYNC_CLUSTER_SIZE
|
||||
mla r8, r0, r10, r8 @ r8 = sync cluster base
|
||||
|
||||
@ Signal that this CPU is coming UP:
|
||||
mov r0, #CPU_COMING_UP
|
||||
mov r5, #MCPM_SYNC_CPU_SIZE
|
||||
mla r5, r9, r5, r8 @ r5 = sync cpu address
|
||||
strb r0, [r5]
|
||||
|
||||
@ At this point, the cluster cannot unexpectedly enter the GOING_DOWN
|
||||
@ state, because there is at least one active CPU (this CPU).
|
||||
|
||||
mov r0, #VLOCK_SIZE
|
||||
mla r11, r0, r10, r11 @ r11 = cluster first man lock
|
||||
mov r0, r11
|
||||
mov r1, r9 @ cpu
|
||||
bl vlock_trylock @ implies DMB
|
||||
|
||||
cmp r0, #0 @ failed to get the lock?
|
||||
bne mcpm_setup_wait @ wait for cluster setup if so
|
||||
|
||||
ldrb r0, [r8, #MCPM_SYNC_CLUSTER_CLUSTER]
|
||||
cmp r0, #CLUSTER_UP @ cluster already up?
|
||||
bne mcpm_setup @ if not, set up the cluster
|
||||
|
||||
@ Otherwise, release the first man lock and skip setup:
|
||||
mov r0, r11
|
||||
bl vlock_unlock
|
||||
b mcpm_setup_complete
|
||||
|
||||
mcpm_setup:
|
||||
@ Control dependency implies strb not observable before previous ldrb.
|
||||
|
||||
@ Signal that the cluster is being brought up:
|
||||
mov r0, #INBOUND_COMING_UP
|
||||
strb r0, [r8, #MCPM_SYNC_CLUSTER_INBOUND]
|
||||
dmb
|
||||
|
||||
@ Any CPU trying to take the cluster into CLUSTER_GOING_DOWN from this
|
||||
@ point onwards will observe INBOUND_COMING_UP and abort.
|
||||
|
||||
@ Wait for any previously-pending cluster teardown operations to abort
|
||||
@ or complete:
|
||||
mcpm_teardown_wait:
|
||||
ldrb r0, [r8, #MCPM_SYNC_CLUSTER_CLUSTER]
|
||||
cmp r0, #CLUSTER_GOING_DOWN
|
||||
bne first_man_setup
|
||||
wfe
|
||||
b mcpm_teardown_wait
|
||||
|
||||
first_man_setup:
|
||||
dmb
|
||||
|
||||
@ If the outbound gave up before teardown started, skip cluster setup:
|
||||
|
||||
cmp r0, #CLUSTER_UP
|
||||
beq mcpm_setup_leave
|
||||
|
||||
@ power_up_setup is now responsible for setting up the cluster:
|
||||
|
||||
cmp r7, #0
|
||||
mov r0, #1 @ second (cluster) affinity level
|
||||
blxne r7 @ Call power_up_setup if defined
|
||||
dmb
|
||||
|
||||
mov r0, #CLUSTER_UP
|
||||
strb r0, [r8, #MCPM_SYNC_CLUSTER_CLUSTER]
|
||||
dmb
|
||||
|
||||
mcpm_setup_leave:
|
||||
@ Leave the cluster setup critical section:
|
||||
|
||||
mov r0, #INBOUND_NOT_COMING_UP
|
||||
strb r0, [r8, #MCPM_SYNC_CLUSTER_INBOUND]
|
||||
dsb st
|
||||
sev
|
||||
|
||||
mov r0, r11
|
||||
bl vlock_unlock @ implies DMB
|
||||
b mcpm_setup_complete
|
||||
|
||||
@ In the contended case, non-first men wait here for cluster setup
|
||||
@ to complete:
|
||||
mcpm_setup_wait:
|
||||
ldrb r0, [r8, #MCPM_SYNC_CLUSTER_CLUSTER]
|
||||
cmp r0, #CLUSTER_UP
|
||||
wfene
|
||||
bne mcpm_setup_wait
|
||||
dmb
|
||||
|
||||
mcpm_setup_complete:
|
||||
@ If a platform-specific CPU setup hook is needed, it is
|
||||
@ called from here.
|
||||
|
||||
cmp r7, #0
|
||||
mov r0, #0 @ first (CPU) affinity level
|
||||
blxne r7 @ Call power_up_setup if defined
|
||||
dmb
|
||||
|
||||
@ Mark the CPU as up:
|
||||
|
||||
mov r0, #CPU_UP
|
||||
strb r0, [r5]
|
||||
|
||||
@ Observability order of CPU_UP and opening of the gate does not matter.
|
||||
|
||||
mcpm_entry_gated:
|
||||
ldr r5, [r6, r4, lsl #2] @ r5 = CPU entry vector
|
||||
cmp r5, #0
|
||||
wfeeq
|
||||
beq mcpm_entry_gated
|
||||
dmb
|
||||
|
||||
pr_dbg "released\n"
|
||||
bx r5
|
||||
|
||||
.align 2
|
||||
|
||||
3: .word mcpm_entry_early_pokes - .
|
||||
.word mcpm_entry_vectors - 3b
|
||||
.word mcpm_power_up_setup_phys - 3b
|
||||
.word mcpm_sync - 3b
|
||||
.word first_man_locks - 3b
|
||||
|
||||
ENDPROC(mcpm_entry_point)
|
||||
|
||||
.bss
|
||||
|
||||
.align CACHE_WRITEBACK_ORDER
|
||||
.type first_man_locks, #object
|
||||
first_man_locks:
|
||||
.space VLOCK_SIZE * MAX_NR_CLUSTERS
|
||||
.align CACHE_WRITEBACK_ORDER
|
||||
|
||||
.type mcpm_entry_vectors, #object
|
||||
ENTRY(mcpm_entry_vectors)
|
||||
.space 4 * MAX_NR_CLUSTERS * MAX_CPUS_PER_CLUSTER
|
||||
|
||||
.type mcpm_entry_early_pokes, #object
|
||||
ENTRY(mcpm_entry_early_pokes)
|
||||
.space 8 * MAX_NR_CLUSTERS * MAX_CPUS_PER_CLUSTER
|
||||
|
||||
.type mcpm_power_up_setup_phys, #object
|
||||
ENTRY(mcpm_power_up_setup_phys)
|
||||
.space 4 @ set by mcpm_sync_init()
|
Loading…
Add table
Add a link
Reference in a new issue