diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-04-02 22:50:11 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-04-02 22:50:11 -0400 |
| commit | 5e11611a5d22252f3f9c169a3c9377eac0c32033 (patch) | |
| tree | c4cd71175afb12c63bc5a3961098321ff0546b63 /arch | |
| parent | d4509e5a6edf8862c18d887a642ce4994bde297d (diff) | |
| parent | c6c352371c1ce486a62f4eb92e545b05cfcef76b (diff) | |
Merge master.kernel.org:/home/rmk/linux-2.6-arm
* master.kernel.org:/home/rmk/linux-2.6-arm:
ARM: 5965/1: Fix soft lockup in at91 udc driver
ARM: 6006/1: ARM: Use the correct NOP size in memmove for Thumb-2 kernel builds
ARM: 6005/1: arm: kprobes: fix register corruption with jprobes
ARM: 6003/1: removing compilation warning from pl061.h
ARM: 6001/1: removing compilation warning comming from clkdev.h
ARM: 6000/1: removing compilation warning comming from <asm/irq.h>
ARM: 5999/1: Including device.h and resource.h header files in linux/amba/bus.h
ARM: 5997/1: ARM: Correct the VFPv3 detection
ARM: 5996/1: ARM: Change the mandatory barriers implementation (4/4)
ARM: 5995/1: ARM: Add L2x0 outer_sync() support (3/4)
ARM: 5994/1: ARM: Add outer_cache_fns.sync function pointer (2/4)
ARM: 5993/1: ARM: Move the outer_cache definitions into a separate file (1/4)
Diffstat (limited to 'arch')
| -rw-r--r-- | arch/arm/include/asm/cacheflush.h | 38 | ||||
| -rw-r--r-- | arch/arm/include/asm/clkdev.h | 1 | ||||
| -rw-r--r-- | arch/arm/include/asm/irq.h | 1 | ||||
| -rw-r--r-- | arch/arm/include/asm/outercache.h | 75 | ||||
| -rw-r--r-- | arch/arm/include/asm/system.h | 16 | ||||
| -rw-r--r-- | arch/arm/kernel/kprobes.c | 10 | ||||
| -rw-r--r-- | arch/arm/lib/memmove.S | 4 | ||||
| -rw-r--r-- | arch/arm/mm/Kconfig | 13 | ||||
| -rw-r--r-- | arch/arm/mm/cache-l2x0.c | 10 | ||||
| -rw-r--r-- | arch/arm/vfp/vfpmodule.c | 2 |
10 files changed, 123 insertions, 47 deletions
diff --git a/arch/arm/include/asm/cacheflush.h b/arch/arm/include/asm/cacheflush.h index 72da7e045c6b..0d08d4170b64 100644 --- a/arch/arm/include/asm/cacheflush.h +++ b/arch/arm/include/asm/cacheflush.h | |||
| @@ -15,6 +15,7 @@ | |||
| 15 | #include <asm/glue.h> | 15 | #include <asm/glue.h> |
| 16 | #include <asm/shmparam.h> | 16 | #include <asm/shmparam.h> |
| 17 | #include <asm/cachetype.h> | 17 | #include <asm/cachetype.h> |
| 18 | #include <asm/outercache.h> | ||
| 18 | 19 | ||
| 19 | #define CACHE_COLOUR(vaddr) ((vaddr & (SHMLBA - 1)) >> PAGE_SHIFT) | 20 | #define CACHE_COLOUR(vaddr) ((vaddr & (SHMLBA - 1)) >> PAGE_SHIFT) |
| 20 | 21 | ||
| @@ -219,12 +220,6 @@ struct cpu_cache_fns { | |||
| 219 | void (*dma_flush_range)(const void *, const void *); | 220 | void (*dma_flush_range)(const void *, const void *); |
| 220 | }; | 221 | }; |
| 221 | 222 | ||
| 222 | struct outer_cache_fns { | ||
| 223 | void (*inv_range)(unsigned long, unsigned long); | ||
| 224 | void (*clean_range)(unsigned long, unsigned long); | ||
| 225 | void (*flush_range)(unsigned long, unsigned long); | ||
| 226 | }; | ||
| 227 | |||
| 228 | /* | 223 | /* |
| 229 | * Select the calling method | 224 | * Select the calling method |
| 230 | */ | 225 | */ |
| @@ -281,37 +276,6 @@ extern void dmac_flush_range(const void *, const void *); | |||
| 281 | 276 | ||
| 282 | #endif | 277 | #endif |
| 283 | 278 | ||
| 284 | #ifdef CONFIG_OUTER_CACHE | ||
| 285 | |||
| 286 | extern struct outer_cache_fns outer_cache; | ||
| 287 | |||
| 288 | static inline void outer_inv_range(unsigned long start, unsigned long end) | ||
| 289 | { | ||
| 290 | if (outer_cache.inv_range) | ||
| 291 | outer_cache.inv_range(start, end); | ||
| 292 | } | ||
| 293 | static inline void outer_clean_range(unsigned long start, unsigned long end) | ||
| 294 | { | ||
| 295 | if (outer_cache.clean_range) | ||
| 296 | outer_cache.clean_range(start, end); | ||
| 297 | } | ||
| 298 | static inline void outer_flush_range(unsigned long start, unsigned long end) | ||
| 299 | { | ||
| 300 | if (outer_cache.flush_range) | ||
| 301 | outer_cache.flush_range(start, end); | ||
| 302 | } | ||
| 303 | |||
| 304 | #else | ||
| 305 | |||
| 306 | static inline void outer_inv_range(unsigned long start, unsigned long end) | ||
| 307 | { } | ||
| 308 | static inline void outer_clean_range(unsigned long start, unsigned long end) | ||
| 309 | { } | ||
| 310 | static inline void outer_flush_range(unsigned long start, unsigned long end) | ||
| 311 | { } | ||
| 312 | |||
| 313 | #endif | ||
| 314 | |||
| 315 | /* | 279 | /* |
| 316 | * Copy user data from/to a page which is mapped into a different | 280 | * Copy user data from/to a page which is mapped into a different |
| 317 | * processes address space. Really, we want to allow our "user | 281 | * processes address space. Really, we want to allow our "user |
diff --git a/arch/arm/include/asm/clkdev.h b/arch/arm/include/asm/clkdev.h index 7a0690da5e63..b56c1389b6fa 100644 --- a/arch/arm/include/asm/clkdev.h +++ b/arch/arm/include/asm/clkdev.h | |||
| @@ -13,6 +13,7 @@ | |||
| 13 | #define __ASM_CLKDEV_H | 13 | #define __ASM_CLKDEV_H |
| 14 | 14 | ||
| 15 | struct clk; | 15 | struct clk; |
| 16 | struct device; | ||
| 16 | 17 | ||
| 17 | struct clk_lookup { | 18 | struct clk_lookup { |
| 18 | struct list_head node; | 19 | struct list_head node; |
diff --git a/arch/arm/include/asm/irq.h b/arch/arm/include/asm/irq.h index 328f14a8b790..237282f7c762 100644 --- a/arch/arm/include/asm/irq.h +++ b/arch/arm/include/asm/irq.h | |||
| @@ -17,6 +17,7 @@ | |||
| 17 | 17 | ||
| 18 | #ifndef __ASSEMBLY__ | 18 | #ifndef __ASSEMBLY__ |
| 19 | struct irqaction; | 19 | struct irqaction; |
| 20 | struct pt_regs; | ||
| 20 | extern void migrate_irqs(void); | 21 | extern void migrate_irqs(void); |
| 21 | 22 | ||
| 22 | extern void asm_do_IRQ(unsigned int, struct pt_regs *); | 23 | extern void asm_do_IRQ(unsigned int, struct pt_regs *); |
diff --git a/arch/arm/include/asm/outercache.h b/arch/arm/include/asm/outercache.h new file mode 100644 index 000000000000..25f76bae57ab --- /dev/null +++ b/arch/arm/include/asm/outercache.h | |||
| @@ -0,0 +1,75 @@ | |||
| 1 | /* | ||
| 2 | * arch/arm/include/asm/outercache.h | ||
| 3 | * | ||
| 4 | * Copyright (C) 2010 ARM Ltd. | ||
| 5 | * Written by Catalin Marinas <catalin.marinas@arm.com> | ||
| 6 | * | ||
| 7 | * This program is free software; you can redistribute it and/or modify | ||
| 8 | * it under the terms of the GNU General Public License version 2 as | ||
| 9 | * published by the Free Software Foundation. | ||
| 10 | * | ||
| 11 | * This program is distributed in the hope that it will be useful, | ||
| 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | * GNU General Public License for more details. | ||
| 15 | * | ||
| 16 | * You should have received a copy of the GNU General Public License | ||
| 17 | * along with this program; if not, write to the Free Software | ||
| 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 19 | */ | ||
| 20 | |||
| 21 | #ifndef __ASM_OUTERCACHE_H | ||
| 22 | #define __ASM_OUTERCACHE_H | ||
| 23 | |||
| 24 | struct outer_cache_fns { | ||
| 25 | void (*inv_range)(unsigned long, unsigned long); | ||
| 26 | void (*clean_range)(unsigned long, unsigned long); | ||
| 27 | void (*flush_range)(unsigned long, unsigned long); | ||
| 28 | #ifdef CONFIG_OUTER_CACHE_SYNC | ||
| 29 | void (*sync)(void); | ||
| 30 | #endif | ||
| 31 | }; | ||
| 32 | |||
| 33 | #ifdef CONFIG_OUTER_CACHE | ||
| 34 | |||
| 35 | extern struct outer_cache_fns outer_cache; | ||
| 36 | |||
| 37 | static inline void outer_inv_range(unsigned long start, unsigned long end) | ||
| 38 | { | ||
| 39 | if (outer_cache.inv_range) | ||
| 40 | outer_cache.inv_range(start, end); | ||
| 41 | } | ||
| 42 | static inline void outer_clean_range(unsigned long start, unsigned long end) | ||
| 43 | { | ||
| 44 | if (outer_cache.clean_range) | ||
| 45 | outer_cache.clean_range(start, end); | ||
| 46 | } | ||
| 47 | static inline void outer_flush_range(unsigned long start, unsigned long end) | ||
| 48 | { | ||
| 49 | if (outer_cache.flush_range) | ||
| 50 | outer_cache.flush_range(start, end); | ||
| 51 | } | ||
| 52 | |||
| 53 | #else | ||
| 54 | |||
| 55 | static inline void outer_inv_range(unsigned long start, unsigned long end) | ||
| 56 | { } | ||
| 57 | static inline void outer_clean_range(unsigned long start, unsigned long end) | ||
| 58 | { } | ||
| 59 | static inline void outer_flush_range(unsigned long start, unsigned long end) | ||
| 60 | { } | ||
| 61 | |||
| 62 | #endif | ||
| 63 | |||
| 64 | #ifdef CONFIG_OUTER_CACHE_SYNC | ||
| 65 | static inline void outer_sync(void) | ||
| 66 | { | ||
| 67 | if (outer_cache.sync) | ||
| 68 | outer_cache.sync(); | ||
| 69 | } | ||
| 70 | #else | ||
| 71 | static inline void outer_sync(void) | ||
| 72 | { } | ||
| 73 | #endif | ||
| 74 | |||
| 75 | #endif /* __ASM_OUTERCACHE_H */ | ||
diff --git a/arch/arm/include/asm/system.h b/arch/arm/include/asm/system.h index ca88e6a84707..4ace45ec3ef8 100644 --- a/arch/arm/include/asm/system.h +++ b/arch/arm/include/asm/system.h | |||
| @@ -60,6 +60,8 @@ | |||
| 60 | #include <linux/linkage.h> | 60 | #include <linux/linkage.h> |
| 61 | #include <linux/irqflags.h> | 61 | #include <linux/irqflags.h> |
| 62 | 62 | ||
| 63 | #include <asm/outercache.h> | ||
| 64 | |||
| 63 | #define __exception __attribute__((section(".exception.text"))) | 65 | #define __exception __attribute__((section(".exception.text"))) |
| 64 | 66 | ||
| 65 | struct thread_info; | 67 | struct thread_info; |
| @@ -137,10 +139,12 @@ extern unsigned int user_debug; | |||
| 137 | #define dmb() __asm__ __volatile__ ("" : : : "memory") | 139 | #define dmb() __asm__ __volatile__ ("" : : : "memory") |
| 138 | #endif | 140 | #endif |
| 139 | 141 | ||
| 140 | #if __LINUX_ARM_ARCH__ >= 7 || defined(CONFIG_SMP) | 142 | #ifdef CONFIG_ARCH_HAS_BARRIERS |
| 141 | #define mb() dmb() | 143 | #include <mach/barriers.h> |
| 144 | #elif __LINUX_ARM_ARCH__ >= 7 || defined(CONFIG_SMP) | ||
| 145 | #define mb() do { dsb(); outer_sync(); } while (0) | ||
| 142 | #define rmb() dmb() | 146 | #define rmb() dmb() |
| 143 | #define wmb() dmb() | 147 | #define wmb() mb() |
| 144 | #else | 148 | #else |
| 145 | #define mb() do { if (arch_is_coherent()) dmb(); else barrier(); } while (0) | 149 | #define mb() do { if (arch_is_coherent()) dmb(); else barrier(); } while (0) |
| 146 | #define rmb() do { if (arch_is_coherent()) dmb(); else barrier(); } while (0) | 150 | #define rmb() do { if (arch_is_coherent()) dmb(); else barrier(); } while (0) |
| @@ -152,9 +156,9 @@ extern unsigned int user_debug; | |||
| 152 | #define smp_rmb() barrier() | 156 | #define smp_rmb() barrier() |
| 153 | #define smp_wmb() barrier() | 157 | #define smp_wmb() barrier() |
| 154 | #else | 158 | #else |
| 155 | #define smp_mb() mb() | 159 | #define smp_mb() dmb() |
| 156 | #define smp_rmb() rmb() | 160 | #define smp_rmb() dmb() |
| 157 | #define smp_wmb() wmb() | 161 | #define smp_wmb() dmb() |
| 158 | #endif | 162 | #endif |
| 159 | 163 | ||
| 160 | #define read_barrier_depends() do { } while(0) | 164 | #define read_barrier_depends() do { } while(0) |
diff --git a/arch/arm/kernel/kprobes.c b/arch/arm/kernel/kprobes.c index 60c62c377fa9..610e0f561c32 100644 --- a/arch/arm/kernel/kprobes.c +++ b/arch/arm/kernel/kprobes.c | |||
| @@ -393,6 +393,14 @@ void __kprobes jprobe_return(void) | |||
| 393 | /* | 393 | /* |
| 394 | * Setup an empty pt_regs. Fill SP and PC fields as | 394 | * Setup an empty pt_regs. Fill SP and PC fields as |
| 395 | * they're needed by longjmp_break_handler. | 395 | * they're needed by longjmp_break_handler. |
| 396 | * | ||
| 397 | * We allocate some slack between the original SP and start of | ||
| 398 | * our fabricated regs. To be precise we want to have worst case | ||
| 399 | * covered which is STMFD with all 16 regs so we allocate 2 * | ||
| 400 | * sizeof(struct_pt_regs)). | ||
| 401 | * | ||
| 402 | * This is to prevent any simulated instruction from writing | ||
| 403 | * over the regs when they are accessing the stack. | ||
| 396 | */ | 404 | */ |
| 397 | "sub sp, %0, %1 \n\t" | 405 | "sub sp, %0, %1 \n\t" |
| 398 | "ldr r0, ="__stringify(JPROBE_MAGIC_ADDR)"\n\t" | 406 | "ldr r0, ="__stringify(JPROBE_MAGIC_ADDR)"\n\t" |
| @@ -410,7 +418,7 @@ void __kprobes jprobe_return(void) | |||
| 410 | "ldmia sp, {r0 - pc} \n\t" | 418 | "ldmia sp, {r0 - pc} \n\t" |
| 411 | : | 419 | : |
| 412 | : "r" (kcb->jprobe_saved_regs.ARM_sp), | 420 | : "r" (kcb->jprobe_saved_regs.ARM_sp), |
| 413 | "I" (sizeof(struct pt_regs)), | 421 | "I" (sizeof(struct pt_regs) * 2), |
| 414 | "J" (offsetof(struct pt_regs, ARM_sp)), | 422 | "J" (offsetof(struct pt_regs, ARM_sp)), |
| 415 | "J" (offsetof(struct pt_regs, ARM_pc)), | 423 | "J" (offsetof(struct pt_regs, ARM_pc)), |
| 416 | "J" (offsetof(struct pt_regs, ARM_cpsr)) | 424 | "J" (offsetof(struct pt_regs, ARM_cpsr)) |
diff --git a/arch/arm/lib/memmove.S b/arch/arm/lib/memmove.S index 5025c863713d..938fc14f962d 100644 --- a/arch/arm/lib/memmove.S +++ b/arch/arm/lib/memmove.S | |||
| @@ -74,7 +74,7 @@ ENTRY(memmove) | |||
| 74 | rsb ip, ip, #32 | 74 | rsb ip, ip, #32 |
| 75 | addne pc, pc, ip @ C is always clear here | 75 | addne pc, pc, ip @ C is always clear here |
| 76 | b 7f | 76 | b 7f |
| 77 | 6: nop | 77 | 6: W(nop) |
| 78 | W(ldr) r3, [r1, #-4]! | 78 | W(ldr) r3, [r1, #-4]! |
| 79 | W(ldr) r4, [r1, #-4]! | 79 | W(ldr) r4, [r1, #-4]! |
| 80 | W(ldr) r5, [r1, #-4]! | 80 | W(ldr) r5, [r1, #-4]! |
| @@ -85,7 +85,7 @@ ENTRY(memmove) | |||
| 85 | 85 | ||
| 86 | add pc, pc, ip | 86 | add pc, pc, ip |
| 87 | nop | 87 | nop |
| 88 | nop | 88 | W(nop) |
| 89 | W(str) r3, [r0, #-4]! | 89 | W(str) r3, [r0, #-4]! |
| 90 | W(str) r4, [r0, #-4]! | 90 | W(str) r4, [r0, #-4]! |
| 91 | W(str) r5, [r0, #-4]! | 91 | W(str) r5, [r0, #-4]! |
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig index c4ed9f93f646..5bd7c89a6045 100644 --- a/arch/arm/mm/Kconfig +++ b/arch/arm/mm/Kconfig | |||
| @@ -736,6 +736,12 @@ config NEEDS_SYSCALL_FOR_CMPXCHG | |||
| 736 | config OUTER_CACHE | 736 | config OUTER_CACHE |
| 737 | bool | 737 | bool |
| 738 | 738 | ||
| 739 | config OUTER_CACHE_SYNC | ||
| 740 | bool | ||
| 741 | help | ||
| 742 | The outer cache has a outer_cache_fns.sync function pointer | ||
| 743 | that can be used to drain the write buffer of the outer cache. | ||
| 744 | |||
| 739 | config CACHE_FEROCEON_L2 | 745 | config CACHE_FEROCEON_L2 |
| 740 | bool "Enable the Feroceon L2 cache controller" | 746 | bool "Enable the Feroceon L2 cache controller" |
| 741 | depends on ARCH_KIRKWOOD || ARCH_MV78XX0 | 747 | depends on ARCH_KIRKWOOD || ARCH_MV78XX0 |
| @@ -757,6 +763,7 @@ config CACHE_L2X0 | |||
| 757 | REALVIEW_EB_A9MP || ARCH_MX35 || ARCH_MX31 || MACH_REALVIEW_PBX || ARCH_NOMADIK || ARCH_OMAP4 | 763 | REALVIEW_EB_A9MP || ARCH_MX35 || ARCH_MX31 || MACH_REALVIEW_PBX || ARCH_NOMADIK || ARCH_OMAP4 |
| 758 | default y | 764 | default y |
| 759 | select OUTER_CACHE | 765 | select OUTER_CACHE |
| 766 | select OUTER_CACHE_SYNC | ||
| 760 | help | 767 | help |
| 761 | This option enables the L2x0 PrimeCell. | 768 | This option enables the L2x0 PrimeCell. |
| 762 | 769 | ||
| @@ -781,3 +788,9 @@ config ARM_L1_CACHE_SHIFT | |||
| 781 | int | 788 | int |
| 782 | default 6 if ARM_L1_CACHE_SHIFT_6 | 789 | default 6 if ARM_L1_CACHE_SHIFT_6 |
| 783 | default 5 | 790 | default 5 |
| 791 | |||
| 792 | config ARCH_HAS_BARRIERS | ||
| 793 | bool | ||
| 794 | help | ||
| 795 | This option allows the use of custom mandatory barriers | ||
| 796 | included via the mach/barriers.h file. | ||
diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c index 07334632d3e2..21ad68ba22ba 100644 --- a/arch/arm/mm/cache-l2x0.c +++ b/arch/arm/mm/cache-l2x0.c | |||
| @@ -93,6 +93,15 @@ static inline void l2x0_flush_line(unsigned long addr) | |||
| 93 | } | 93 | } |
| 94 | #endif | 94 | #endif |
| 95 | 95 | ||
| 96 | static void l2x0_cache_sync(void) | ||
| 97 | { | ||
| 98 | unsigned long flags; | ||
| 99 | |||
| 100 | spin_lock_irqsave(&l2x0_lock, flags); | ||
| 101 | cache_sync(); | ||
| 102 | spin_unlock_irqrestore(&l2x0_lock, flags); | ||
| 103 | } | ||
| 104 | |||
| 96 | static inline void l2x0_inv_all(void) | 105 | static inline void l2x0_inv_all(void) |
| 97 | { | 106 | { |
| 98 | unsigned long flags; | 107 | unsigned long flags; |
| @@ -225,6 +234,7 @@ void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask) | |||
| 225 | outer_cache.inv_range = l2x0_inv_range; | 234 | outer_cache.inv_range = l2x0_inv_range; |
| 226 | outer_cache.clean_range = l2x0_clean_range; | 235 | outer_cache.clean_range = l2x0_clean_range; |
| 227 | outer_cache.flush_range = l2x0_flush_range; | 236 | outer_cache.flush_range = l2x0_flush_range; |
| 237 | outer_cache.sync = l2x0_cache_sync; | ||
| 228 | 238 | ||
| 229 | printk(KERN_INFO "L2X0 cache controller enabled\n"); | 239 | printk(KERN_INFO "L2X0 cache controller enabled\n"); |
| 230 | } | 240 | } |
diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c index 7f3f59fcaa21..a420cb949328 100644 --- a/arch/arm/vfp/vfpmodule.c +++ b/arch/arm/vfp/vfpmodule.c | |||
| @@ -545,7 +545,7 @@ static int __init vfp_init(void) | |||
| 545 | */ | 545 | */ |
| 546 | elf_hwcap |= HWCAP_VFP; | 546 | elf_hwcap |= HWCAP_VFP; |
| 547 | #ifdef CONFIG_VFPv3 | 547 | #ifdef CONFIG_VFPv3 |
| 548 | if (VFP_arch >= 3) { | 548 | if (VFP_arch >= 2) { |
| 549 | elf_hwcap |= HWCAP_VFPv3; | 549 | elf_hwcap |= HWCAP_VFPv3; |
| 550 | 550 | ||
| 551 | /* | 551 | /* |
