[PATCH v4 04/13] ARM: mvebu: Remove the unused argument of set_cpu_coherent()
Thomas Petazzoni
thomas.petazzoni at free-electrons.com
Wed Feb 19 11:27:48 EST 2014
Dear Gregory CLEMENT,
On Thu, 13 Feb 2014 18:33:27 +0100, Gregory CLEMENT wrote:
> set_cpu_coherent() took the SMP group ID as parameter. But this
> parameter was never used, and the CPU always use the SMP group 0. So
> we can remove this parameter.
>
> Signed-off-by: Gregory CLEMENT <gregory.clement at free-electrons.com>
This patch does much more than what the title and commit log says. The
title and commit log says the patch is removing the useless parameter
of set_cpu_coherent(), which I'm fine with.
But this patch also renames ll_set_cpu_coherent() to
ll_set_cpu_coherent_and_smp(), introduces the modify_coherent_reg
macro, etc.
And actually, I'm really unhappy about this modify_coherent_reg macro.
It is a large blurb of assembly with some conditions in the middle. I
have already stated this in previous reviews of this patch series, but
you have not taken into account my comments: this stuff should be split
in separate functions, each function doing *one* thing, and then those
functions are called in sequence depending on what needs to be done
whether you're starting a secondary CPU, entering or exiting deep idle,
etc.
Here is what I would prefer to see:
/* Returns with r1 filled with the coherency base address */
ENTRY(ll_get_coherency_base)
mrc p15, 0, r1, c1, c0, 0
tst r1, #CR_M @ Check MMU bit enabled
bne 1f
/* use physical address of the coherency register */
adr r1, 3f
ldr r3, [r1]
ldr r1, [r1, r3]
b 2f
1:
/* use virtual address of the coherency register */
ldr r1, =coherency_base
ldr r1, [r1]
2:
mov pc, lr
ENDPROC(ll_get_coherency_base)
/* Returns with the CPU ID in r3 */
ENTRY(ll_get_cpuid)
mrc 15, 0, r3, cr0, cr0, 5
and r3, r3, #15
mov r2, #(1 << 24)
lsl r3, r2, r3
ARM_BE8(rev r3, r3)
mov pc, lr
ENDPROC(ll_get_cpuid)
ENTRY(ll_add_cpu_to_smp_group)
bl ll_get_coherency_base
bl ll_get_cpuid
add r0, r1, #ARMADA_XP_CFB_CFG_REG_OFFSET
1:
ldrex r2, [r0]
orr r2, r2, r3
strex r1, r2, [r0]
cmp r1, #0
bne 1b
mov pc, lr
ENDPROC(ll_add_cpu_to_smp_group)
ENTRY(ll_enable_coherency)
bl ll_get_coherency_base
bl ll_get_cpuid
add r0, r1, #ARMADA_XP_CFB_CTL_REG_OFFSET
1:
ldrex r2, [r0]
orr r2, r2, r3
strex r1, r2, [r0]
cmp r1, #0
bne 1b
dsb
mov pc, lr
ENDPROC(ll_enable_coherency)
ENTRY(ll_disable_coherency)
bl ll_get_coherency_base
bl ll_get_cpuid
add r0, r1, #ARMADA_XP_CFB_CTL_REG_OFFSET
1:
ldrex r2, [r0]
bic r2, r2, r3
strex r1, r2, [r0]
cmp r1, #0
bne 1b
dsb
mov pc, lr
ENDPROC(ll_disable_coherency)
And then, your C code calls ll_disable_coherency(),
ll_enable_coherency() and/or ll_add_cpu_to_smp_group().
An alternative solution is to implement more of this stuff in C, with
only a small helper function in assembly to do the atomic bit set or
clear magic:
/* First argument: address
Second argument: bit mask
*/
ENTRY(ll_atomic_bit_set)
1:
ldrex r2, [r0]
orr r2, r2, r1
strex r3, r2, [r0]
cmp r3, #0
bne 1b
dsb
mov pc, lr
ENDPROC(ll_atomic_bit_set)
ENTRY(ll_atomic_bit_clear)
1:
ldrex r2, [r0]
bic r2, r2, r1
strex r3, r2, [r0]
cmp r3, #0
bne 1b
dsb
mov pc, lr
ENDPROC(ll_atomic_bit_clear)
Thomas
--
Thomas Petazzoni, CTO, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
More information about the linux-arm-kernel
mailing list