Merge master.kernel.org:/home/rmk/linux-2.6-arm
This commit is contained in:
@@ -269,7 +269,7 @@ __pabt_svc:
|
|||||||
add r5, sp, #S_PC
|
add r5, sp, #S_PC
|
||||||
ldmia r7, {r2 - r4} @ Get USR pc, cpsr
|
ldmia r7, {r2 - r4} @ Get USR pc, cpsr
|
||||||
|
|
||||||
#if __LINUX_ARM_ARCH__ < 6
|
#if __LINUX_ARM_ARCH__ < 6 && !defined(CONFIG_NEEDS_SYSCALL_FOR_CMPXCHG)
|
||||||
@ make sure our user space atomic helper is aborted
|
@ make sure our user space atomic helper is aborted
|
||||||
cmp r2, #VIRT_OFFSET
|
cmp r2, #VIRT_OFFSET
|
||||||
bichs r3, r3, #PSR_Z_BIT
|
bichs r3, r3, #PSR_Z_BIT
|
||||||
@@ -616,11 +616,17 @@ __kuser_helper_start:
|
|||||||
|
|
||||||
__kuser_cmpxchg: @ 0xffff0fc0
|
__kuser_cmpxchg: @ 0xffff0fc0
|
||||||
|
|
||||||
#if __LINUX_ARM_ARCH__ < 6
|
#if defined(CONFIG_NEEDS_SYSCALL_FOR_CMPXCHG)
|
||||||
|
|
||||||
#ifdef CONFIG_SMP /* sanity check */
|
/*
|
||||||
#error "CONFIG_SMP on a machine supporting pre-ARMv6 processors?"
|
* Poor you. No fast solution possible...
|
||||||
#endif
|
* The kernel itself must perform the operation.
|
||||||
|
* A special ghost syscall is used for that (see traps.c).
|
||||||
|
*/
|
||||||
|
swi #0x9ffff0
|
||||||
|
mov pc, lr
|
||||||
|
|
||||||
|
#elif __LINUX_ARM_ARCH__ < 6
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Theory of operation:
|
* Theory of operation:
|
||||||
|
@@ -464,6 +464,55 @@ asmlinkage int arm_syscall(int no, struct pt_regs *regs)
|
|||||||
#endif
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
#ifdef CONFIG_NEEDS_SYSCALL_FOR_CMPXCHG
|
||||||
|
/*
|
||||||
|
* Atomically store r1 in *r2 if *r2 is equal to r0 for user space.
|
||||||
|
* Return zero in r0 if *MEM was changed or non-zero if no exchange
|
||||||
|
* happened. Also set the user C flag accordingly.
|
||||||
|
* If access permissions have to be fixed up then non-zero is
|
||||||
|
* returned and the operation has to be re-attempted.
|
||||||
|
*
|
||||||
|
* *NOTE*: This is a ghost syscall private to the kernel. Only the
|
||||||
|
* __kuser_cmpxchg code in entry-armv.S should be aware of its
|
||||||
|
* existence. Don't ever use this from user code.
|
||||||
|
*/
|
||||||
|
case 0xfff0:
|
||||||
|
{
|
||||||
|
extern void do_DataAbort(unsigned long addr, unsigned int fsr,
|
||||||
|
struct pt_regs *regs);
|
||||||
|
unsigned long val;
|
||||||
|
unsigned long addr = regs->ARM_r2;
|
||||||
|
struct mm_struct *mm = current->mm;
|
||||||
|
pgd_t *pgd; pmd_t *pmd; pte_t *pte;
|
||||||
|
|
||||||
|
regs->ARM_cpsr &= ~PSR_C_BIT;
|
||||||
|
spin_lock(&mm->page_table_lock);
|
||||||
|
pgd = pgd_offset(mm, addr);
|
||||||
|
if (!pgd_present(*pgd))
|
||||||
|
goto bad_access;
|
||||||
|
pmd = pmd_offset(pgd, addr);
|
||||||
|
if (!pmd_present(*pmd))
|
||||||
|
goto bad_access;
|
||||||
|
pte = pte_offset_map(pmd, addr);
|
||||||
|
if (!pte_present(*pte) || !pte_write(*pte))
|
||||||
|
goto bad_access;
|
||||||
|
val = *(unsigned long *)addr;
|
||||||
|
val -= regs->ARM_r0;
|
||||||
|
if (val == 0) {
|
||||||
|
*(unsigned long *)addr = regs->ARM_r1;
|
||||||
|
regs->ARM_cpsr |= PSR_C_BIT;
|
||||||
|
}
|
||||||
|
spin_unlock(&mm->page_table_lock);
|
||||||
|
return val;
|
||||||
|
|
||||||
|
bad_access:
|
||||||
|
spin_unlock(&mm->page_table_lock);
|
||||||
|
/* simulate a read access fault */
|
||||||
|
do_DataAbort(addr, 15 + (1 << 11), regs);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
default:
|
default:
|
||||||
/* Calls 9f00xx..9f07ff are defined to return -ENOSYS
|
/* Calls 9f00xx..9f07ff are defined to return -ENOSYS
|
||||||
if not implemented, rather than raising SIGILL. This
|
if not implemented, rather than raising SIGILL. This
|
||||||
|
@@ -87,9 +87,9 @@ ENTRY(__raw_writesw)
|
|||||||
subs r2, r2, #2
|
subs r2, r2, #2
|
||||||
orr ip, ip, r3, push_hbyte1
|
orr ip, ip, r3, push_hbyte1
|
||||||
strh ip, [r0]
|
strh ip, [r0]
|
||||||
bpl 2b
|
bpl 1b
|
||||||
|
|
||||||
3: tst r2, #1
|
tst r2, #1
|
||||||
2: movne ip, r3, lsr #8
|
3: movne ip, r3, lsr #8
|
||||||
strneh ip, [r0]
|
strneh ip, [r0]
|
||||||
mov pc, lr
|
mov pc, lr
|
||||||
|
@@ -422,3 +422,11 @@ config HAS_TLS_REG
|
|||||||
assume directly accessing that register and always obtain the
|
assume directly accessing that register and always obtain the
|
||||||
expected value only on ARMv7 and above.
|
expected value only on ARMv7 and above.
|
||||||
|
|
||||||
|
config NEEDS_SYSCALL_FOR_CMPXCHG
|
||||||
|
bool
|
||||||
|
default y if SMP && (CPU_32v5 || CPU_32v4 || CPU_32v3)
|
||||||
|
help
|
||||||
|
SMP on a pre-ARMv6 processor? Well OK then.
|
||||||
|
Forget about fast user space cmpxchg support.
|
||||||
|
It is just not possible.
|
||||||
|
|
||||||
|
@@ -1296,6 +1296,7 @@
|
|||||||
#define GPIO111_MMCDAT3 111 /* MMC DAT3 (PXA27x) */
|
#define GPIO111_MMCDAT3 111 /* MMC DAT3 (PXA27x) */
|
||||||
#define GPIO111_MMCCS1 111 /* MMC Chip Select 1 (PXA27x) */
|
#define GPIO111_MMCCS1 111 /* MMC Chip Select 1 (PXA27x) */
|
||||||
#define GPIO112_MMCCMD 112 /* MMC CMD (PXA27x) */
|
#define GPIO112_MMCCMD 112 /* MMC CMD (PXA27x) */
|
||||||
|
#define GPIO113_I2S_SYSCLK 113 /* I2S System Clock (PXA27x) */
|
||||||
#define GPIO113_AC97_RESET_N 113 /* AC97 NRESET on (PXA27x) */
|
#define GPIO113_AC97_RESET_N 113 /* AC97 NRESET on (PXA27x) */
|
||||||
|
|
||||||
/* GPIO alternate function mode & direction */
|
/* GPIO alternate function mode & direction */
|
||||||
@@ -1428,6 +1429,7 @@
|
|||||||
#define GPIO111_MMCDAT3_MD (111 | GPIO_ALT_FN_1_OUT)
|
#define GPIO111_MMCDAT3_MD (111 | GPIO_ALT_FN_1_OUT)
|
||||||
#define GPIO110_MMCCS1_MD (111 | GPIO_ALT_FN_1_OUT)
|
#define GPIO110_MMCCS1_MD (111 | GPIO_ALT_FN_1_OUT)
|
||||||
#define GPIO112_MMCCMD_MD (112 | GPIO_ALT_FN_1_OUT)
|
#define GPIO112_MMCCMD_MD (112 | GPIO_ALT_FN_1_OUT)
|
||||||
|
#define GPIO113_I2S_SYSCLK_MD (113 | GPIO_ALT_FN_1_OUT)
|
||||||
#define GPIO113_AC97_RESET_N_MD (113 | GPIO_ALT_FN_2_OUT)
|
#define GPIO113_AC97_RESET_N_MD (113 | GPIO_ALT_FN_2_OUT)
|
||||||
#define GPIO117_I2CSCL_MD (117 | GPIO_ALT_FN_1_OUT)
|
#define GPIO117_I2CSCL_MD (117 | GPIO_ALT_FN_1_OUT)
|
||||||
#define GPIO118_I2CSDA_MD (118 | GPIO_ALT_FN_1_IN)
|
#define GPIO118_I2CSDA_MD (118 | GPIO_ALT_FN_1_IN)
|
||||||
|
Reference in New Issue
Block a user