Skip to content

Commit

Permalink
Merge branch 'for-linus' of master.kernel.org:/home/rmk/linux-2.6-arm
Browse files Browse the repository at this point in the history
* 'for-linus' of master.kernel.org:/home/rmk/linux-2.6-arm:
  [ARM] 4680/1: parentheses around NR_IRQS definition
  [ARM] 4679/1: AT91: Change maintainer email address
  [ARM] 4675/1: pxa: fix mfp address definition error for pxa320
  [ARM] 4674/1: pxa: increase LCD PCLK drive strength to fast 2mA for PXA300/PXA310
  [ARM] 4673/1: pxa: add missing IRQ_SSP4 definitions for PXA3xx
  [ARM] 4672/1: pxa: fix DRCMR(n) to support PXA27x and later processors
  [ARM] 4665/1: fix __und_usr wrt accessing the undefined insn in user space
  [ARM] 4659/1: remove possibilities for spurious false negative with __kuser_cmpxchg
  [ARM] 4661/1: fix do_undefinstr wrt the enabling of IRQs
  [ARM] uengine: fix memset size error
  [ARM] 4648/1: i.MX/MX1 ensure more complete AITC initialization
  [ARM] 4611/2: AT91: Fix GPIO buttons pins on SAM9261-EK.
  [ARM] 4650/1: AT91: New-style init of I2C, support for i2c-gpio
  [ARM] 4604/2: AT91: Master clock divistor on SAM9
  [ARM] 4662/1: Fix PXA serial driver compilation if SERIAL_PXA_CONSOLE is disabled
  [ARM] PXA ssp: unlock when ssp tries to close an invalid port
  [ARM] 4654/1: pxa: update default MFP register value
  [ARM] 4653/1: pxa: fix a gpio typo in mfp-pxa320.h
  [ARM] 4652/1: pxa: fix a typo of pxa27x usb host clk definition
  [ARM] 4651/1: pxa: add PXA3xx specific IRQ definitions
  • Loading branch information
Linus Torvalds committed Nov 30, 2007
2 parents 80cbd91 + e252d4c commit b62c855
Show file tree
Hide file tree
Showing 36 changed files with 403 additions and 116 deletions.
2 changes: 1 addition & 1 deletion MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -439,7 +439,7 @@ S: Maintained

ARM/ATMEL AT91RM9200 ARM ARCHITECTURE
P: Andrew Victor
M: andrew@sanpeople.com
M: linux@maxim.org.za
L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
W: http://maxim.org.za/at91_26.html
S: Maintained
Expand Down
6 changes: 2 additions & 4 deletions arch/arm/common/uengine.c
Original file line number Diff line number Diff line change
Expand Up @@ -374,8 +374,8 @@ static int set_initial_registers(int uengine, struct ixp2000_uengine_code *c)
u8 *ucode;
int i;

