]> Pileus Git - ~andy/linux/commitdiff
Merge branches 'fixes' and 'misc' into for-linus
authorRussell King <rmk+kernel@arm.linux.org.uk>
Tue, 28 Jan 2014 21:38:48 +0000 (21:38 +0000)
committerRussell King <rmk+kernel@arm.linux.org.uk>
Tue, 28 Jan 2014 21:38:48 +0000 (21:38 +0000)
arch/arm/Makefile
arch/arm/include/asm/io.h
arch/arm/kernel/entry-armv.S
arch/arm/kernel/head.S
arch/arm/kernel/io.c
arch/arm/mm/init.c

index 23d5e3946589a6c5e240b7d0060d84efee71d5d5..08a9ef58d9c3567f1b78862ed136546416ad241d 100644 (file)
@@ -96,7 +96,7 @@ tune-$(CONFIG_CPU_V6K)                =$(call cc-option,-mtune=arm1136j-s,-mtune=strongarm)
 tune-y := $(tune-y)
 
 ifeq ($(CONFIG_AEABI),y)
-CFLAGS_ABI     :=-mabi=aapcs-linux -mno-thumb-interwork
+CFLAGS_ABI     :=-mabi=aapcs-linux -mno-thumb-interwork -mfpu=vfp
 else
 CFLAGS_ABI     :=$(call cc-option,-mapcs-32,-mabi=apcs-gnu) $(call cc-option,-mno-thumb-interwork,)
 endif
index fbeb39c869e9fdcedace1d61688247c14141cab3..8aa4cca74501f394b74d35fb69657553bc54daa3 100644 (file)
 #define isa_page_to_bus page_to_phys
 #define isa_bus_to_virt phys_to_virt
 
+/*
+ * Atomic MMIO-wide IO modify
+ */
+extern void atomic_io_modify(void __iomem *reg, u32 mask, u32 set);
+extern void atomic_io_modify_relaxed(void __iomem *reg, u32 mask, u32 set);
+
 /*
  * Generic IO read/write.  These perform native-endian accesses.  Note
  * that some architectures will want to re-define __raw_{read,write}w.
index b3fb8c9e1ff2d75f15666a9233dee2d1b3ccb6bc..1879e8dd2acc18a7837f0eee71beb8241c1aa9c0 100644 (file)
@@ -451,9 +451,11 @@ __und_usr_thumb:
        .arch   armv6t2
 #endif
 2:     ldrht   r5, [r4]
+ARM_BE8(rev16  r5, r5)                         @ little endian instruction
        cmp     r5, #0xe800                     @ 32bit instruction if xx != 0
        blo     __und_usr_fault_16              @ 16bit undefined instruction
 3:     ldrht   r0, [r2]
+ARM_BE8(rev16  r0, r0)                         @ little endian instruction
        add     r2, r2, #2                      @ r2 is PC + 2, make it PC + 4
        str     r2, [sp, #S_PC]                 @ it's a 2x16bit instr, update
        orr     r0, r0, r5, lsl #16
index 32f317e5828adafc2bdec200705a9d12c686711c..914616e0bdcd0c0108376a9e5834e9cb73219b51 100644 (file)
@@ -52,7 +52,8 @@
        .equ    swapper_pg_dir, KERNEL_RAM_VADDR - PG_DIR_SIZE
 
        .macro  pgtbl, rd, phys
-       add     \rd, \phys, #TEXT_OFFSET - PG_DIR_SIZE
+       add     \rd, \phys, #TEXT_OFFSET
+       sub     \rd, \rd, #PG_DIR_SIZE
        .endm
 
 /*
index dcd5b4d8614374519a80eb0772c8cd12df1320e0..9203cf883330a3c64460f07d572994f5f8263a83 100644 (file)
@@ -1,6 +1,41 @@
 #include <linux/export.h>
 #include <linux/types.h>
 #include <linux/io.h>
+#include <linux/spinlock.h>
+
+static DEFINE_RAW_SPINLOCK(__io_lock);
+
+/*
+ * Generic atomic MMIO modify.
+ *
+ * Allows thread-safe access to registers shared by unrelated subsystems.
+ * The access is protected by a single MMIO-wide lock.
+ */
+void atomic_io_modify_relaxed(void __iomem *reg, u32 mask, u32 set)
+{
+       unsigned long flags;
+       u32 value;
+
+       raw_spin_lock_irqsave(&__io_lock, flags);
+       value = readl_relaxed(reg) & ~mask;
+       value |= (set & mask);
+       writel_relaxed(value, reg);
+       raw_spin_unlock_irqrestore(&__io_lock, flags);
+}
+EXPORT_SYMBOL(atomic_io_modify_relaxed);
+
+void atomic_io_modify(void __iomem *reg, u32 mask, u32 set)
+{
+       unsigned long flags;
+       u32 value;
+
+       raw_spin_lock_irqsave(&__io_lock, flags);
+       value = readl_relaxed(reg) & ~mask;
+       value |= (set & mask);
+       writel(value, reg);
+       raw_spin_unlock_irqrestore(&__io_lock, flags);
+}
+EXPORT_SYMBOL(atomic_io_modify);
 
 /*
  * Copy data from IO memory space to "real" memory space.
index f57fb338cc8aaa2ee533ca77be3e06994a74b25f..804d61566a53dd235750f44ed6ad7875df246b70 100644 (file)
@@ -290,10 +290,11 @@ void __init arm_memblock_init(struct meminfo *mi,
 #endif
 #ifdef CONFIG_BLK_DEV_INITRD
        /* FDT scan will populate initrd_start */
-       if (initrd_start) {
+       if (initrd_start && !phys_initrd_size) {
                phys_initrd_start = __virt_to_phys(initrd_start);
                phys_initrd_size = initrd_end - initrd_start;
        }
+       initrd_start = initrd_end = 0;
        if (phys_initrd_size &&
            !memblock_is_region_memory(phys_initrd_start, phys_initrd_size)) {
                pr_err("INITRD: 0x%08llx+0x%08lx is not a memory region - disabling initrd\n",