From: Russell King <rmk+kernel@arm.linux.org.uk>
Date: Fri, 22 Jul 2011 22:09:07 +0000 (+0100)
Subject: Merge branch 'devel-stable' into for-next
X-Git-Tag: v3.1-rc1~258^2
X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=3ad55155b222f2a901405dea20ff7c68828ecd92;p=users%2Fwilly%2Fxarray.git

Merge branch 'devel-stable' into for-next

Conflicts:
	arch/arm/kernel/entry-armv.S
---

3ad55155b222f2a901405dea20ff7c68828ecd92
diff --cc arch/arm/kernel/entry-armv.S
index fa02a22a4c4b,8f9ab5c9015b..a87cbf889ff4
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@@ -385,8 -391,8 +385,8 @@@ ENDPROC(__pabt_svc
  	@ if it was interrupted in a critical region.  Here we
  	@ perform a quick test inline since it should be false
  	@ 99.9999% of the time.  The rest is done out of line.
 -	cmp	r2, #TASK_SIZE
 +	cmp	r4, #TASK_SIZE
- 	blhs	kuser_cmpxchg_fixup
+ 	blhs	kuser_cmpxchg64_fixup
  #endif
  #endif
  	.endm
@@@ -742,40 -780,95 +723,95 @@@ ENDPROC(__switch_to
  __kuser_helper_start:
  
  /*
-  * Reference prototype:
-  *
-  *	void __kernel_memory_barrier(void)
-  *
-  * Input:
-  *
-  *	lr = return address
-  *
-  * Output:
-  *
-  *	none
-  *
-  * Clobbered:
-  *
-  *	none
-  *
-  * Definition and user space usage example:
-  *
-  *	typedef void (__kernel_dmb_t)(void);
-  *	#define __kernel_dmb (*(__kernel_dmb_t *)0xffff0fa0)
-  *
-  * Apply any needed memory barrier to preserve consistency with data modified
-  * manually and __kuser_cmpxchg usage.
-  *
-  * This could be used as follows:
-  *
-  * #define __kernel_dmb() \
-  *         asm volatile ( "mov r0, #0xffff0fff; mov lr, pc; sub pc, r0, #95" \
-  *	        : : : "r0", "lr","cc" )
+  * Due to the length of some sequences, __kuser_cmpxchg64 spans 2 regular
+  * kuser "slots", therefore 0xffff0f80 is not used as a valid entry point.
   */
  
- __kuser_memory_barrier:				@ 0xffff0fa0
+ __kuser_cmpxchg64:				@ 0xffff0f60
+ 
+ #if defined(CONFIG_NEEDS_SYSCALL_FOR_CMPXCHG)
+ 
+ 	/*
+ 	 * Poor you.  No fast solution possible...
+ 	 * The kernel itself must perform the operation.
+ 	 * A special ghost syscall is used for that (see traps.c).
+ 	 */
+ 	stmfd	sp!, {r7, lr}
+ 	ldr	r7, 1f			@ it's 20 bits
+ 	swi	__ARM_NR_cmpxchg64
+ 	ldmfd	sp!, {r7, pc}
+ 1:	.word	__ARM_NR_cmpxchg64
+ 
+ #elif defined(CONFIG_CPU_32v6K)
+ 
+ 	stmfd	sp!, {r4, r5, r6, r7}
+ 	ldrd	r4, r5, [r0]			@ load old val
+ 	ldrd	r6, r7, [r1]			@ load new val
+ 	smp_dmb	arm
+ 1:	ldrexd	r0, r1, [r2]			@ load current val
+ 	eors	r3, r0, r4			@ compare with oldval (1)
+ 	eoreqs	r3, r1, r5			@ compare with oldval (2)
+ 	strexdeq r3, r6, r7, [r2]		@ store newval if eq
+ 	teqeq	r3, #1				@ success?
+ 	beq	1b				@ if no then retry
  	smp_dmb	arm
+ 	rsbs	r0, r3, #0			@ set returned val and C flag
+ 	ldmfd	sp!, {r4, r5, r6, r7}
+ 	bx	lr
+ 
+ #elif !defined(CONFIG_SMP)
+ 
+ #ifdef CONFIG_MMU
+ 
+ 	/*
+ 	 * The only thing that can break atomicity in this cmpxchg64
+ 	 * implementation is either an IRQ or a data abort exception
+ 	 * causing another process/thread to be scheduled in the middle of
+ 	 * the critical sequence.  The same strategy as for cmpxchg is used.
+ 	 */
+ 	stmfd	sp!, {r4, r5, r6, lr}
+ 	ldmia	r0, {r4, r5}			@ load old val
+ 	ldmia	r1, {r6, lr}			@ load new val
+ 1:	ldmia	r2, {r0, r1}			@ load current val
+ 	eors	r3, r0, r4			@ compare with oldval (1)
+ 	eoreqs	r3, r1, r5			@ compare with oldval (2)
+ 2:	stmeqia	r2, {r6, lr}			@ store newval if eq
+ 	rsbs	r0, r3, #0			@ set return val and C flag
+ 	ldmfd	sp!, {r4, r5, r6, pc}
+ 
+ 	.text
+ kuser_cmpxchg64_fixup:
+ 	@ Called from kuser_cmpxchg_fixup.
 -	@ r2 = address of interrupted insn (must be preserved).
++	@ r4 = address of interrupted insn (must be preserved).
+ 	@ sp = saved regs. r7 and r8 are clobbered.
+ 	@ 1b = first critical insn, 2b = last critical insn.
 -	@ If r2 >= 1b and r2 <= 2b then saved pc_usr is set to 1b.
++	@ If r4 >= 1b and r4 <= 2b then saved pc_usr is set to 1b.
+ 	mov	r7, #0xffff0fff
+ 	sub	r7, r7, #(0xffff0fff - (0xffff0f60 + (1b - __kuser_cmpxchg64)))
 -	subs	r8, r2, r7
++	subs	r8, r4, r7
+ 	rsbcss	r8, r8, #(2b - 1b)
+ 	strcs	r7, [sp, #S_PC]
+ #if __LINUX_ARM_ARCH__ < 6
+ 	bcc	kuser_cmpxchg32_fixup
+ #endif
+ 	mov	pc, lr
+ 	.previous
+ 
+ #else
+ #warning "NPTL on non MMU needs fixing"
+ 	mov	r0, #-1
+ 	adds	r0, r0, #0
  	usr_ret	lr
+ #endif
+ 
+ #else
+ #error "incoherent kernel configuration"
+ #endif
+ 
+ 	/* pad to next slot */
+ 	.rept	(16 - (. - __kuser_cmpxchg64)/4)
+ 	.word	0
+ 	.endr
  
  	.align	5
  
@@@ -868,15 -913,15 +856,15 @@@ __kuser_cmpxchg:				@ 0xffff0fc
  	usr_ret	lr
  
  	.text
- kuser_cmpxchg_fixup:
+ kuser_cmpxchg32_fixup:
  	@ Called from kuser_cmpxchg_check macro.
 -	@ r2 = address of interrupted insn (must be preserved).
 +	@ r4 = address of interrupted insn (must be preserved).
  	@ sp = saved regs. r7 and r8 are clobbered.
  	@ 1b = first critical insn, 2b = last critical insn.
 -	@ If r2 >= 1b and r2 <= 2b then saved pc_usr is set to 1b.
 +	@ If r4 >= 1b and r4 <= 2b then saved pc_usr is set to 1b.
  	mov	r7, #0xffff0fff
  	sub	r7, r7, #(0xffff0fff - (0xffff0fc0 + (1b - __kuser_cmpxchg)))
 -	subs	r8, r2, r7
 +	subs	r8, r4, r7
  	rsbcss	r8, r8, #(2b - 1b)
  	strcs	r7, [sp, #S_PC]
  	mov	pc, lr
diff --cc arch/arm/kernel/setup.c
index 9c3278f37796,f59653d67652..70bca649e925
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@@ -917,8 -915,15 +917,14 @@@ void __init setup_arch(char **cmdline_p
  #endif
  	reserve_crashkernel();
  
 -	cpu_init();
  	tcm_init();
  
+ #ifdef CONFIG_ZONE_DMA
+ 	if (mdesc->dma_zone_size) {
+ 		extern unsigned long arm_dma_zone_size;
+ 		arm_dma_zone_size = mdesc->dma_zone_size;
+ 	}
+ #endif
  #ifdef CONFIG_MULTI_IRQ_HANDLER
  	handle_arch_irq = mdesc->handle_irq;
  #endif