gpr_a = kmalloc(128 * sizeof(u32), GFP_KERNEL);
gpr_b = kmalloc(128 * sizeof(u32), GFP_KERNEL);
gpr_a = kzalloc(128 * sizeof(u32), GFP_KERNEL);
gpr_b = kzalloc(128 * sizeof(u32), GFP_KERNEL);
ucode = kmalloc(513 * 5, GFP_KERNEL);
if (gpr_a == NULL || gpr_b == NULL || ucode == NULL) {
kfree(ucode);
Expand All @@ -388,8 +388,6 @@ static int set_initial_registers(int uengine, struct ixp2000_uengine_code *c)
if (c->uengine_parameters & IXP2000_UENGINE_4_CONTEXTS)
per_ctx_regs = 32;

memset(gpr_a, 0, sizeof(gpr_a));
memset(gpr_b, 0, sizeof(gpr_b));
for (i = 0; i < 256; i++) {
struct ixp2000_reg_value *r = c->initial_reg_values + i;
u32 *bank;
Expand Down
96 changes: 58 additions & 38 deletions arch/arm/kernel/entry-armv.S
Original file line number Diff line number Diff line change
Expand Up @@ -339,16 +339,6 @@ __pabt_svc:
str r1, [sp] @ save the "real" r0 copied
@ from the exception stack

#if __LINUX_ARM_ARCH__ < 6 && !defined(CONFIG_NEEDS_SYSCALL_FOR_CMPXCHG)
#ifndef CONFIG_MMU
#warning "NPTL on non MMU needs fixing"
#else
@ make sure our user space atomic helper is aborted
cmp r2, #TASK_SIZE
bichs r3, r3, #PSR_Z_BIT
#endif
#endif

@
@ We are now ready to fill in the remaining blanks on the stack:
@
Expand All @@ -372,9 +362,25 @@ __pabt_svc:
zero_fp
.endm

.macro kuser_cmpxchg_check
#if __LINUX_ARM_ARCH__ < 6 && !defined(CONFIG_NEEDS_SYSCALL_FOR_CMPXCHG)
#ifndef CONFIG_MMU
#warning "NPTL on non MMU needs fixing"
#else
@ Make sure our user space atomic helper is restarted
@ 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
blhs kuser_cmpxchg_fixup
#endif
#endif
.endm

.align 5
__dabt_usr:
usr_entry
kuser_cmpxchg_check

@
@ Call the processor-specific abort handler:
Expand Down Expand Up @@ -404,6 +410,7 @@ __dabt_usr:
.align 5
__irq_usr:
usr_entry
kuser_cmpxchg_check

#ifdef CONFIG_TRACE_IRQFLAGS
bl trace_hardirqs_off
Expand Down Expand Up @@ -446,9 +453,9 @@ __und_usr:
@
@ r0 - instruction
@
1: ldrt r0, [r4]
adr r9, ret_from_exception
adr lr, __und_usr_unknown
1: ldrt r0, [r4]
@
@ fallthrough to call_fpe
@
Expand Down Expand Up @@ -669,7 +676,7 @@ __kuser_helper_start:
*
* Clobbered:
*
* the Z flag might be lost
* none
*
* Definition and user space usage example:
*
Expand Down Expand Up @@ -730,9 +737,6 @@ __kuser_memory_barrier: @ 0xffff0fa0
*
* - This routine already includes memory barriers as needed.
*
* - A failure might be transient, i.e. it is possible, although unlikely,
* that "failure" be returned even if *ptr == oldval.
*
* For example, a user space atomic_add implementation could look like this:
*
* #define atomic_add(ptr, val) \
Expand Down Expand Up @@ -769,46 +773,62 @@ __kuser_cmpxchg: @ 0xffff0fc0

#elif __LINUX_ARM_ARCH__ < 6

#ifdef CONFIG_MMU

/*
* Theory of operation:
*
* We set the Z flag before loading oldval. If ever an exception
* occurs we can not be sure the loaded value will still be the same
* when the exception returns, therefore the user exception handler
* will clear the Z flag whenever the interrupted user code was
* actually from the kernel address space (see the usr_entry macro).
*
* The post-increment on the str is used to prevent a race with an
* exception happening just after the str instruction which would
* clear the Z flag although the exchange was done.
* The only thing that can break atomicity in this cmpxchg
* implementation is either an IRQ or a data abort exception
* causing another process/thread to be scheduled in the middle
* of the critical sequence. To prevent this, code is added to
* the IRQ and data abort exception handlers to set the pc back
* to the beginning of the critical section if it is found to be
* within that critical section (see kuser_cmpxchg_fixup).
*/
#ifdef CONFIG_MMU
teq ip, ip @ set Z flag
ldr ip, [r2] @ load current val
add r3, r2, #1 @ prepare store ptr
teqeq ip, r0 @ compare with oldval if still allowed
streq r1, [r3, #-1]! @ store newval if still allowed
subs r0, r2, r3 @ if r2 == r3 the str occured
1: ldr r3, [r2] @ load current val
subs r3, r3, r0 @ compare with oldval
2: streq r1, [r2] @ store newval if eq
rsbs r0, r3, #0 @ set return val and C flag
usr_ret lr

.text
kuser_cmpxchg_fixup:
@ Called from kuser_cmpxchg_check macro.
@ r2 = 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.
mov r7, #0xffff0fff
sub r7, r7, #(0xffff0fff - (0xffff0fc0 + (1b - __kuser_cmpxchg)))
subs r8, r2, r7
rsbcss r8, r8, #(2b - 1b)
strcs r7, [sp, #S_PC]
mov pc, lr
.previous

#else
#warning "NPTL on non MMU needs fixing"
mov r0, #-1
adds r0, r0, #0
#endif
usr_ret lr
#endif

#else

#ifdef CONFIG_SMP
mcr p15, 0, r0, c7, c10, 5 @ dmb
#endif
ldrex r3, [r2]
1: ldrex r3, [r2]
subs r3, r3, r0
strexeq r3, r1, [r2]
teqeq r3, #1
beq 1b
rsbs r0, r3, #0
/* beware -- each __kuser slot must be 8 instructions max */
#ifdef CONFIG_SMP
mcr p15, 0, r0, c7, c10, 5 @ dmb
#endif
b __kuser_memory_barrier
#else
usr_ret lr
#endif

#endif

Expand All @@ -829,7 +849,7 @@ __kuser_cmpxchg: @ 0xffff0fc0
*
* Clobbered:
*
* the Z flag might be lost
* none
*
* Definition and user space usage example:
*
Expand Down
5 changes: 2 additions & 3 deletions arch/arm/kernel/traps.c
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,7 @@ asmlinkage void __exception do_undefinstr(struct pt_regs *regs)
if ((instr & hook->instr_mask) == hook->instr_val &&
(regs->ARM_cpsr & hook->cpsr_mask) == hook->cpsr_val) {
if (hook->fn(regs, instr) == 0) {
spin_unlock_irq(&undef_lock);
spin_unlock_irqrestore(&undef_lock, flags);
return;
}
}
Expand Down Expand Up @@ -509,7 +509,7 @@ asmlinkage int arm_syscall(int no, struct pt_regs *regs)
* existence. Don't ever use this from user code.
*/
case 0xfff0:
{
for (;;) {
extern void do_DataAbort(unsigned long addr, unsigned int fsr,
struct pt_regs *regs);
unsigned long val;
Expand Down Expand Up @@ -545,7 +545,6 @@ asmlinkage int arm_syscall(int no, struct pt_regs *regs)
up_read(&mm->mmap_sem);
/* simulate a write access fault */
do_DataAbort(addr, 15 + (1 << 11), regs);
return -1;
}
#endif

Expand Down
41 changes: 38 additions & 3 deletions arch/arm/mach-at91/at91rm9200_devices.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include <asm/mach/map.h>

#include <linux/platform_device.h>
#include <linux/i2c-gpio.h>

#include <asm/arch/board.h>
#include <asm/arch/gpio.h>
Expand Down Expand Up @@ -435,7 +436,40 @@ void __init at91_add_device_nand(struct at91_nand_data *data) {}
* TWI (i2c)
* -------------------------------------------------------------------- */

#if defined(CONFIG_I2C_AT91) || defined(CONFIG_I2C_AT91_MODULE)
/*
* Prefer the GPIO code since the TWI controller isn't robust
* (gets overruns and underruns under load) and can only issue
* repeated STARTs in one scenario (the driver doesn't yet handle them).
*/
#if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE)

static struct i2c_gpio_platform_data pdata = {
.sda_pin = AT91_PIN_PA25,
.sda_is_open_drain = 1,
.scl_pin = AT91_PIN_PA26,
.scl_is_open_drain = 1,
.udelay = 2, /* ~100 kHz */
};

static struct platform_device at91rm9200_twi_device = {
.name = "i2c-gpio",
.id = -1,
.dev.platform_data = &pdata,
};

void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices)
{
at91_set_GPIO_periph(AT91_PIN_PA25, 1); /* TWD (SDA) */
at91_set_multi_drive(AT91_PIN_PA25, 1);

at91_set_GPIO_periph(AT91_PIN_PA26, 1); /* TWCK (SCL) */
at91_set_multi_drive(AT91_PIN_PA26, 1);

i2c_register_board_info(0, devices, nr_devices);
platform_device_register(&at91rm9200_twi_device);
}

#elif defined(CONFIG_I2C_AT91) || defined(CONFIG_I2C_AT91_MODULE)

static struct resource twi_resources[] = {
[0] = {
Expand All @@ -457,7 +491,7 @@ static struct platform_device at91rm9200_twi_device = {
.num_resources = ARRAY_SIZE(twi_resources),
};

void __init at91_add_device_i2c(void)
void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices)
{
/* pins used for TWI interface */
at91_set_A_periph(AT91_PIN_PA25, 0); /* TWD */
Expand All @@ -466,10 +500,11 @@ void __init at91_add_device_i2c(void)
at91_set_A_periph(AT91_PIN_PA26, 0); /* TWCK */
at91_set_multi_drive(AT91_PIN_PA26, 1);

i2c_register_board_info(0, devices, nr_devices);
platform_device_register(&at91rm9200_twi_device);
}
#else
void __init at91_add_device_i2c(void) {}
void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices) {}
#endif


Expand Down
42 changes: 39 additions & 3 deletions arch/arm/mach-at91/at91sam9260_devices.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include <asm/mach/map.h>

#include <linux/platform_device.h>
#include <linux/i2c-gpio.h>

#include <asm/arch/board.h>
#include <asm/arch/gpio.h>
Expand Down Expand Up @@ -352,7 +353,41 @@ void __init at91_add_device_nand(struct at91_nand_data *data) {}
* TWI (i2c)
* -------------------------------------------------------------------- */

#if defined(CONFIG_I2C_AT91) || defined(CONFIG_I2C_AT91_MODULE)
/*
* Prefer the GPIO code since the TWI controller isn't robust
* (gets overruns and underruns under load) and can only issue
* repeated STARTs in one scenario (the driver doesn't yet handle them).
*/

#if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE)

static struct i2c_gpio_platform_data pdata = {
.sda_pin = AT91_PIN_PA23,
.sda_is_open_drain = 1,
.scl_pin = AT91_PIN_PA24,
.scl_is_open_drain = 1,
.udelay = 2, /* ~100 kHz */
};

static struct platform_device at91sam9260_twi_device = {
.name = "i2c-gpio",
.id = -1,
.dev.platform_data = &pdata,
};

void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices)
{
at91_set_GPIO_periph(AT91_PIN_PA23, 1); /* TWD (SDA) */
at91_set_multi_drive(AT91_PIN_PA23, 1);

at91_set_GPIO_periph(AT91_PIN_PA24, 1); /* TWCK (SCL) */
at91_set_multi_drive(AT91_PIN_PA24, 1);

i2c_register_board_info(0, devices, nr_devices);
platform_device_register(&at91sam9260_twi_device);
}

#elif defined(CONFIG_I2C_AT91) || defined(CONFIG_I2C_AT91_MODULE)

static struct resource twi_resources[] = {
[0] = {
Expand All @@ -374,7 +409,7 @@ static struct platform_device at91sam9260_twi_device = {
.num_resources = ARRAY_SIZE(twi_resources),
};

void __init at91_add_device_i2c(void)
void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices)
{
/* pins used for TWI interface */
at91_set_A_periph(AT91_PIN_PA23, 0); /* TWD */
Expand All @@ -383,10 +418,11 @@ void __init at91_add_device_i2c(void)
at91_set_A_periph(AT91_PIN_PA24, 0); /* TWCK */
at91_set_multi_drive(AT91_PIN_PA24, 1);

i2c_register_board_info(0, devices, nr_devices);
platform_device_register(&at91sam9260_twi_device);
}
#else
void __init at91_add_device_i2c(void) {}
void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices) {}
#endif


Expand Down
Loading

0 comments on commit b62c855

Please sign in to comment.