From 1996bda2a42480c275656233e631ee0966574be4 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Fri, 21 May 2010 14:05:13 +0200 Subject: arch: Implement local64_t On 64bit, local_t is of size long, and thus we make local64_t an alias. On 32bit, we fall back to atomic64_t. (architecture can provide optimized 32-bit version) (This new facility is to be used by perf events optimizations.) Signed-off-by: Peter Zijlstra Cc: linux-arch@vger.kernel.org Cc: Andrew Morton Cc: Linus Torvalds LKML-Reference: Signed-off-by: Ingo Molnar --- arch/arm/include/asm/local64.h | 1 + 1 file changed, 1 insertion(+) create mode 100644 arch/arm/include/asm/local64.h (limited to 'arch/arm/include') diff --git a/arch/arm/include/asm/local64.h b/arch/arm/include/asm/local64.h new file mode 100644 index 000000000000..36c93b5cc239 --- /dev/null +++ b/arch/arm/include/asm/local64.h @@ -0,0 +1 @@ +#include -- cgit v1.2.3 From 390daa0d8f391378865221cd8446028884a3baa9 Mon Sep 17 00:00:00 2001 From: Steve Bennett Date: Wed, 21 Apr 2010 16:30:33 +1000 Subject: [ARM] pxa: fix incorrect gpio type in udc_pxa2xx.h gpio must be int, not u16, otherwise -1 isn't recognised by gpio_is_valid(). Signed-off-by: Steve Bennett Signed-off-by: Eric Miao --- arch/arm/include/asm/mach/udc_pxa2xx.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch/arm/include') diff --git a/arch/arm/include/asm/mach/udc_pxa2xx.h b/arch/arm/include/asm/mach/udc_pxa2xx.h index f3eabf1ecec3..833306ee9e7f 100644 --- a/arch/arm/include/asm/mach/udc_pxa2xx.h +++ b/arch/arm/include/asm/mach/udc_pxa2xx.h @@ -21,8 +21,8 @@ struct pxa2xx_udc_mach_info { * here. Note that sometimes the signals go through inverters... */ bool gpio_vbus_inverted; - u16 gpio_vbus; /* high == vbus present */ + int gpio_vbus; /* high == vbus present */ bool gpio_pullup_inverted; - u16 gpio_pullup; /* high == pullup activated */ + int gpio_pullup; /* high == pullup activated */ }; -- cgit v1.2.3 From 990cb8acf23cab19a2930f1ed5e7dc108f89079b Mon Sep 17 00:00:00 2001 From: Nicolas Pitre Date: Mon, 14 Jun 2010 16:27:19 -0400 Subject: [ARM] implement arch_randomize_brk() For this feature to take effect, CONFIG_COMPAT_BRK must be turned off. This can safely be turned off for any EABI user space versions. Signed-off-by: Nicolas Pitre --- arch/arm/include/asm/elf.h | 3 +++ arch/arm/kernel/process.c | 7 +++++++ 2 files changed, 10 insertions(+) (limited to 'arch/arm/include') diff --git a/arch/arm/include/asm/elf.h b/arch/arm/include/asm/elf.h index 51662feb9f1d..0a96e8c1b82a 100644 --- a/arch/arm/include/asm/elf.h +++ b/arch/arm/include/asm/elf.h @@ -121,4 +121,7 @@ int dump_task_regs(struct task_struct *t, elf_gregset_t *elfregs); extern void elf_set_personality(const struct elf32_hdr *); #define SET_PERSONALITY(ex) elf_set_personality(&(ex)) +extern unsigned long arch_randomize_brk(struct mm_struct *mm); +#define arch_randomize_brk arch_randomize_brk + #endif diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c index acf5e6fdb6dc..1c6eb7ed9642 100644 --- a/arch/arm/kernel/process.c +++ b/arch/arm/kernel/process.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -421,3 +422,9 @@ unsigned long get_wchan(struct task_struct *p) } while (count ++ < 16); return 0; } + +unsigned long arch_randomize_brk(struct mm_struct *mm) +{ + unsigned long range_end = mm->brk + 0x02000000; + return randomize_range(mm->brk, range_end, 0) ? : mm->brk; +} -- cgit v1.2.3 From c743f38013aeff58ef6252601e397b5ba281c633 Mon Sep 17 00:00:00 2001 From: Nicolas Pitre Date: Mon, 24 May 2010 23:55:42 -0400 Subject: ARM: initial stack protector (-fstack-protector) support This is the very basic stuff without the changing canary upon task switch yet. Just the Kconfig option and a constant canary value initialized at boot time. Signed-off-by: Nicolas Pitre --- arch/arm/Kconfig | 12 +++++++++++ arch/arm/Makefile | 4 ++++ arch/arm/include/asm/stackprotector.h | 38 +++++++++++++++++++++++++++++++++++ arch/arm/kernel/process.c | 6 ++++++ 4 files changed, 60 insertions(+) create mode 100644 arch/arm/include/asm/stackprotector.h (limited to 'arch/arm/include') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 1f254bd6c937..f160b93691cd 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -1374,6 +1374,18 @@ config UACCESS_WITH_MEMCPY However, if the CPU data cache is using a write-allocate mode, this option is unlikely to provide any performance gain. +config CC_STACKPROTECTOR + bool "Enable -fstack-protector buffer overflow detection (EXPERIMENTAL)" + help + This option turns on the -fstack-protector GCC feature. This + feature puts, at the beginning of functions, a canary value on + the stack just before the return address, and validates + the value just before actually returning. Stack based buffer + overflows (that need to overwrite this return address) now also + overwrite the canary, which gets detected and the attack is then + neutralized via a kernel panic. + This feature requires gcc version 4.2 or above. + endmenu menu "Boot options" diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 64ba313724d2..ddf6da158ad8 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -34,6 +34,10 @@ ifeq ($(CONFIG_FRAME_POINTER),y) KBUILD_CFLAGS +=-fno-omit-frame-pointer -mapcs -mno-sched-prolog endif +ifeq ($(CONFIG_CC_STACKPROTECTOR),y) +KBUILD_CFLAGS +=-fstack-protector +endif + ifeq ($(CONFIG_CPU_BIG_ENDIAN),y) KBUILD_CPPFLAGS += -mbig-endian AS += -EB diff --git a/arch/arm/include/asm/stackprotector.h b/arch/arm/include/asm/stackprotector.h new file mode 100644 index 000000000000..de003327be97 --- /dev/null +++ b/arch/arm/include/asm/stackprotector.h @@ -0,0 +1,38 @@ +/* + * GCC stack protector support. + * + * Stack protector works by putting predefined pattern at the start of + * the stack frame and verifying that it hasn't been overwritten when + * returning from the function. The pattern is called stack canary + * and gcc expects it to be defined by a global variable called + * "__stack_chk_guard" on ARM. This unfortunately means that on SMP + * we cannot have a different canary value per task. + */ + +#ifndef _ASM_STACKPROTECTOR_H +#define _ASM_STACKPROTECTOR_H 1 + +#include +#include + +extern unsigned long __stack_chk_guard; + +/* + * Initialize the stackprotector canary value. + * + * NOTE: this must only be called from functions that never return, + * and it must always be inlined. + */ +static __always_inline void boot_init_stack_canary(void) +{ + unsigned long canary; + + /* Try to get a semi random initial value. */ + get_random_bytes(&canary, sizeof(canary)); + canary ^= LINUX_VERSION_CODE; + + current->stack_canary = canary; + __stack_chk_guard = current->stack_canary; +} + +#endif /* _ASM_STACKPROTECTOR_H */ diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c index 1c6eb7ed9642..090ac9459da1 100644 --- a/arch/arm/kernel/process.c +++ b/arch/arm/kernel/process.c @@ -37,6 +37,12 @@ #include #include +#ifdef CONFIG_CC_STACKPROTECTOR +#include +unsigned long __stack_chk_guard __read_mostly; +EXPORT_SYMBOL(__stack_chk_guard); +#endif + static const char *processor_modes[] = { "USER_26", "FIQ_26" , "IRQ_26" , "SVC_26" , "UK4_26" , "UK5_26" , "UK6_26" , "UK7_26" , "UK8_26" , "UK9_26" , "UK10_26", "UK11_26", "UK12_26", "UK13_26", "UK14_26", "UK15_26", -- cgit v1.2.3 From 534be1d5a2da940ecc5e528992ea4ace8658157a Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Mon, 21 Jun 2010 15:29:03 +0100 Subject: ARM: 6194/1: change definition of cpu_relax() for ARM11MPCore Linux expects that if a CPU modifies a memory location, then that modification will eventually become visible to other CPUs in the system. On an ARM11MPCore processor, loads are prioritised over stores so it is possible for a store operation to be postponed if a polling loop immediately follows it. If the variable being polled indirectly depends on the outstanding store [for example, another CPU may be polling the variable that is pending modification] then there is the potential for deadlock if interrupts are disabled. This deadlock occurs in the KGDB testsuire when executing on an SMP ARM11MPCore configuration. This patch changes the definition of cpu_relax() to smp_mb() for ARMv6 cores, forcing a flushing of the write buffer on SMP systems before the next load takes place. If the Kernel is not compiled for SMP support, this will expand to a barrier() as before. Acked-by: Catalin Marinas Signed-off-by: Will Deacon Signed-off-by: Russell King --- arch/arm/include/asm/processor.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'arch/arm/include') diff --git a/arch/arm/include/asm/processor.h b/arch/arm/include/asm/processor.h index 6a89567ffc5b..7bed3daf83b8 100644 --- a/arch/arm/include/asm/processor.h +++ b/arch/arm/include/asm/processor.h @@ -91,7 +91,11 @@ extern void release_thread(struct task_struct *); unsigned long get_wchan(struct task_struct *p); +#if __LINUX_ARM_ARCH__ == 6 +#define cpu_relax() smp_mb() +#else #define cpu_relax() barrier() +#endif /* * Create a new kernel thread -- cgit v1.2.3 From 068de8d1be48a04b92fd97f76bb7e113b7be82a8 Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Thu, 8 Jul 2010 10:58:06 +0100 Subject: ARM: 6211/1: atomic ops: fix register constraints for atomic64_add_unless The atomic64_add_unless function compares an atomic variable with a given value and, if they are not equal, adds another given value to the atomic variable. The function returns zero if the addition did not occur and non-zero otherwise. On ARM, the return value is initialised to 1 in C code. Inline assembly code then performs the atomic64_add_unless operation, setting the return value to 0 iff the addition does not occur. This means that when the addition *does* occur, the value of ret must be preserved across the inline assembly and therefore requires a "+r" constraint rather than the current one of "=&r". Thanks to Nicolas Pitre for helping to spot this. Cc: stable@kernel.org Reviewed-by: Nicolas Pitre Signed-off-by: Will Deacon Signed-off-by: Russell King --- arch/arm/include/asm/atomic.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/arm/include') diff --git a/arch/arm/include/asm/atomic.h b/arch/arm/include/asm/atomic.h index a0162fa94564..e9e56c00b858 100644 --- a/arch/arm/include/asm/atomic.h +++ b/arch/arm/include/asm/atomic.h @@ -440,7 +440,7 @@ static inline int atomic64_add_unless(atomic64_t *v, u64 a, u64 u) " teq %2, #0\n" " bne 1b\n" "2:" - : "=&r" (val), "=&r" (ret), "=&r" (tmp) + : "=&r" (val), "+r" (ret), "=&r" (tmp) : "r" (&v->counter), "r" (u), "r" (a) : "cc"); -- cgit v1.2.3 From 398aa66827155ef52bab58bebd24597d90968929 Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Thu, 8 Jul 2010 10:59:16 +0100 Subject: ARM: 6212/1: atomic ops: add memory constraints to inline asm Currently, the 32-bit and 64-bit atomic operations on ARM do not include memory constraints in the inline assembly blocks. In the case of barrier-less operations [for example, atomic_add], this means that the compiler may constant fold values which have actually been modified by a call to an atomic operation. This issue can be observed in the atomic64_test routine in /lib/atomic64_test.c: 00000000 : 0: e1a0c00d mov ip, sp 4: e92dd830 push {r4, r5, fp, ip, lr, pc} 8: e24cb004 sub fp, ip, #4 c: e24dd008 sub sp, sp, #8 10: e24b3014 sub r3, fp, #20 14: e30d000d movw r0, #53261 ; 0xd00d 18: e3011337 movw r1, #4919 ; 0x1337 1c: e34c0001 movt r0, #49153 ; 0xc001 20: e34a1aa3 movt r1, #43683 ; 0xaaa3 24: e16300f8 strd r0, [r3, #-8]! 28: e30c0afe movw r0, #51966 ; 0xcafe 2c: e30b1eef movw r1, #48879 ; 0xbeef 30: e34d0eaf movt r0, #57007 ; 0xdeaf 34: e34d1ead movt r1, #57005 ; 0xdead 38: e1b34f9f ldrexd r4, [r3] 3c: e1a34f90 strexd r4, r0, [r3] 40: e3340000 teq r4, #0 44: 1afffffb bne 38 48: e59f0004 ldr r0, [pc, #4] ; 54 4c: e3a0101e mov r1, #30 50: ebfffffe bl 0 <__bug> 54: 00000000 .word 0x00000000 The atomic64_set (0x38-0x44) writes to the atomic64_t, but the compiler doesn't see this, assumes the test condition is always false and generates an unconditional branch to __bug. The rest of the test is optimised away. This patch adds suitable memory constraints to the atomic operations on ARM to ensure that the compiler is informed of the correct data hazards. We have to use the "Qo" constraints to avoid hitting the GCC anomaly described at http://gcc.gnu.org/bugzilla/show_bug.cgi?id=44492 , where the compiler makes assumptions about the writeback in the addressing mode used by the inline assembly. These constraints forbid the use of auto{inc,dec} addressing modes, so it doesn't matter if we don't use the operand exactly once. Cc: stable@kernel.org Reviewed-by: Nicolas Pitre Signed-off-by: Will Deacon Signed-off-by: Russell King --- arch/arm/include/asm/atomic.h | 132 +++++++++++++++++++++--------------------- 1 file changed, 66 insertions(+), 66 deletions(-) (limited to 'arch/arm/include') diff --git a/arch/arm/include/asm/atomic.h b/arch/arm/include/asm/atomic.h index e9e56c00b858..7e79503ab89b 100644 --- a/arch/arm/include/asm/atomic.h +++ b/arch/arm/include/asm/atomic.h @@ -40,12 +40,12 @@ static inline void atomic_add(int i, atomic_t *v) int result; __asm__ __volatile__("@ atomic_add\n" -"1: ldrex %0, [%2]\n" -" add %0, %0, %3\n" -" strex %1, %0, [%2]\n" +"1: ldrex %0, [%3]\n" +" add %0, %0, %4\n" +" strex %1, %0, [%3]\n" " teq %1, #0\n" " bne 1b" - : "=&r" (result), "=&r" (tmp) + : "=&r" (result), "=&r" (tmp), "+Qo" (v->counter) : "r" (&v->counter), "Ir" (i) : "cc"); } @@ -58,12 +58,12 @@ static inline int atomic_add_return(int i, atomic_t *v) smp_mb(); __asm__ __volatile__("@ atomic_add_return\n" -"1: ldrex %0, [%2]\n" -" add %0, %0, %3\n" -" strex %1, %0, [%2]\n" +"1: ldrex %0, [%3]\n" +" add %0, %0, %4\n" +" strex %1, %0, [%3]\n" " teq %1, #0\n" " bne 1b" - : "=&r" (result), "=&r" (tmp) + : "=&r" (result), "=&r" (tmp), "+Qo" (v->counter) : "r" (&v->counter), "Ir" (i) : "cc"); @@ -78,12 +78,12 @@ static inline void atomic_sub(int i, atomic_t *v) int result; __asm__ __volatile__("@ atomic_sub\n" -"1: ldrex %0, [%2]\n" -" sub %0, %0, %3\n" -" strex %1, %0, [%2]\n" +"1: ldrex %0, [%3]\n" +" sub %0, %0, %4\n" +" strex %1, %0, [%3]\n" " teq %1, #0\n" " bne 1b" - : "=&r" (result), "=&r" (tmp) + : "=&r" (result), "=&r" (tmp), "+Qo" (v->counter) : "r" (&v->counter), "Ir" (i) : "cc"); } @@ -96,12 +96,12 @@ static inline int atomic_sub_return(int i, atomic_t *v) smp_mb(); __asm__ __volatile__("@ atomic_sub_return\n" -"1: ldrex %0, [%2]\n" -" sub %0, %0, %3\n" -" strex %1, %0, [%2]\n" +"1: ldrex %0, [%3]\n" +" sub %0, %0, %4\n" +" strex %1, %0, [%3]\n" " teq %1, #0\n" " bne 1b" - : "=&r" (result), "=&r" (tmp) + : "=&r" (result), "=&r" (tmp), "+Qo" (v->counter) : "r" (&v->counter), "Ir" (i) : "cc"); @@ -118,11 +118,11 @@ static inline int atomic_cmpxchg(atomic_t *ptr, int old, int new) do { __asm__ __volatile__("@ atomic_cmpxchg\n" - "ldrex %1, [%2]\n" + "ldrex %1, [%3]\n" "mov %0, #0\n" - "teq %1, %3\n" - "strexeq %0, %4, [%2]\n" - : "=&r" (res), "=&r" (oldval) + "teq %1, %4\n" + "strexeq %0, %5, [%3]\n" + : "=&r" (res), "=&r" (oldval), "+Qo" (ptr->counter) : "r" (&ptr->counter), "Ir" (old), "r" (new) : "cc"); } while (res); @@ -137,12 +137,12 @@ static inline void atomic_clear_mask(unsigned long mask, unsigned long *addr) unsigned long tmp, tmp2; __asm__ __volatile__("@ atomic_clear_mask\n" -"1: ldrex %0, [%2]\n" -" bic %0, %0, %3\n" -" strex %1, %0, [%2]\n" +"1: ldrex %0, [%3]\n" +" bic %0, %0, %4\n" +" strex %1, %0, [%3]\n" " teq %1, #0\n" " bne 1b" - : "=&r" (tmp), "=&r" (tmp2) + : "=&r" (tmp), "=&r" (tmp2), "+Qo" (*addr) : "r" (addr), "Ir" (mask) : "cc"); } @@ -249,7 +249,7 @@ static inline u64 atomic64_read(atomic64_t *v) __asm__ __volatile__("@ atomic64_read\n" " ldrexd %0, %H0, [%1]" : "=&r" (result) - : "r" (&v->counter) + : "r" (&v->counter), "Qo" (v->counter) ); return result; @@ -260,11 +260,11 @@ static inline void atomic64_set(atomic64_t *v, u64 i) u64 tmp; __asm__ __volatile__("@ atomic64_set\n" -"1: ldrexd %0, %H0, [%1]\n" -" strexd %0, %2, %H2, [%1]\n" +"1: ldrexd %0, %H0, [%2]\n" +" strexd %0, %3, %H3, [%2]\n" " teq %0, #0\n" " bne 1b" - : "=&r" (tmp) + : "=&r" (tmp), "=Qo" (v->counter) : "r" (&v->counter), "r" (i) : "cc"); } @@ -275,13 +275,13 @@ static inline void atomic64_add(u64 i, atomic64_t *v) unsigned long tmp; __asm__ __volatile__("@ atomic64_add\n" -"1: ldrexd %0, %H0, [%2]\n" -" adds %0, %0, %3\n" -" adc %H0, %H0, %H3\n" -" strexd %1, %0, %H0, [%2]\n" +"1: ldrexd %0, %H0, [%3]\n" +" adds %0, %0, %4\n" +" adc %H0, %H0, %H4\n" +" strexd %1, %0, %H0, [%3]\n" " teq %1, #0\n" " bne 1b" - : "=&r" (result), "=&r" (tmp) + : "=&r" (result), "=&r" (tmp), "+Qo" (v->counter) : "r" (&v->counter), "r" (i) : "cc"); } @@ -294,13 +294,13 @@ static inline u64 atomic64_add_return(u64 i, atomic64_t *v) smp_mb(); __asm__ __volatile__("@ atomic64_add_return\n" -"1: ldrexd %0, %H0, [%2]\n" -" adds %0, %0, %3\n" -" adc %H0, %H0, %H3\n" -" strexd %1, %0, %H0, [%2]\n" +"1: ldrexd %0, %H0, [%3]\n" +" adds %0, %0, %4\n" +" adc %H0, %H0, %H4\n" +" strexd %1, %0, %H0, [%3]\n" " teq %1, #0\n" " bne 1b" - : "=&r" (result), "=&r" (tmp) + : "=&r" (result), "=&r" (tmp), "+Qo" (v->counter) : "r" (&v->counter), "r" (i) : "cc"); @@ -315,13 +315,13 @@ static inline void atomic64_sub(u64 i, atomic64_t *v) unsigned long tmp; __asm__ __volatile__("@ atomic64_sub\n" -"1: ldrexd %0, %H0, [%2]\n" -" subs %0, %0, %3\n" -" sbc %H0, %H0, %H3\n" -" strexd %1, %0, %H0, [%2]\n" +"1: ldrexd %0, %H0, [%3]\n" +" subs %0, %0, %4\n" +" sbc %H0, %H0, %H4\n" +" strexd %1, %0, %H0, [%3]\n" " teq %1, #0\n" " bne 1b" - : "=&r" (result), "=&r" (tmp) + : "=&r" (result), "=&r" (tmp), "+Qo" (v->counter) : "r" (&v->counter), "r" (i) : "cc"); } @@ -334,13 +334,13 @@ static inline u64 atomic64_sub_return(u64 i, atomic64_t *v) smp_mb(); __asm__ __volatile__("@ atomic64_sub_return\n" -"1: ldrexd %0, %H0, [%2]\n" -" subs %0, %0, %3\n" -" sbc %H0, %H0, %H3\n" -" strexd %1, %0, %H0, [%2]\n" +"1: ldrexd %0, %H0, [%3]\n" +" subs %0, %0, %4\n" +" sbc %H0, %H0, %H4\n" +" strexd %1, %0, %H0, [%3]\n" " teq %1, #0\n" " bne 1b" - : "=&r" (result), "=&r" (tmp) + : "=&r" (result), "=&r" (tmp), "+Qo" (v->counter) : "r" (&v->counter), "r" (i) : "cc"); @@ -358,12 +358,12 @@ static inline u64 atomic64_cmpxchg(atomic64_t *ptr, u64 old, u64 new) do { __asm__ __volatile__("@ atomic64_cmpxchg\n" - "ldrexd %1, %H1, [%2]\n" + "ldrexd %1, %H1, [%3]\n" "mov %0, #0\n" - "teq %1, %3\n" - "teqeq %H1, %H3\n" - "strexdeq %0, %4, %H4, [%2]" - : "=&r" (res), "=&r" (oldval) + "teq %1, %4\n" + "teqeq %H1, %H4\n" + "strexdeq %0, %5, %H5, [%3]" + : "=&r" (res), "=&r" (oldval), "+Qo" (ptr->counter) : "r" (&ptr->counter), "r" (old), "r" (new) : "cc"); } while (res); @@ -381,11 +381,11 @@ static inline u64 atomic64_xchg(atomic64_t *ptr, u64 new) smp_mb(); __asm__ __volatile__("@ atomic64_xchg\n" -"1: ldrexd %0, %H0, [%2]\n" -" strexd %1, %3, %H3, [%2]\n" +"1: ldrexd %0, %H0, [%3]\n" +" strexd %1, %4, %H4, [%3]\n" " teq %1, #0\n" " bne 1b" - : "=&r" (result), "=&r" (tmp) + : "=&r" (result), "=&r" (tmp), "+Qo" (ptr->counter) : "r" (&ptr->counter), "r" (new) : "cc"); @@ -402,16 +402,16 @@ static inline u64 atomic64_dec_if_positive(atomic64_t *v) smp_mb(); __asm__ __volatile__("@ atomic64_dec_if_positive\n" -"1: ldrexd %0, %H0, [%2]\n" +"1: ldrexd %0, %H0, [%3]\n" " subs %0, %0, #1\n" " sbc %H0, %H0, #0\n" " teq %H0, #0\n" " bmi 2f\n" -" strexd %1, %0, %H0, [%2]\n" +" strexd %1, %0, %H0, [%3]\n" " teq %1, #0\n" " bne 1b\n" "2:" - : "=&r" (result), "=&r" (tmp) + : "=&r" (result), "=&r" (tmp), "+Qo" (v->counter) : "r" (&v->counter) : "cc"); @@ -429,18 +429,18 @@ static inline int atomic64_add_unless(atomic64_t *v, u64 a, u64 u) smp_mb(); __asm__ __volatile__("@ atomic64_add_unless\n" -"1: ldrexd %0, %H0, [%3]\n" -" teq %0, %4\n" -" teqeq %H0, %H4\n" +"1: ldrexd %0, %H0, [%4]\n" +" teq %0, %5\n" +" teqeq %H0, %H5\n" " moveq %1, #0\n" " beq 2f\n" -" adds %0, %0, %5\n" -" adc %H0, %H0, %H5\n" -" strexd %2, %0, %H0, [%3]\n" +" adds %0, %0, %6\n" +" adc %H0, %H0, %H6\n" +" strexd %2, %0, %H0, [%4]\n" " teq %2, #0\n" " bne 1b\n" "2:" - : "=&r" (val), "+r" (ret), "=&r" (tmp) + : "=&r" (val), "+r" (ret), "=&r" (tmp), "+Qo" (v->counter) : "r" (&v->counter), "r" (u), "r" (a) : "cc"); -- cgit v1.2.3 From 354e6f72d6fd5d3d2963efe030265972866cd969 Mon Sep 17 00:00:00 2001 From: eric miao Date: Fri, 25 Jun 2010 09:46:09 +0100 Subject: ARM: 6197/2: preliminary support for sparse IRQ So to allow NR_IRQS to be dynamic and platforms to specify the number of IRQs really needed. Acked-by: Paul Mundt Signed-off-by: Eric Miao Signed-off-by: Russell King --- arch/arm/Kconfig | 12 ++++++++++++ arch/arm/include/asm/irq.h | 2 ++ arch/arm/include/asm/mach/arch.h | 1 + arch/arm/include/asm/mach/irq.h | 1 + arch/arm/kernel/irq.c | 41 ++++++++++++++++++++++++++-------------- arch/arm/kernel/setup.c | 1 + 6 files changed, 44 insertions(+), 14 deletions(-) (limited to 'arch/arm/include') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 1f254bd6c937..9a0ed364d4f7 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -1289,6 +1289,18 @@ config HW_PERF_EVENTS Enable hardware performance counter support for perf events. If disabled, perf events will use software events only. +config SPARSE_IRQ + bool "Support sparse irq numbering" + depends on EXPERIMENTAL + help + This enables support for sparse irqs. This is useful in general + as most CPUs have a fairly sparse array of IRQ vectors, which + the irq_desc then maps directly on to. Systems with a high + number of off-chip IRQs will want to treat this as + experimental until they have been independently verified. + + If you don't know what to do here, say N. + source "mm/Kconfig" config LEDS diff --git a/arch/arm/include/asm/irq.h b/arch/arm/include/asm/irq.h index 237282f7c762..2721a5814cb9 100644 --- a/arch/arm/include/asm/irq.h +++ b/arch/arm/include/asm/irq.h @@ -7,6 +7,8 @@ #define irq_canonicalize(i) (i) #endif +#define NR_IRQS_LEGACY 16 + /* * Use this value to indicate lack of interrupt * capability diff --git a/arch/arm/include/asm/mach/arch.h b/arch/arm/include/asm/mach/arch.h index c59842dc7cb8..5ee6f85236a4 100644 --- a/arch/arm/include/asm/mach/arch.h +++ b/arch/arm/include/asm/mach/arch.h @@ -20,6 +20,7 @@ struct machine_desc { * by assembler code in head.S, head-common.S */ unsigned int nr; /* architecture number */ + unsigned int nr_irqs; /* number of IRQs */ unsigned int phys_io; /* start of physical io */ unsigned int io_pg_offst; /* byte offset for io * page tabe entry */ diff --git a/arch/arm/include/asm/mach/irq.h b/arch/arm/include/asm/mach/irq.h index 8920b2d6e3b8..ce3eee9fe26c 100644 --- a/arch/arm/include/asm/mach/irq.h +++ b/arch/arm/include/asm/mach/irq.h @@ -17,6 +17,7 @@ struct seq_file; /* * This is internal. Do not use it. */ +extern unsigned int arch_nr_irqs; extern void (*init_arch_irq)(void); extern void init_FIQ(void); extern int show_fiq_list(struct seq_file *, void *); diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c index 3b3d2c80509c..c0d5c3b3a760 100644 --- a/arch/arm/kernel/irq.c +++ b/arch/arm/kernel/irq.c @@ -47,12 +47,14 @@ #define irq_finish(irq) do { } while (0) #endif +unsigned int arch_nr_irqs; void (*init_arch_irq)(void) __initdata = NULL; unsigned long irq_err_count; int show_interrupts(struct seq_file *p, void *v) { int i = *(loff_t *) v, cpu; + struct irq_desc *desc; struct irqaction * action; unsigned long flags; @@ -67,24 +69,25 @@ int show_interrupts(struct seq_file *p, void *v) seq_putc(p, '\n'); } - if (i < NR_IRQS) { - raw_spin_lock_irqsave(&irq_desc[i].lock, flags); - action = irq_desc[i].action; + if (i < nr_irqs) { + desc = irq_to_desc(i); + raw_spin_lock_irqsave(&desc->lock, flags); + action = desc->action; if (!action) goto unlock; seq_printf(p, "%3d: ", i); for_each_present_cpu(cpu) seq_printf(p, "%10u ", kstat_irqs_cpu(i, cpu)); - seq_printf(p, " %10s", irq_desc[i].chip->name ? : "-"); + seq_printf(p, " %10s", desc->chip->name ? : "-"); seq_printf(p, " %s", action->name); for (action = action->next; action; action = action->next) seq_printf(p, ", %s", action->name); seq_putc(p, '\n'); unlock: - raw_spin_unlock_irqrestore(&irq_desc[i].lock, flags); - } else if (i == NR_IRQS) { + raw_spin_unlock_irqrestore(&desc->lock, flags); + } else if (i == nr_irqs) { #ifdef CONFIG_FIQ show_fiq_list(p, v); #endif @@ -112,7 +115,7 @@ asmlinkage void __exception asm_do_IRQ(unsigned int irq, struct pt_regs *regs) * Some hardware gives randomly wrong interrupts. Rather * than crashing, do something sensible. */ - if (unlikely(irq >= NR_IRQS)) { + if (unlikely(irq >= nr_irqs)) { if (printk_ratelimit()) printk(KERN_WARNING "Bad IRQ%u\n", irq); ack_bad_irq(irq); @@ -132,12 +135,12 @@ void set_irq_flags(unsigned int irq, unsigned int iflags) struct irq_desc *desc; unsigned long flags; - if (irq >= NR_IRQS) { + if (irq >= nr_irqs) { printk(KERN_ERR "Trying to set irq flags for IRQ%d\n", irq); return; } - desc = irq_desc + irq; + desc = irq_to_desc(irq); raw_spin_lock_irqsave(&desc->lock, flags); desc->status |= IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN; if (iflags & IRQF_VALID) @@ -151,14 +154,25 @@ void set_irq_flags(unsigned int irq, unsigned int iflags) void __init init_IRQ(void) { + struct irq_desc *desc; int irq; - for (irq = 0; irq < NR_IRQS; irq++) - irq_desc[irq].status |= IRQ_NOREQUEST | IRQ_NOPROBE; + for (irq = 0; irq < nr_irqs; irq++) { + desc = irq_to_desc_alloc_node(irq, 0); + desc->status |= IRQ_NOREQUEST | IRQ_NOPROBE; + } init_arch_irq(); } +#ifdef CONFIG_SPARSE_IRQ +int __init arch_probe_nr_irqs(void) +{ + nr_irqs = arch_nr_irqs ? arch_nr_irqs : NR_IRQS; + return 0; +} +#endif + #ifdef CONFIG_HOTPLUG_CPU static void route_irq(struct irq_desc *desc, unsigned int irq, unsigned int cpu) @@ -178,10 +192,9 @@ static void route_irq(struct irq_desc *desc, unsigned int irq, unsigned int cpu) void migrate_irqs(void) { unsigned int i, cpu = smp_processor_id(); + struct irq_desc *desc; - for (i = 0; i < NR_IRQS; i++) { - struct irq_desc *desc = irq_desc + i; - + for_each_irq_desc(i, desc) { if (desc->node == cpu) { unsigned int newcpu = cpumask_any_and(desc->affinity, cpu_online_mask); diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index 122d999bdc7c..7ae65dc594a4 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c @@ -729,6 +729,7 @@ void __init setup_arch(char **cmdline_p) /* * Set up various architecture-specific pointers */ + arch_nr_irqs = mdesc->nr_irqs; init_arch_irq = mdesc->init_irq; system_timer = mdesc->timer; init_machine = mdesc->init_machine; -- cgit v1.2.3 From e513f8bf240d34bd6e732ba2f74df9ab84686ce6 Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Fri, 25 Jun 2010 12:24:53 +0100 Subject: ARM: 6199/1: Add kprobe-based event tracer This patch enables the HAVE_REGS_AND_STACK_ACCESS_API option for ARM which is required by the kprobe events tracer. Code based on the PowerPC port. Cc: Jean Pihet Tested-by: Jamie Iles Signed-off-by: Will Deacon Signed-off-by: Russell King --- arch/arm/Kconfig | 1 + arch/arm/include/asm/ptrace.h | 36 ++++++++++++++++ arch/arm/kernel/ptrace.c | 96 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 133 insertions(+) (limited to 'arch/arm/include') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 9a0ed364d4f7..aa738aa70c78 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -24,6 +24,7 @@ config ARM select HAVE_KERNEL_LZMA select HAVE_PERF_EVENTS select PERF_USE_VMALLOC + select HAVE_REGS_AND_STACK_ACCESS_API help The ARM series is a line of low-power-consumption RISC chip designs licensed by ARM Ltd and targeted at embedded applications and diff --git a/arch/arm/include/asm/ptrace.h b/arch/arm/include/asm/ptrace.h index 9dcb11e59026..c974be8913a7 100644 --- a/arch/arm/include/asm/ptrace.h +++ b/arch/arm/include/asm/ptrace.h @@ -184,6 +184,42 @@ extern unsigned long profile_pc(struct pt_regs *regs); #define predicate(x) ((x) & 0xf0000000) #define PREDICATE_ALWAYS 0xe0000000 +/* + * kprobe-based event tracer support + */ +#include +#include +#define MAX_REG_OFFSET (offsetof(struct pt_regs, ARM_ORIG_r0)) + +extern int regs_query_register_offset(const char *name); +extern const char *regs_query_register_name(unsigned int offset); +extern bool regs_within_kernel_stack(struct pt_regs *regs, unsigned long addr); +extern unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs, + unsigned int n); + +/** + * regs_get_register() - get register value from its offset + * @regs: pt_regs from which register value is gotten + * @offset: offset number of the register. + * + * regs_get_register returns the value of a register whose offset from @regs. + * The @offset is the offset of the register in struct pt_regs. + * If @offset is bigger than MAX_REG_OFFSET, this returns 0. + */ +static inline unsigned long regs_get_register(struct pt_regs *regs, + unsigned int offset) +{ + if (unlikely(offset > MAX_REG_OFFSET)) + return 0; + return *(unsigned long *)((unsigned long)regs + offset); +} + +/* Valid only for Kernel mode traps. */ +static inline unsigned long kernel_stack_pointer(struct pt_regs *regs) +{ + return regs->ARM_sp; +} + #endif /* __KERNEL__ */ #endif /* __ASSEMBLY__ */ diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c index 3f562a7c0a99..f99d489822d5 100644 --- a/arch/arm/kernel/ptrace.c +++ b/arch/arm/kernel/ptrace.c @@ -52,6 +52,102 @@ #define BREAKINST_THUMB 0xde01 #endif +struct pt_regs_offset { + const char *name; + int offset; +}; + +#define REG_OFFSET_NAME(r) \ + {.name = #r, .offset = offsetof(struct pt_regs, ARM_##r)} +#define REG_OFFSET_END {.name = NULL, .offset = 0} + +static const struct pt_regs_offset regoffset_table[] = { + REG_OFFSET_NAME(r0), + REG_OFFSET_NAME(r1), + REG_OFFSET_NAME(r2), + REG_OFFSET_NAME(r3), + REG_OFFSET_NAME(r4), + REG_OFFSET_NAME(r5), + REG_OFFSET_NAME(r6), + REG_OFFSET_NAME(r7), + REG_OFFSET_NAME(r8), + REG_OFFSET_NAME(r9), + REG_OFFSET_NAME(r10), + REG_OFFSET_NAME(fp), + REG_OFFSET_NAME(ip), + REG_OFFSET_NAME(sp), + REG_OFFSET_NAME(lr), + REG_OFFSET_NAME(pc), + REG_OFFSET_NAME(cpsr), + REG_OFFSET_NAME(ORIG_r0), + REG_OFFSET_END, +}; + +/** + * regs_query_register_offset() - query register offset from its name + * @name: the name of a register + * + * regs_query_register_offset() returns the offset of a register in struct + * pt_regs from its name. If the name is invalid, this returns -EINVAL; + */ +int regs_query_register_offset(const char *name) +{ + const struct pt_regs_offset *roff; + for (roff = regoffset_table; roff->name != NULL; roff++) + if (!strcmp(roff->name, name)) + return roff->offset; + return -EINVAL; +} + +/** + * regs_query_register_name() - query register name from its offset + * @offset: the offset of a register in struct pt_regs. + * + * regs_query_register_name() returns the name of a register from its + * offset in struct pt_regs. If the @offset is invalid, this returns NULL; + */ +const char *regs_query_register_name(unsigned int offset) +{ + const struct pt_regs_offset *roff; + for (roff = regoffset_table; roff->name != NULL; roff++) + if (roff->offset == offset) + return roff->name; + return NULL; +} + +/** + * regs_within_kernel_stack() - check the address in the stack + * @regs: pt_regs which contains kernel stack pointer. + * @addr: address which is checked. + * + * regs_within_kernel_stack() checks @addr is within the kernel stack page(s). + * If @addr is within the kernel stack, it returns true. If not, returns false. + */ +bool regs_within_kernel_stack(struct pt_regs *regs, unsigned long addr) +{ + return ((addr & ~(THREAD_SIZE - 1)) == + (kernel_stack_pointer(regs) & ~(THREAD_SIZE - 1))); +} + +/** + * regs_get_kernel_stack_nth() - get Nth entry of the stack + * @regs: pt_regs which contains kernel stack pointer. + * @n: stack entry number. + * + * regs_get_kernel_stack_nth() returns @n th entry of the kernel stack which + * is specified by @regs. If the @n th entry is NOT in the kernel stack, + * this returns 0. + */ +unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs, unsigned int n) +{ + unsigned long *addr = (unsigned long *)kernel_stack_pointer(regs); + addr += n; + if (regs_within_kernel_stack(regs, (unsigned long)addr)) + return *addr; + else + return 0; +} + /* * this routine will get a word off of the processes privileged stack. * the offset is how far from the base addr as stored in the THREAD. -- cgit v1.2.3 From 5aaf254409f8d58229107b59507a8235b715a960 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Thu, 1 Jul 2010 13:41:05 +0100 Subject: ARM: 6203/1: Make VFPv3 usable on ARMv6 MVFR0 and MVFR1 are only available starting with ARM1136 r1p0 release according to "B.5 VFP changes" in DDI0211F_arm1136_r1p0_trm.pdf. This is also when TLS register got added, so we can use HAS_TLS also to test for MVFR0 and MVFR1. Otherwise VFPFMRX and VFPFMXR access fails and we get: Internal error: Oops - undefined instruction: 0 [#1] PC is at no_old_VFP_process+0x8/0x3c LR is at __und_svc+0x48/0x80 ... Signed-off-by: Tony Lindgren Acked-by: Catalin Marinas Signed-off-by: Russell King --- arch/arm/include/asm/vfpmacros.h | 18 ++++++++++++++++++ arch/arm/vfp/vfpmodule.c | 10 +++++++--- 2 files changed, 25 insertions(+), 3 deletions(-) (limited to 'arch/arm/include') diff --git a/arch/arm/include/asm/vfpmacros.h b/arch/arm/include/asm/vfpmacros.h index 422f3cc204a2..3d5fc41ae8d3 100644 --- a/arch/arm/include/asm/vfpmacros.h +++ b/arch/arm/include/asm/vfpmacros.h @@ -3,6 +3,8 @@ * * Assembler-only file containing VFP macros and register definitions. */ +#include + #include "vfp.h" @ Macros to allow building with old toolkits (with no VFP support) @@ -22,11 +24,19 @@ LDC p11, cr0, [\base],#32*4 @ FLDMIAD \base!, {d0-d15} #endif #ifdef CONFIG_VFPv3 +#if __LINUX_ARM_ARCH__ <= 6 + ldr \tmp, =elf_hwcap @ may not have MVFR regs + ldr \tmp, [\tmp, #0] + tst \tmp, #HWCAP_VFPv3D16 + ldceq p11, cr0, [\base],#32*4 @ FLDMIAD \base!, {d16-d31} + addne \base, \base, #32*4 @ step over unused register space +#else VFPFMRX \tmp, MVFR0 @ Media and VFP Feature Register 0 and \tmp, \tmp, #MVFR0_A_SIMD_MASK @ A_SIMD field cmp \tmp, #2 @ 32 x 64bit registers? ldceql p11, cr0, [\base],#32*4 @ FLDMIAD \base!, {d16-d31} addne \base, \base, #32*4 @ step over unused register space +#endif #endif .endm @@ -38,10 +48,18 @@ STC p11, cr0, [\base],#32*4 @ FSTMIAD \base!, {d0-d15} #endif #ifdef CONFIG_VFPv3 +#if __LINUX_ARM_ARCH__ <= 6 + ldr \tmp, =elf_hwcap @ may not have MVFR regs + ldr \tmp, [\tmp, #0] + tst \tmp, #HWCAP_VFPv3D16 + stceq p11, cr0, [\base],#32*4 @ FSTMIAD \base!, {d16-d31} + addne \base, \base, #32*4 @ step over unused register space +#else VFPFMRX \tmp, MVFR0 @ Media and VFP Feature Register 0 and \tmp, \tmp, #MVFR0_A_SIMD_MASK @ A_SIMD field cmp \tmp, #2 @ 32 x 64bit registers? stceql p11, cr0, [\base],#32*4 @ FSTMIAD \base!, {d16-d31} addne \base, \base, #32*4 @ step over unused register space +#endif #endif .endm diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c index 315a540c7ce5..8063a322c790 100644 --- a/arch/arm/vfp/vfpmodule.c +++ b/arch/arm/vfp/vfpmodule.c @@ -15,6 +15,7 @@ #include #include +#include #include #include @@ -549,10 +550,13 @@ static int __init vfp_init(void) /* * Check for the presence of the Advanced SIMD * load/store instructions, integer and single - * precision floating point operations. + * precision floating point operations. Only check + * for NEON if the hardware has the MVFR registers. */ - if ((fmrx(MVFR1) & 0x000fff00) == 0x00011100) - elf_hwcap |= HWCAP_NEON; + if ((read_cpuid_id() & 0x000f0000) == 0x000f0000) { + if ((fmrx(MVFR1) & 0x000fff00) == 0x00011100) + elf_hwcap |= HWCAP_NEON; + } #endif } return 0; -- cgit v1.2.3 From f159f4ed55bb0fa5470800641e03a13a7e0eae6e Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Mon, 5 Jul 2010 14:53:10 +0100 Subject: ARM: 6207/1: Replace CONFIG_HAS_TLS_REG with HWCAP_TLS and check for it on V6 The TLS register is only available on ARM1136 r1p0 and later. Set HWCAP_TLS flags if hardware TLS is available and test for it if CONFIG_CPU_32v6K is not set for V6. Note that we set the TLS instruction in __kuser_get_tls dynamically as suggested by Jamie Lokier . Also the __switch_to code is optimized out in most cases as suggested by Nicolas Pitre . Reviewed-by: Nicolas Pitre Signed-off-by: Tony Lindgren Signed-off-by: Russell King --- arch/arm/include/asm/hwcap.h | 1 + arch/arm/include/asm/tls.h | 46 ++++++++++++++++++++++++++++++++++++++++++++ arch/arm/kernel/entry-armv.S | 23 +++++++--------------- arch/arm/kernel/setup.c | 17 ++++++++++++++++ arch/arm/kernel/traps.c | 41 ++++++++++++++++++++++++++++----------- arch/arm/mm/Kconfig | 11 ----------- arch/arm/mm/proc-v6.S | 5 +++-- arch/arm/mm/proc-v7.S | 2 +- 8 files changed, 105 insertions(+), 41 deletions(-) create mode 100644 arch/arm/include/asm/tls.h (limited to 'arch/arm/include') diff --git a/arch/arm/include/asm/hwcap.h b/arch/arm/include/asm/hwcap.h index f7bd52b1c365..c1062c317103 100644 --- a/arch/arm/include/asm/hwcap.h +++ b/arch/arm/include/asm/hwcap.h @@ -19,6 +19,7 @@ #define HWCAP_NEON 4096 #define HWCAP_VFPv3 8192 #define HWCAP_VFPv3D16 16384 +#define HWCAP_TLS 32768 #if defined(__KERNEL__) && !defined(__ASSEMBLY__) /* diff --git a/arch/arm/include/asm/tls.h b/arch/arm/include/asm/tls.h new file mode 100644 index 000000000000..e71d6ff8d104 --- /dev/null +++ b/arch/arm/include/asm/tls.h @@ -0,0 +1,46 @@ +#ifndef __ASMARM_TLS_H +#define __ASMARM_TLS_H + +#ifdef __ASSEMBLY__ + .macro set_tls_none, tp, tmp1, tmp2 + .endm + + .macro set_tls_v6k, tp, tmp1, tmp2 + mcr p15, 0, \tp, c13, c0, 3 @ set TLS register + .endm + + .macro set_tls_v6, tp, tmp1, tmp2 + ldr \tmp1, =elf_hwcap + ldr \tmp1, [\tmp1, #0] + mov \tmp2, #0xffff0fff + tst \tmp1, #HWCAP_TLS @ hardware TLS available? + mcrne p15, 0, \tp, c13, c0, 3 @ yes, set TLS register + streq \tp, [\tmp2, #-15] @ set TLS value at 0xffff0ff0 + .endm + + .macro set_tls_software, tp, tmp1, tmp2 + mov \tmp1, #0xffff0fff + str \tp, [\tmp1, #-15] @ set TLS value at 0xffff0ff0 + .endm +#endif + +#ifdef CONFIG_TLS_REG_EMUL +#define tls_emu 1 +#define has_tls_reg 1 +#define set_tls set_tls_none +#elif __LINUX_ARM_ARCH__ >= 7 || \ + (__LINUX_ARM_ARCH__ == 6 && defined(CONFIG_CPU_32v6K)) +#define tls_emu 0 +#define has_tls_reg 1 +#define set_tls set_tls_v6k +#elif __LINUX_ARM_ARCH__ == 6 +#define tls_emu 0 +#define has_tls_reg (elf_hwcap & HWCAP_TLS) +#define set_tls set_tls_v6 +#else +#define tls_emu 0 +#define has_tls_reg 0 +#define set_tls set_tls_software +#endif + +#endif /* __ASMARM_TLS_H */ diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S index 7ee48e7f8f31..a6cfb1791af3 100644 --- a/arch/arm/kernel/entry-armv.S +++ b/arch/arm/kernel/entry-armv.S @@ -22,6 +22,7 @@ #include #include #include +#include #include "entry-header.S" @@ -739,12 +740,7 @@ ENTRY(__switch_to) #ifdef CONFIG_MMU ldr r6, [r2, #TI_CPU_DOMAIN] #endif -#if defined(CONFIG_HAS_TLS_REG) - mcr p15, 0, r3, c13, c0, 3 @ set TLS register -#elif !defined(CONFIG_TLS_REG_EMUL) - mov r4, #0xffff0fff - str r3, [r4, #-15] @ TLS val at 0xffff0ff0 -#endif + set_tls r3, r4, r5 #ifdef CONFIG_MMU mcr p15, 0, r6, c3, c0, 0 @ Set domain register #endif @@ -1009,17 +1005,12 @@ kuser_cmpxchg_fixup: */ __kuser_get_tls: @ 0xffff0fe0 - -#if !defined(CONFIG_HAS_TLS_REG) && !defined(CONFIG_TLS_REG_EMUL) - ldr r0, [pc, #(16 - 8)] @ TLS stored at 0xffff0ff0 -#else - mrc p15, 0, r0, c13, c0, 3 @ read TLS register -#endif + ldr r0, [pc, #(16 - 8)] @ read TLS, set in kuser_get_tls_init usr_ret lr - - .rep 5 - .word 0 @ pad up to __kuser_helper_version - .endr + mrc p15, 0, r0, c13, c0, 3 @ 0xffff0fe8 hardware TLS code + .rep 4 + .word 0 @ 0xffff0ff0 software TLS value, then + .endr @ pad up to __kuser_helper_version /* * Reference declaration: diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index 7ae65dc594a4..648c3c1e16c4 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c @@ -269,6 +269,21 @@ static void __init cacheid_init(void) extern struct proc_info_list *lookup_processor_type(unsigned int); extern struct machine_desc *lookup_machine_type(unsigned int); +static void __init feat_v6_fixup(void) +{ + int id = read_cpuid_id(); + + if ((id & 0xff0f0000) != 0x41070000) + return; + + /* + * HWCAP_TLS is available only on 1136 r1p0 and later, + * see also kuser_get_tls_init. + */ + if ((((id >> 4) & 0xfff) == 0xb36) && (((id >> 20) & 3) == 0)) + elf_hwcap &= ~HWCAP_TLS; +} + static void __init setup_processor(void) { struct proc_info_list *list; @@ -311,6 +326,8 @@ static void __init setup_processor(void) elf_hwcap &= ~HWCAP_THUMB; #endif + feat_v6_fixup(); + cacheid_init(); cpu_proc_init(); } diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c index 1621e5327b2a..cda78d59aa31 100644 --- a/arch/arm/kernel/traps.c +++ b/arch/arm/kernel/traps.c @@ -30,6 +30,7 @@ #include #include #include +#include #include "ptrace.h" #include "signal.h" @@ -518,17 +519,20 @@ asmlinkage int arm_syscall(int no, struct pt_regs *regs) case NR(set_tls): thread->tp_value = regs->ARM_r0; -#if defined(CONFIG_HAS_TLS_REG) - asm ("mcr p15, 0, %0, c13, c0, 3" : : "r" (regs->ARM_r0) ); -#elif !defined(CONFIG_TLS_REG_EMUL) - /* - * User space must never try to access this directly. - * Expect your app to break eventually if you do so. - * The user helper at 0xffff0fe0 must be used instead. - * (see entry-armv.S for details) - */ - *((unsigned int *)0xffff0ff0) = regs->ARM_r0; -#endif + if (tls_emu) + return 0; + if (has_tls_reg) { + asm ("mcr p15, 0, %0, c13, c0, 3" + : : "r" (regs->ARM_r0)); + } else { + /* + * User space must never try to access this directly. + * Expect your app to break eventually if you do so. + * The user helper at 0xffff0fe0 must be used instead. + * (see entry-armv.S for details) + */ + *((unsigned int *)0xffff0ff0) = regs->ARM_r0; + } return 0; #ifdef CONFIG_NEEDS_SYSCALL_FOR_CMPXCHG @@ -743,6 +747,16 @@ void __init trap_init(void) return; } +static void __init kuser_get_tls_init(unsigned long vectors) +{ + /* + * vectors + 0xfe0 = __kuser_get_tls + * vectors + 0xfe8 = hardware TLS instruction at 0xffff0fe8 + */ + if (tls_emu || has_tls_reg) + memcpy((void *)vectors + 0xfe0, (void *)vectors + 0xfe8, 4); +} + void __init early_trap_init(void) { unsigned long vectors = CONFIG_VECTORS_BASE; @@ -760,6 +774,11 @@ void __init early_trap_init(void) memcpy((void *)vectors + 0x200, __stubs_start, __stubs_end - __stubs_start); memcpy((void *)vectors + 0x1000 - kuser_sz, __kuser_helper_start, kuser_sz); + /* + * Do processor specific fixups for the kuser helpers + */ + kuser_get_tls_init(vectors); + /* * Copy signal return handlers into the vector page, and * set sigreturn to be a pointer to these. diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig index 346ae14824a5..71d5d5efceef 100644 --- a/arch/arm/mm/Kconfig +++ b/arch/arm/mm/Kconfig @@ -717,17 +717,6 @@ config TLS_REG_EMUL a few prototypes like that in existence) and therefore access to that required register must be emulated. -config HAS_TLS_REG - bool - depends on !TLS_REG_EMUL - default y if SMP || CPU_32v7 - help - This selects support for the CP15 thread register. - It is defined to be available on some ARMv6 processors (including - all SMP capable ARMv6's) or later processors. User space may - assume directly accessing that register and always obtain the - expected value only on ARMv7 and above. - config NEEDS_SYSCALL_FOR_CMPXCHG bool help diff --git a/arch/arm/mm/proc-v6.S b/arch/arm/mm/proc-v6.S index 7a5337ed7d68..2f5a3c23a0fe 100644 --- a/arch/arm/mm/proc-v6.S +++ b/arch/arm/mm/proc-v6.S @@ -239,7 +239,8 @@ __v6_proc_info: b __v6_setup .long cpu_arch_name .long cpu_elf_name - .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP|HWCAP_JAVA + /* See also feat_v6_fixup() for HWCAP_TLS */ + .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP|HWCAP_JAVA|HWCAP_TLS .long cpu_v6_name .long v6_processor_functions .long v6wbi_tlb_fns @@ -262,7 +263,7 @@ __pj4_v6_proc_info: b __v6_setup .long cpu_arch_name .long cpu_elf_name - .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP + .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP|HWCAP_TLS .long cpu_pj4_name .long v6_processor_functions .long v6wbi_tlb_fns diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S index 7aaf88a3b7aa..8071bcd4c995 100644 --- a/arch/arm/mm/proc-v7.S +++ b/arch/arm/mm/proc-v7.S @@ -344,7 +344,7 @@ __v7_proc_info: b __v7_setup .long cpu_arch_name .long cpu_elf_name - .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP + .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP|HWCAP_TLS .long cpu_v7_name .long v7_processor_functions .long v7wbi_tlb_fns -- cgit v1.2.3 From 24b776bfb6396fded148167643ffaf8eb3f782b1 Mon Sep 17 00:00:00 2001 From: Mika Westerberg Date: Mon, 10 May 2010 09:22:14 +0100 Subject: ARM: 6117/1: kdump: implement crash_setup_regs() Implement machine specific function crash_setup_regs() which is responsible for storing machine state when crash occured. Signed-off-by: Mika Westerberg Signed-off-by: Russell King --- arch/arm/include/asm/kexec.h | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) (limited to 'arch/arm/include') diff --git a/arch/arm/include/asm/kexec.h b/arch/arm/include/asm/kexec.h index df15a0dc228e..8ec9ef5c3c7b 100644 --- a/arch/arm/include/asm/kexec.h +++ b/arch/arm/include/asm/kexec.h @@ -19,10 +19,26 @@ #ifndef __ASSEMBLY__ -struct kimage; -/* Provide a dummy definition to avoid build failures. */ +/** + * crash_setup_regs() - save registers for the panic kernel + * @newregs: registers are saved here + * @oldregs: registers to be saved (may be %NULL) + * + * Function copies machine registers from @oldregs to @newregs. If @oldregs is + * %NULL then current registers are stored there. + */ static inline void crash_setup_regs(struct pt_regs *newregs, - struct pt_regs *oldregs) { } + struct pt_regs *oldregs) +{ + if (oldregs) { + memcpy(newregs, oldregs, sizeof(*newregs)); + } else { + __asm__ __volatile__ ("stmia %0, {r0 - r15}" + : : "r" (&newregs->ARM_r0)); + __asm__ __volatile__ ("mrs %0, cpsr" + : "=r" (newregs->ARM_cpsr)); + } +} #endif /* __ASSEMBLY__ */ -- cgit v1.2.3 From be370302742ff9948f2a42b15cb2ba174d97b930 Mon Sep 17 00:00:00 2001 From: Russell King Date: Fri, 7 May 2010 17:40:33 +0100 Subject: ARM: Remove DISCONTIGMEM support Everything should now be using sparsemem rather than discontigmem, so remove the code supporting discontigmem from ARM. Signed-off-by: Russell King --- arch/arm/Kconfig | 13 +- arch/arm/include/asm/memory.h | 65 ------- arch/arm/include/asm/mmzone.h | 30 --- arch/arm/include/asm/setup.h | 8 +- arch/arm/kernel/setup.c | 3 +- arch/arm/mach-aaec2000/include/mach/memory.h | 10 - arch/arm/mach-clps711x/Kconfig | 1 - arch/arm/mach-clps711x/clep7312.c | 1 - arch/arm/mach-clps711x/edb7211-arch.c | 2 - arch/arm/mach-clps711x/fortunet.c | 1 - arch/arm/mach-clps711x/include/mach/memory.h | 2 - arch/arm/mach-iop13xx/include/mach/memory.h | 2 - arch/arm/mach-lh7a40x/include/mach/memory.h | 44 ----- arch/arm/mach-msm/board-trout.c | 1 - arch/arm/mach-pxa/corgi.c | 1 - arch/arm/mach-pxa/eseries.c | 1 - arch/arm/mach-pxa/generic.h | 3 +- arch/arm/mach-pxa/include/mach/memory.h | 12 -- arch/arm/mach-pxa/poodle.c | 1 - arch/arm/mach-pxa/spitz.c | 1 - arch/arm/mach-pxa/tosa.c | 1 - arch/arm/mach-s3c2412/mach-smdk2413.c | 1 - arch/arm/mach-s3c2412/mach-vstms.c | 1 - arch/arm/mach-sa1100/generic.h | 3 +- arch/arm/mm/Makefile | 1 - arch/arm/mm/discontig.c | 45 ----- arch/arm/mm/init.c | 266 ++++++++++++--------------- arch/arm/mm/mm.h | 4 +- arch/arm/mm/mmu.c | 38 ++-- arch/arm/mm/nommu.c | 13 +- 30 files changed, 143 insertions(+), 432 deletions(-) delete mode 100644 arch/arm/include/asm/mmzone.h delete mode 100644 arch/arm/mm/discontig.c (limited to 'arch/arm/include') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 98922f7d2d12..410edd65f117 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -719,7 +719,6 @@ config ARCH_SHARK config ARCH_LH7A40X bool "Sharp LH7A40X" select CPU_ARM922T - select ARCH_DISCONTIGMEM_ENABLE if !LH7A40X_CONTIGMEM select ARCH_SPARSEMEM_ENABLE if !LH7A40X_CONTIGMEM select ARCH_USES_GETTIMEOFFSET help @@ -1241,10 +1240,6 @@ config OABI_COMPAT config ARCH_HAS_HOLES_MEMORYMODEL bool -# Discontigmem is deprecated -config ARCH_DISCONTIGMEM_ENABLE - bool - config ARCH_SPARSEMEM_ENABLE bool @@ -1252,13 +1247,7 @@ config ARCH_SPARSEMEM_DEFAULT def_bool ARCH_SPARSEMEM_ENABLE config ARCH_SELECT_MEMORY_MODEL - def_bool ARCH_DISCONTIGMEM_ENABLE && ARCH_SPARSEMEM_ENABLE - -config NODES_SHIFT - int - default "4" if ARCH_LH7A40X - default "2" - depends on NEED_MULTIPLE_NODES + def_bool ARCH_SPARSEMEM_ENABLE config HIGHMEM bool "High Memory Support (EXPERIMENTAL)" diff --git a/arch/arm/include/asm/memory.h b/arch/arm/include/asm/memory.h index 4312ee5e3d0b..e263ec7c5dcb 100644 --- a/arch/arm/include/asm/memory.h +++ b/arch/arm/include/asm/memory.h @@ -234,76 +234,11 @@ static inline __deprecated void *bus_to_virt(unsigned long x) * virt_to_page(k) convert a _valid_ virtual address to struct page * * virt_addr_valid(k) indicates whether a virtual address is valid */ -#ifndef CONFIG_DISCONTIGMEM - #define ARCH_PFN_OFFSET PHYS_PFN_OFFSET #define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT) #define virt_addr_valid(kaddr) ((unsigned long)(kaddr) >= PAGE_OFFSET && (unsigned long)(kaddr) < (unsigned long)high_memory) -#define PHYS_TO_NID(addr) (0) - -#else /* CONFIG_DISCONTIGMEM */ - -/* - * This is more complex. We have a set of mem_map arrays spread - * around in memory. - */ -#include - -#define arch_pfn_to_nid(pfn) PFN_TO_NID(pfn) -#define arch_local_page_offset(pfn, nid) LOCAL_MAP_NR((pfn) << PAGE_SHIFT) - -#define virt_to_page(kaddr) \ - (ADDR_TO_MAPBASE(kaddr) + LOCAL_MAP_NR(kaddr)) - -#define virt_addr_valid(kaddr) (KVADDR_TO_NID(kaddr) < MAX_NUMNODES) - -/* - * Common discontigmem stuff. - * PHYS_TO_NID is used by the ARM kernel/setup.c - */ -#define PHYS_TO_NID(addr) PFN_TO_NID((addr) >> PAGE_SHIFT) - -/* - * Given a kaddr, ADDR_TO_MAPBASE finds the owning node of the memory - * and returns the mem_map of that node. - */ -#define ADDR_TO_MAPBASE(kaddr) NODE_MEM_MAP(KVADDR_TO_NID(kaddr)) - -/* - * Given a page frame number, find the owning node of the memory - * and returns the mem_map of that node. - */ -#define PFN_TO_MAPBASE(pfn) NODE_MEM_MAP(PFN_TO_NID(pfn)) - -#ifdef NODE_MEM_SIZE_BITS -#define NODE_MEM_SIZE_MASK ((1 << NODE_MEM_SIZE_BITS) - 1) - -/* - * Given a kernel address, find the home node of the underlying memory. - */ -#define KVADDR_TO_NID(addr) \ - (((unsigned long)(addr) - PAGE_OFFSET) >> NODE_MEM_SIZE_BITS) - -/* - * Given a page frame number, convert it to a node id. - */ -#define PFN_TO_NID(pfn) \ - (((pfn) - PHYS_PFN_OFFSET) >> (NODE_MEM_SIZE_BITS - PAGE_SHIFT)) - -/* - * Given a kaddr, LOCAL_MEM_MAP finds the owning node of the memory - * and returns the index corresponding to the appropriate page in the - * node's mem_map. - */ -#define LOCAL_MAP_NR(addr) \ - (((unsigned long)(addr) & NODE_MEM_SIZE_MASK) >> PAGE_SHIFT) - -#endif /* NODE_MEM_SIZE_BITS */ - -#endif /* !CONFIG_DISCONTIGMEM */ - /* * Optional coherency support. Currently used only by selected * Intel XSC3-based systems. diff --git a/arch/arm/include/asm/mmzone.h b/arch/arm/include/asm/mmzone.h deleted file mode 100644 index ae63a4fd28c8..000000000000 --- a/arch/arm/include/asm/mmzone.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * arch/arm/include/asm/mmzone.h - * - * 1999-12-29 Nicolas Pitre Created - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#ifndef __ASM_MMZONE_H -#define __ASM_MMZONE_H - -/* - * Currently defined in arch/arm/mm/discontig.c - */ -extern pg_data_t discontig_node_data[]; - -/* - * Return a pointer to the node data for node n. - */ -#define NODE_DATA(nid) (&discontig_node_data[nid]) - -/* - * NODE_MEM_MAP gives the kaddr for the mem_map of the node. - */ -#define NODE_MEM_MAP(nid) (NODE_DATA(nid)->node_mem_map) - -#include - -#endif diff --git a/arch/arm/include/asm/setup.h b/arch/arm/include/asm/setup.h index f392fb4437af..f1e5a9bca249 100644 --- a/arch/arm/include/asm/setup.h +++ b/arch/arm/include/asm/setup.h @@ -201,8 +201,7 @@ static struct tagtable __tagtable_##fn __tag = { tag, fn } struct membank { unsigned long start; unsigned long size; - unsigned short node; - unsigned short highmem; + unsigned int highmem; }; struct meminfo { @@ -212,9 +211,8 @@ struct meminfo { extern struct meminfo meminfo; -#define for_each_nodebank(iter,mi,no) \ - for (iter = 0; iter < (mi)->nr_banks; iter++) \ - if ((mi)->bank[iter].node == no) +#define for_each_bank(iter,mi) \ + for (iter = 0; iter < (mi)->nr_banks; iter++) #define bank_pfn_start(bank) __phys_to_pfn((bank)->start) #define bank_pfn_end(bank) __phys_to_pfn((bank)->start + (bank)->size) diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index 122d999bdc7c..387d2e9cb51f 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c @@ -402,13 +402,12 @@ static int __init arm_add_memory(unsigned long start, unsigned long size) size -= start & ~PAGE_MASK; bank->start = PAGE_ALIGN(start); bank->size = size & PAGE_MASK; - bank->node = PHYS_TO_NID(start); /* * Check whether this memory region has non-zero size or * invalid node number. */ - if (bank->size == 0 || bank->node >= MAX_NUMNODES) + if (bank->size == 0) return -EINVAL; meminfo.nr_banks++; diff --git a/arch/arm/mach-aaec2000/include/mach/memory.h b/arch/arm/mach-aaec2000/include/mach/memory.h index c00822543d9f..4f93c567a35a 100644 --- a/arch/arm/mach-aaec2000/include/mach/memory.h +++ b/arch/arm/mach-aaec2000/include/mach/memory.h @@ -14,14 +14,4 @@ #define PHYS_OFFSET UL(0xf0000000) -/* - * The nodes are the followings: - * - * node 0: 0xf000.0000 - 0xf3ff.ffff - * node 1: 0xf400.0000 - 0xf7ff.ffff - * node 2: 0xf800.0000 - 0xfbff.ffff - * node 3: 0xfc00.0000 - 0xffff.ffff - */ -#define NODE_MEM_SIZE_BITS 26 - #endif /* __ASM_ARCH_MEMORY_H */ diff --git a/arch/arm/mach-clps711x/Kconfig b/arch/arm/mach-clps711x/Kconfig index dbaae5f746a1..eb34bd1251d4 100644 --- a/arch/arm/mach-clps711x/Kconfig +++ b/arch/arm/mach-clps711x/Kconfig @@ -30,7 +30,6 @@ config ARCH_CLEP7312 config ARCH_EDB7211 bool "EDB7211" select ISA - select ARCH_DISCONTIGMEM_ENABLE select ARCH_SPARSEMEM_ENABLE select ARCH_SELECT_MEMORY_MODEL help diff --git a/arch/arm/mach-clps711x/clep7312.c b/arch/arm/mach-clps711x/clep7312.c index 09fb57e45213..3c3bf45039ff 100644 --- a/arch/arm/mach-clps711x/clep7312.c +++ b/arch/arm/mach-clps711x/clep7312.c @@ -32,7 +32,6 @@ fixup_clep7312(struct machine_desc *desc, struct tag *tags, mi->nr_banks=1; mi->bank[0].start = 0xc0000000; mi->bank[0].size = 0x01000000; - mi->bank[0].node = 0; } diff --git a/arch/arm/mach-clps711x/edb7211-arch.c b/arch/arm/mach-clps711x/edb7211-arch.c index dc81cc68595d..41a4425617c1 100644 --- a/arch/arm/mach-clps711x/edb7211-arch.c +++ b/arch/arm/mach-clps711x/edb7211-arch.c @@ -43,10 +43,8 @@ fixup_edb7211(struct machine_desc *desc, struct tag *tags, */ mi->bank[0].start = 0xc0000000; mi->bank[0].size = 8*1024*1024; - mi->bank[0].node = 0; mi->bank[1].start = 0xc1000000; mi->bank[1].size = 8*1024*1024; - mi->bank[1].node = 1; mi->nr_banks = 2; } diff --git a/arch/arm/mach-clps711x/fortunet.c b/arch/arm/mach-clps711x/fortunet.c index 7430e4049d87..a696099aa4f8 100644 --- a/arch/arm/mach-clps711x/fortunet.c +++ b/arch/arm/mach-clps711x/fortunet.c @@ -39,7 +39,6 @@ struct meminfo memmap = { { .start = 0xC0000000, .size = 0x01000000, - .node = 0 }, }, }; diff --git a/arch/arm/mach-clps711x/include/mach/memory.h b/arch/arm/mach-clps711x/include/mach/memory.h index f70d52be48a2..f45c8e892cb5 100644 --- a/arch/arm/mach-clps711x/include/mach/memory.h +++ b/arch/arm/mach-clps711x/include/mach/memory.h @@ -20,7 +20,6 @@ #ifndef __ASM_ARCH_MEMORY_H #define __ASM_ARCH_MEMORY_H - /* * Physical DRAM offset. */ @@ -72,7 +71,6 @@ * node 2: 0xd0000000 - 0xd7ffffff * node 3: 0xd8000000 - 0xdfffffff */ -#define NODE_MEM_SIZE_BITS 24 #define SECTION_SIZE_BITS 24 #define MAX_PHYSMEM_BITS 32 diff --git a/arch/arm/mach-iop13xx/include/mach/memory.h b/arch/arm/mach-iop13xx/include/mach/memory.h index 25b1da9a5035..7415e4338651 100644 --- a/arch/arm/mach-iop13xx/include/mach/memory.h +++ b/arch/arm/mach-iop13xx/include/mach/memory.h @@ -69,6 +69,4 @@ static inline unsigned long __lbus_to_virt(dma_addr_t x) #endif /* CONFIG_ARCH_IOP13XX */ #endif /* !ASSEMBLY */ -#define PFN_TO_NID(addr) (0) - #endif diff --git a/arch/arm/mach-lh7a40x/include/mach/memory.h b/arch/arm/mach-lh7a40x/include/mach/memory.h index 189d20e543e7..edb8f5faf5d5 100644 --- a/arch/arm/mach-lh7a40x/include/mach/memory.h +++ b/arch/arm/mach-lh7a40x/include/mach/memory.h @@ -19,50 +19,6 @@ */ #define PHYS_OFFSET UL(0xc0000000) -#ifdef CONFIG_DISCONTIGMEM - -/* - * Given a kernel address, find the home node of the underlying memory. - */ - -# ifdef CONFIG_LH7A40X_ONE_BANK_PER_NODE -# define KVADDR_TO_NID(addr) \ - ( ((((unsigned long) (addr) - PAGE_OFFSET) >> 24) & 1)\ - | ((((unsigned long) (addr) - PAGE_OFFSET) >> 25) & ~1)) -# else /* 2 banks per node */ -# define KVADDR_TO_NID(addr) \ - (((unsigned long) (addr) - PAGE_OFFSET) >> 26) -# endif - -/* - * Given a page frame number, convert it to a node id. - */ - -# ifdef CONFIG_LH7A40X_ONE_BANK_PER_NODE -# define PFN_TO_NID(pfn) \ - (((((pfn) - PHYS_PFN_OFFSET) >> (24 - PAGE_SHIFT)) & 1)\ - | ((((pfn) - PHYS_PFN_OFFSET) >> (25 - PAGE_SHIFT)) & ~1)) -# else /* 2 banks per node */ -# define PFN_TO_NID(pfn) \ - (((pfn) - PHYS_PFN_OFFSET) >> (26 - PAGE_SHIFT)) -#endif - -/* - * Given a kaddr, LOCAL_MEM_MAP finds the owning node of the memory - * and returns the index corresponding to the appropriate page in the - * node's mem_map. - */ - -# ifdef CONFIG_LH7A40X_ONE_BANK_PER_NODE -# define LOCAL_MAP_NR(addr) \ - (((unsigned long)(addr) & 0x003fffff) >> PAGE_SHIFT) -# else /* 2 banks per node */ -# define LOCAL_MAP_NR(addr) \ - (((unsigned long)(addr) & 0x01ffffff) >> PAGE_SHIFT) -# endif - -#endif - /* * Sparsemem version of the above */ diff --git a/arch/arm/mach-msm/board-trout.c b/arch/arm/mach-msm/board-trout.c index dca5a5f062dc..e69a1502e4e8 100644 --- a/arch/arm/mach-msm/board-trout.c +++ b/arch/arm/mach-msm/board-trout.c @@ -50,7 +50,6 @@ static void __init trout_fixup(struct machine_desc *desc, struct tag *tags, { mi->nr_banks = 1; mi->bank[0].start = PHYS_OFFSET; - mi->bank[0].node = PHYS_TO_NID(PHYS_OFFSET); mi->bank[0].size = (101*1024*1024); } diff --git a/arch/arm/mach-pxa/corgi.c b/arch/arm/mach-pxa/corgi.c index 3d1dcb9ac08f..95234fb4fcf8 100644 --- a/arch/arm/mach-pxa/corgi.c +++ b/arch/arm/mach-pxa/corgi.c @@ -715,7 +715,6 @@ static void __init fixup_corgi(struct machine_desc *desc, sharpsl_save_param(); mi->nr_banks=1; mi->bank[0].start = 0xa0000000; - mi->bank[0].node = 0; if (machine_is_corgi()) mi->bank[0].size = (32*1024*1024); else diff --git a/arch/arm/mach-pxa/eseries.c b/arch/arm/mach-pxa/eseries.c index 96ed13081639..a0ab3082a000 100644 --- a/arch/arm/mach-pxa/eseries.c +++ b/arch/arm/mach-pxa/eseries.c @@ -34,7 +34,6 @@ void __init eseries_fixup(struct machine_desc *desc, { mi->nr_banks=1; mi->bank[0].start = 0xa0000000; - mi->bank[0].node = 0; if (machine_is_e800()) mi->bank[0].size = (128*1024*1024); else diff --git a/arch/arm/mach-pxa/generic.h b/arch/arm/mach-pxa/generic.h index 890fb90a672f..c6305c5b8a72 100644 --- a/arch/arm/mach-pxa/generic.h +++ b/arch/arm/mach-pxa/generic.h @@ -26,8 +26,7 @@ extern unsigned int get_clk_frequency_khz(int info); #define SET_BANK(__nr,__start,__size) \ mi->bank[__nr].start = (__start), \ - mi->bank[__nr].size = (__size), \ - mi->bank[__nr].node = (((unsigned)(__start) - PHYS_OFFSET) >> 27) + mi->bank[__nr].size = (__size) #define ARRAY_AND_SIZE(x) (x), ARRAY_SIZE(x) diff --git a/arch/arm/mach-pxa/include/mach/memory.h b/arch/arm/mach-pxa/include/mach/memory.h index f626730ee42e..81fd4a081c82 100644 --- a/arch/arm/mach-pxa/include/mach/memory.h +++ b/arch/arm/mach-pxa/include/mach/memory.h @@ -17,18 +17,6 @@ */ #define PHYS_OFFSET UL(0xa0000000) -/* - * The nodes are matched with the physical SDRAM banks as follows: - * - * node 0: 0xa0000000-0xa3ffffff --> 0xc0000000-0xc3ffffff - * node 1: 0xa4000000-0xa7ffffff --> 0xc4000000-0xc7ffffff - * node 2: 0xa8000000-0xabffffff --> 0xc8000000-0xcbffffff - * node 3: 0xac000000-0xafffffff --> 0xcc000000-0xcfffffff - * - * This needs a node mem size of 26 bits. - */ -#define NODE_MEM_SIZE_BITS 26 - #if !defined(__ASSEMBLY__) && defined(CONFIG_MACH_ARMCORE) && defined(CONFIG_PCI) void cmx2xx_pci_adjust_zones(int node, unsigned long *size, unsigned long *holes); diff --git a/arch/arm/mach-pxa/poodle.c b/arch/arm/mach-pxa/poodle.c index f4abdaafdac4..bc2758b54446 100644 --- a/arch/arm/mach-pxa/poodle.c +++ b/arch/arm/mach-pxa/poodle.c @@ -463,7 +463,6 @@ static void __init fixup_poodle(struct machine_desc *desc, sharpsl_save_param(); mi->nr_banks=1; mi->bank[0].start = 0xa0000000; - mi->bank[0].node = 0; mi->bank[0].size = (32*1024*1024); } diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c index c1048a35f187..51756c723557 100644 --- a/arch/arm/mach-pxa/spitz.c +++ b/arch/arm/mach-pxa/spitz.c @@ -847,7 +847,6 @@ static void __init fixup_spitz(struct machine_desc *desc, sharpsl_save_param(); mi->nr_banks = 1; mi->bank[0].start = 0xa0000000; - mi->bank[0].node = 0; mi->bank[0].size = (64*1024*1024); } diff --git a/arch/arm/mach-pxa/tosa.c b/arch/arm/mach-pxa/tosa.c index 7512b822c6ca..83cc3a18c2e9 100644 --- a/arch/arm/mach-pxa/tosa.c +++ b/arch/arm/mach-pxa/tosa.c @@ -948,7 +948,6 @@ static void __init fixup_tosa(struct machine_desc *desc, sharpsl_save_param(); mi->nr_banks=1; mi->bank[0].start = 0xa0000000; - mi->bank[0].node = 0; mi->bank[0].size = (64*1024*1024); } diff --git a/arch/arm/mach-s3c2412/mach-smdk2413.c b/arch/arm/mach-s3c2412/mach-smdk2413.c index ba93a356a839..054c9f92232a 100644 --- a/arch/arm/mach-s3c2412/mach-smdk2413.c +++ b/arch/arm/mach-s3c2412/mach-smdk2413.c @@ -119,7 +119,6 @@ static void __init smdk2413_fixup(struct machine_desc *desc, mi->nr_banks=1; mi->bank[0].start = 0x30000000; mi->bank[0].size = SZ_64M; - mi->bank[0].node = 0; } } diff --git a/arch/arm/mach-s3c2412/mach-vstms.c b/arch/arm/mach-s3c2412/mach-vstms.c index 3ca9265b6997..f291ac25d312 100644 --- a/arch/arm/mach-s3c2412/mach-vstms.c +++ b/arch/arm/mach-s3c2412/mach-vstms.c @@ -137,7 +137,6 @@ static void __init vstms_fixup(struct machine_desc *desc, mi->nr_banks=1; mi->bank[0].start = 0x30000000; mi->bank[0].size = SZ_64M; - mi->bank[0].node = 0; } } diff --git a/arch/arm/mach-sa1100/generic.h b/arch/arm/mach-sa1100/generic.h index ec03f187c52b..b7a9a601c2d1 100644 --- a/arch/arm/mach-sa1100/generic.h +++ b/arch/arm/mach-sa1100/generic.h @@ -13,8 +13,7 @@ extern void __init sa1100_init_gpio(void); #define SET_BANK(__nr,__start,__size) \ mi->bank[__nr].start = (__start), \ - mi->bank[__nr].size = (__size), \ - mi->bank[__nr].node = (((unsigned)(__start) - PHYS_OFFSET) >> 27) + mi->bank[__nr].size = (__size) extern void (*sa1100fb_backlight_power)(int on); extern void (*sa1100fb_lcd_power)(int on); diff --git a/arch/arm/mm/Makefile b/arch/arm/mm/Makefile index e8d34a80851c..d63b6c413758 100644 --- a/arch/arm/mm/Makefile +++ b/arch/arm/mm/Makefile @@ -15,7 +15,6 @@ endif obj-$(CONFIG_MODULES) += proc-syms.o obj-$(CONFIG_ALIGNMENT_TRAP) += alignment.o -obj-$(CONFIG_DISCONTIGMEM) += discontig.o obj-$(CONFIG_HIGHMEM) += highmem.o obj-$(CONFIG_CPU_ABRT_NOMMU) += abort-nommu.o diff --git a/arch/arm/mm/discontig.c b/arch/arm/mm/discontig.c deleted file mode 100644 index c8c0c4b0f0a3..000000000000 --- a/arch/arm/mm/discontig.c +++ /dev/null @@ -1,45 +0,0 @@ -/* - * linux/arch/arm/mm/discontig.c - * - * Discontiguous memory support. - * - * Initial code: Copyright (C) 1999-2000 Nicolas Pitre - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include -#include -#include - -#if MAX_NUMNODES != 4 && MAX_NUMNODES != 16 -# error Fix Me Please -#endif - -/* - * Our node_data structure for discontiguous memory. - */ - -pg_data_t discontig_node_data[MAX_NUMNODES] = { - { .bdata = &bootmem_node_data[0] }, - { .bdata = &bootmem_node_data[1] }, - { .bdata = &bootmem_node_data[2] }, - { .bdata = &bootmem_node_data[3] }, -#if MAX_NUMNODES == 16 - { .bdata = &bootmem_node_data[4] }, - { .bdata = &bootmem_node_data[5] }, - { .bdata = &bootmem_node_data[6] }, - { .bdata = &bootmem_node_data[7] }, - { .bdata = &bootmem_node_data[8] }, - { .bdata = &bootmem_node_data[9] }, - { .bdata = &bootmem_node_data[10] }, - { .bdata = &bootmem_node_data[11] }, - { .bdata = &bootmem_node_data[12] }, - { .bdata = &bootmem_node_data[13] }, - { .bdata = &bootmem_node_data[14] }, - { .bdata = &bootmem_node_data[15] }, -#endif -}; - -EXPORT_SYMBOL(discontig_node_data); diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c index f6a999465323..4011e524cb1d 100644 --- a/arch/arm/mm/init.c +++ b/arch/arm/mm/init.c @@ -79,38 +79,37 @@ struct meminfo meminfo; void show_mem(void) { int free = 0, total = 0, reserved = 0; - int shared = 0, cached = 0, slab = 0, node, i; + int shared = 0, cached = 0, slab = 0, i; struct meminfo * mi = &meminfo; printk("Mem-info:\n"); show_free_areas(); - for_each_online_node(node) { - for_each_nodebank (i,mi,node) { - struct membank *bank = &mi->bank[i]; - unsigned int pfn1, pfn2; - struct page *page, *end; - - pfn1 = bank_pfn_start(bank); - pfn2 = bank_pfn_end(bank); - - page = pfn_to_page(pfn1); - end = pfn_to_page(pfn2 - 1) + 1; - - do { - total++; - if (PageReserved(page)) - reserved++; - else if (PageSwapCache(page)) - cached++; - else if (PageSlab(page)) - slab++; - else if (!page_count(page)) - free++; - else - shared += page_count(page) - 1; - page++; - } while (page < end); - } + + for_each_bank (i, mi) { + struct membank *bank = &mi->bank[i]; + unsigned int pfn1, pfn2; + struct page *page, *end; + + pfn1 = bank_pfn_start(bank); + pfn2 = bank_pfn_end(bank); + + page = pfn_to_page(pfn1); + end = pfn_to_page(pfn2 - 1) + 1; + + do { + total++; + if (PageReserved(page)) + reserved++; + else if (PageSwapCache(page)) + cached++; + else if (PageSlab(page)) + slab++; + else if (!page_count(page)) + free++; + else + shared += page_count(page) - 1; + page++; + } while (page < end); } printk("%d pages of RAM\n", total); @@ -121,7 +120,7 @@ void show_mem(void) printk("%d pages swap cached\n", cached); } -static void __init find_node_limits(int node, struct meminfo *mi, +static void __init find_limits(struct meminfo *mi, unsigned long *min, unsigned long *max_low, unsigned long *max_high) { int i; @@ -129,7 +128,7 @@ static void __init find_node_limits(int node, struct meminfo *mi, *min = -1UL; *max_low = *max_high = 0; - for_each_nodebank(i, mi, node) { + for_each_bank (i, mi) { struct membank *bank = &mi->bank[i]; unsigned long start, end; @@ -154,14 +153,14 @@ static void __init find_node_limits(int node, struct meminfo *mi, * the end, we won't clash. */ static unsigned int __init -find_bootmap_pfn(int node, struct meminfo *mi, unsigned int bootmap_pages) +find_bootmap_pfn(struct meminfo *mi, unsigned int bootmap_pages) { unsigned int start_pfn, i, bootmap_pfn; start_pfn = PAGE_ALIGN(__pa(_end)) >> PAGE_SHIFT; bootmap_pfn = 0; - for_each_nodebank(i, mi, node) { + for_each_bank(i, mi) { struct membank *bank = &mi->bank[i]; unsigned int start, end; @@ -191,7 +190,7 @@ find_bootmap_pfn(int node, struct meminfo *mi, unsigned int bootmap_pages) static int __init check_initrd(struct meminfo *mi) { - int initrd_node = -2; + int initrd = -2; #ifdef CONFIG_BLK_DEV_INITRD unsigned long end = phys_initrd_start + phys_initrd_size; @@ -202,17 +201,17 @@ static int __init check_initrd(struct meminfo *mi) if (phys_initrd_size) { unsigned int i; - initrd_node = -1; + initrd = -1; for (i = 0; i < mi->nr_banks; i++) { struct membank *bank = &mi->bank[i]; if (bank_phys_start(bank) <= phys_initrd_start && end <= bank_phys_end(bank)) - initrd_node = bank->node; + initrd = 0; } } - if (initrd_node == -1) { + if (initrd == -1) { printk(KERN_ERR "INITRD: 0x%08lx+0x%08lx extends beyond " "physical memory - disabling initrd\n", phys_initrd_start, phys_initrd_size); @@ -220,10 +219,10 @@ static int __init check_initrd(struct meminfo *mi) } #endif - return initrd_node; + return initrd; } -static void __init bootmem_init_node(int node, struct meminfo *mi, +static void __init arm_bootmem_init(struct meminfo *mi, unsigned long start_pfn, unsigned long end_pfn) { unsigned long boot_pfn; @@ -235,37 +234,36 @@ static void __init bootmem_init_node(int node, struct meminfo *mi, * Allocate the bootmem bitmap page. */ boot_pages = bootmem_bootmap_pages(end_pfn - start_pfn); - boot_pfn = find_bootmap_pfn(node, mi, boot_pages); + boot_pfn = find_bootmap_pfn(mi, boot_pages); /* - * Initialise the bootmem allocator for this node, handing the + * Initialise the bootmem allocator, handing the * memory banks over to bootmem. */ - node_set_online(node); - pgdat = NODE_DATA(node); + node_set_online(0); + pgdat = NODE_DATA(0); init_bootmem_node(pgdat, boot_pfn, start_pfn, end_pfn); - for_each_nodebank(i, mi, node) { + for_each_bank(i, mi) { struct membank *bank = &mi->bank[i]; if (!bank->highmem) - free_bootmem_node(pgdat, bank_phys_start(bank), bank_phys_size(bank)); + free_bootmem(bank_phys_start(bank), bank_phys_size(bank)); } /* - * Reserve the bootmem bitmap for this node. + * Reserve the bootmem bitmap. */ - reserve_bootmem_node(pgdat, boot_pfn << PAGE_SHIFT, - boot_pages << PAGE_SHIFT, BOOTMEM_DEFAULT); + reserve_bootmem(boot_pfn << PAGE_SHIFT, + boot_pages << PAGE_SHIFT, BOOTMEM_DEFAULT); } -static void __init bootmem_reserve_initrd(int node) +static void __init bootmem_reserve_initrd(void) { #ifdef CONFIG_BLK_DEV_INITRD - pg_data_t *pgdat = NODE_DATA(node); int res; - res = reserve_bootmem_node(pgdat, phys_initrd_start, - phys_initrd_size, BOOTMEM_EXCLUSIVE); + res = reserve_bootmem(phys_initrd_start, + phys_initrd_size, BOOTMEM_EXCLUSIVE); if (res == 0) { initrd_start = __phys_to_virt(phys_initrd_start); @@ -279,23 +277,23 @@ static void __init bootmem_reserve_initrd(int node) #endif } -static void __init bootmem_free_node(int node, struct meminfo *mi) +static void __init arm_bootmem_free(struct meminfo *mi) { unsigned long zone_size[MAX_NR_ZONES], zhole_size[MAX_NR_ZONES]; unsigned long min, max_low, max_high; int i; - find_node_limits(node, mi, &min, &max_low, &max_high); + find_limits(mi, &min, &max_low, &max_high); /* - * initialise the zones within this node. + * initialise the zones. */ memset(zone_size, 0, sizeof(zone_size)); /* - * The size of this node has already been determined. If we need - * to do anything fancy with the allocation of this memory to the - * zones, now is the time to do it. + * The memory size has already been determined. If we need + * to do anything fancy with the allocation of this memory + * to the zones, now is the time to do it. */ zone_size[0] = max_low - min; #ifdef CONFIG_HIGHMEM @@ -303,11 +301,11 @@ static void __init bootmem_free_node(int node, struct meminfo *mi) #endif /* - * For each bank in this node, calculate the size of the holes. - * holes = node_size - sum(bank_sizes_in_node) + * Calculate the size of the holes. + * holes = node_size - sum(bank_sizes) */ memcpy(zhole_size, zone_size, sizeof(zhole_size)); - for_each_nodebank(i, mi, node) { + for_each_bank(i, mi) { int idx = 0; #ifdef CONFIG_HIGHMEM if (mi->bank[i].highmem) @@ -320,9 +318,9 @@ static void __init bootmem_free_node(int node, struct meminfo *mi) * Adjust the sizes according to any special requirements for * this machine type. */ - arch_adjust_zones(node, zone_size, zhole_size); + arch_adjust_zones(0, zone_size, zhole_size); - free_area_init_node(node, zone_size, min, zhole_size); + free_area_init_node(0, zone_size, min, zhole_size); } #ifndef CONFIG_SPARSEMEM @@ -346,16 +344,16 @@ int pfn_valid(unsigned long pfn) } EXPORT_SYMBOL(pfn_valid); -static void arm_memory_present(struct meminfo *mi, int node) +static void arm_memory_present(struct meminfo *mi) { } #else -static void arm_memory_present(struct meminfo *mi, int node) +static void arm_memory_present(struct meminfo *mi) { int i; - for_each_nodebank(i, mi, node) { + for_each_bank(i, mi) { struct membank *bank = &mi->bank[i]; - memory_present(node, bank_pfn_start(bank), bank_pfn_end(bank)); + memory_present(0, bank_pfn_start(bank), bank_pfn_end(bank)); } } #endif @@ -364,55 +362,35 @@ void __init bootmem_init(void) { struct meminfo *mi = &meminfo; unsigned long min, max_low, max_high; - int node, initrd_node; + int initrd; /* - * Locate which node contains the ramdisk image, if any. + * Locate the ramdisk image, if any. */ - initrd_node = check_initrd(mi); + initrd = check_initrd(mi); max_low = max_high = 0; - /* - * Run through each node initialising the bootmem allocator. - */ - for_each_node(node) { - unsigned long node_low, node_high; - - find_node_limits(node, mi, &min, &node_low, &node_high); + find_limits(mi, &min, &max_low, &max_high); - if (node_low > max_low) - max_low = node_low; - if (node_high > max_high) - max_high = node_high; + arm_bootmem_init(mi, min, max_low); - /* - * If there is no memory in this node, ignore it. - * (We can't have nodes which have no lowmem) - */ - if (node_low == 0) - continue; - - bootmem_init_node(node, mi, min, node_low); - - /* - * Reserve any special node zero regions. - */ - if (node == 0) - reserve_node_zero(NODE_DATA(node)); + /* + * Reserve any special regions. + */ + reserve_special_regions(); - /* - * If the initrd is in this node, reserve its memory. - */ - if (node == initrd_node) - bootmem_reserve_initrd(node); + /* + * If the initrd is present, reserve its memory. + */ + if (initrd == 0) + bootmem_reserve_initrd(); - /* - * Sparsemem tries to allocate bootmem in memory_present(), - * so must be done after the fixed reservations - */ - arm_memory_present(mi, node); - } + /* + * Sparsemem tries to allocate bootmem in memory_present(), + * so must be done after the fixed reservations + */ + arm_memory_present(mi); /* * sparse_init() needs the bootmem allocator up and running. @@ -420,12 +398,11 @@ void __init bootmem_init(void) sparse_init(); /* - * Now free memory in each node - free_area_init_node needs + * Now free the memory - free_area_init_node needs * the sparse mem_map arrays initialized by sparse_init() * for memmap_init_zone(), otherwise all PFNs are invalid. */ - for_each_node(node) - bootmem_free_node(node, mi); + arm_bootmem_free(mi); high_memory = __va((max_low << PAGE_SHIFT) - 1) + 1; @@ -460,7 +437,7 @@ static inline int free_area(unsigned long pfn, unsigned long end, char *s) } static inline void -free_memmap(int node, unsigned long start_pfn, unsigned long end_pfn) +free_memmap(unsigned long start_pfn, unsigned long end_pfn) { struct page *start_pg, *end_pg; unsigned long pg, pgend; @@ -483,13 +460,13 @@ free_memmap(int node, unsigned long start_pfn, unsigned long end_pfn) * free the section of the memmap array. */ if (pg < pgend) - free_bootmem_node(NODE_DATA(node), pg, pgend - pg); + free_bootmem(pg, pgend - pg); } /* * The mem_map array can get very big. Free the unused area of the memory map. */ -static void __init free_unused_memmap_node(int node, struct meminfo *mi) +static void __init free_unused_memmap(struct meminfo *mi) { unsigned long bank_start, prev_bank_end = 0; unsigned int i; @@ -499,7 +476,7 @@ static void __init free_unused_memmap_node(int node, struct meminfo *mi) * may not be the case, especially if the user has provided the * information on the command line. */ - for_each_nodebank(i, mi, node) { + for_each_bank(i, mi) { struct membank *bank = &mi->bank[i]; bank_start = bank_pfn_start(bank); @@ -514,7 +491,7 @@ static void __init free_unused_memmap_node(int node, struct meminfo *mi) * between the current bank and the previous, free it. */ if (prev_bank_end && prev_bank_end != bank_start) - free_memmap(node, prev_bank_end, bank_start); + free_memmap(prev_bank_end, bank_start); prev_bank_end = bank_pfn_end(bank); } @@ -528,21 +505,14 @@ static void __init free_unused_memmap_node(int node, struct meminfo *mi) void __init mem_init(void) { unsigned long reserved_pages, free_pages; - int i, node; + int i; -#ifndef CONFIG_DISCONTIGMEM max_mapnr = pfn_to_page(max_pfn + PHYS_PFN_OFFSET) - mem_map; -#endif /* this will put all unused low memory onto the freelists */ - for_each_online_node(node) { - pg_data_t *pgdat = NODE_DATA(node); - - free_unused_memmap_node(node, &meminfo); + free_unused_memmap(&meminfo); - if (pgdat->node_spanned_pages != 0) - totalram_pages += free_all_bootmem_node(pgdat); - } + totalram_pages += free_all_bootmem(); #ifdef CONFIG_SA1111 /* now that our DMA memory is actually so designated, we can free it */ @@ -552,39 +522,35 @@ void __init mem_init(void) #ifdef CONFIG_HIGHMEM /* set highmem page free */ - for_each_online_node(node) { - for_each_nodebank (i, &meminfo, node) { - unsigned long start = bank_pfn_start(&meminfo.bank[i]); - unsigned long end = bank_pfn_end(&meminfo.bank[i]); - if (start >= max_low_pfn + PHYS_PFN_OFFSET) - totalhigh_pages += free_area(start, end, NULL); - } + for_each_bank (i, &meminfo) { + unsigned long start = bank_pfn_start(&meminfo.bank[i]); + unsigned long end = bank_pfn_end(&meminfo.bank[i]); + if (start >= max_low_pfn + PHYS_PFN_OFFSET) + totalhigh_pages += free_area(start, end, NULL); } totalram_pages += totalhigh_pages; #endif reserved_pages = free_pages = 0; - for_each_online_node(node) { - for_each_nodebank(i, &meminfo, node) { - struct membank *bank = &meminfo.bank[i]; - unsigned int pfn1, pfn2; - struct page *page, *end; - - pfn1 = bank_pfn_start(bank); - pfn2 = bank_pfn_end(bank); - - page = pfn_to_page(pfn1); - end = pfn_to_page(pfn2 - 1) + 1; - - do { - if (PageReserved(page)) - reserved_pages++; - else if (!page_count(page)) - free_pages++; - page++; - } while (page < end); - } + for_each_bank(i, &meminfo) { + struct membank *bank = &meminfo.bank[i]; + unsigned int pfn1, pfn2; + struct page *page, *end; + + pfn1 = bank_pfn_start(bank); + pfn2 = bank_pfn_end(bank); + + page = pfn_to_page(pfn1); + end = pfn_to_page(pfn2 - 1) + 1; + + do { + if (PageReserved(page)) + reserved_pages++; + else if (!page_count(page)) + free_pages++; + page++; + } while (page < end); } /* diff --git a/arch/arm/mm/mm.h b/arch/arm/mm/mm.h index 815d08eecbb0..7b19c90ab295 100644 --- a/arch/arm/mm/mm.h +++ b/arch/arm/mm/mm.h @@ -28,7 +28,5 @@ extern void __flush_dcache_page(struct address_space *mapping, struct page *page #endif -struct pglist_data; - void __init bootmem_init(void); -void reserve_node_zero(struct pglist_data *pgdat); +void reserve_special_regions(void); diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c index 6a08087ab022..ddb1bee6de73 100644 --- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c @@ -827,9 +827,9 @@ static inline void prepare_page_table(void) } /* - * Reserve the various regions of node 0 + * Reserve the various regions */ -void __init reserve_node_zero(pg_data_t *pgdat) +void __init reserve_special_regions(void) { unsigned long res_size = 0; @@ -838,19 +838,17 @@ void __init reserve_node_zero(pg_data_t *pgdat) * Note that this can only be in node 0. */ #ifdef CONFIG_XIP_KERNEL - reserve_bootmem_node(pgdat, __pa(_data), _end - _data, - BOOTMEM_DEFAULT); + reserve_bootmem(__pa(_data), _end - _data, BOOTMEM_DEFAULT); #else - reserve_bootmem_node(pgdat, __pa(_stext), _end - _stext, - BOOTMEM_DEFAULT); + reserve_bootmem(__pa(_stext), _end - _stext, BOOTMEM_DEFAULT); #endif /* * Reserve the page tables. These are already in use, * and can only be in node 0. */ - reserve_bootmem_node(pgdat, __pa(swapper_pg_dir), - PTRS_PER_PGD * sizeof(pgd_t), BOOTMEM_DEFAULT); + reserve_bootmem(__pa(swapper_pg_dir), + PTRS_PER_PGD * sizeof(pgd_t), BOOTMEM_DEFAULT); /* * Hmm... This should go elsewhere, but we really really need to @@ -874,29 +872,22 @@ void __init reserve_node_zero(pg_data_t *pgdat) if (machine_is_h1940() || machine_is_rx3715() || machine_is_rx1950()) { - reserve_bootmem_node(pgdat, 0x30003000, 0x1000, - BOOTMEM_DEFAULT); - reserve_bootmem_node(pgdat, 0x30081000, 0x1000, - BOOTMEM_DEFAULT); + reserve_bootmem(0x30003000, 0x1000, BOOTMEM_DEFAULT); + reserve_bootmem(0x30081000, 0x1000, BOOTMEM_DEFAULT); } if (machine_is_palmld() || machine_is_palmtx()) { - reserve_bootmem_node(pgdat, 0xa0000000, 0x1000, - BOOTMEM_EXCLUSIVE); - reserve_bootmem_node(pgdat, 0xa0200000, 0x1000, - BOOTMEM_EXCLUSIVE); + reserve_bootmem(0xa0000000, 0x1000, BOOTMEM_EXCLUSIVE); + reserve_bootmem(0xa0200000, 0x1000, BOOTMEM_EXCLUSIVE); } if (machine_is_treo680() || machine_is_centro()) { - reserve_bootmem_node(pgdat, 0xa0000000, 0x1000, - BOOTMEM_EXCLUSIVE); - reserve_bootmem_node(pgdat, 0xa2000000, 0x1000, - BOOTMEM_EXCLUSIVE); + reserve_bootmem(0xa0000000, 0x1000, BOOTMEM_EXCLUSIVE); + reserve_bootmem(0xa2000000, 0x1000, BOOTMEM_EXCLUSIVE); } if (machine_is_palmt5()) - reserve_bootmem_node(pgdat, 0xa0200000, 0x1000, - BOOTMEM_EXCLUSIVE); + reserve_bootmem(0xa0200000, 0x1000, BOOTMEM_EXCLUSIVE); /* * U300 - This platform family can share physical memory @@ -920,8 +911,7 @@ void __init reserve_node_zero(pg_data_t *pgdat) res_size = __pa(swapper_pg_dir) - PHYS_OFFSET; #endif if (res_size) - reserve_bootmem_node(pgdat, PHYS_OFFSET, res_size, - BOOTMEM_DEFAULT); + reserve_bootmem(PHYS_OFFSET, res_size, BOOTMEM_DEFAULT); } /* diff --git a/arch/arm/mm/nommu.c b/arch/arm/mm/nommu.c index 33b327379f07..25376d480b8e 100644 --- a/arch/arm/mm/nommu.c +++ b/arch/arm/mm/nommu.c @@ -18,20 +18,18 @@ #include "mm.h" /* - * Reserve the various regions of node 0 + * Reserve the various regions */ -void __init reserve_node_zero(pg_data_t *pgdat) +void __init reserve_special_regions(void) { /* * Register the kernel text and data with bootmem. * Note that this can only be in node 0. */ #ifdef CONFIG_XIP_KERNEL - reserve_bootmem_node(pgdat, __pa(_data), _end - _data, - BOOTMEM_DEFAULT); + reserve_bootmem(__pa(_data), _end - _data, BOOTMEM_DEFAULT); #else - reserve_bootmem_node(pgdat, __pa(_stext), _end - _stext, - BOOTMEM_DEFAULT); + reserve_bootmem(__pa(_stext), _end - _stext, BOOTMEM_DEFAULT); #endif /* @@ -39,8 +37,7 @@ void __init reserve_node_zero(pg_data_t *pgdat) * some architectures which the DRAM is the exception vector to trap, * alloc_page breaks with error, although it is not NULL, but "0." */ - reserve_bootmem_node(pgdat, CONFIG_VECTORS_BASE, PAGE_SIZE, - BOOTMEM_DEFAULT); + reserve_bootmem(CONFIG_VECTORS_BASE, PAGE_SIZE, BOOTMEM_DEFAULT); } /* -- cgit v1.2.3 From b65b4781fbd5846a82cdac0c32818af1a7452d1f Mon Sep 17 00:00:00 2001 From: Russell King Date: Sat, 22 May 2010 20:58:51 +0100 Subject: ARM: Remove 'node' argument form arch_adjust_zones() Since we no longer support discontigmem, node is always zero, so remove this argument. Signed-off-by: Russell King --- arch/arm/common/sa1111.c | 5 +---- arch/arm/include/asm/memory.h | 2 +- arch/arm/mach-davinci/include/mach/memory.h | 9 +++------ arch/arm/mach-ixp4xx/common-pci.c | 4 ++-- arch/arm/mach-ixp4xx/include/mach/memory.h | 6 +++--- arch/arm/mach-pxa/cm-x2xx-pci.c | 4 ++-- arch/arm/mach-pxa/include/mach/memory.h | 7 +++---- arch/arm/mach-realview/core.c | 5 ++--- arch/arm/mach-realview/include/mach/memory.h | 7 +++---- arch/arm/mach-sa1100/include/mach/memory.h | 6 +++--- arch/arm/mach-shark/include/mach/memory.h | 7 +++---- arch/arm/mm/init.c | 2 +- 12 files changed, 27 insertions(+), 37 deletions(-) (limited to 'arch/arm/include') diff --git a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c index 6f80665f477e..ac2fd440652e 100644 --- a/arch/arm/common/sa1111.c +++ b/arch/arm/common/sa1111.c @@ -185,13 +185,10 @@ static struct sa1111_dev_info sa1111_devices[] = { }, }; -void __init sa1111_adjust_zones(int node, unsigned long *size, unsigned long *holes) +void __init sa1111_adjust_zones(unsigned long *size, unsigned long *holes) { unsigned int sz = SZ_1M >> PAGE_SHIFT; - if (node != 0) - sz = 0; - size[1] = size[0] - sz; size[0] = sz; } diff --git a/arch/arm/include/asm/memory.h b/arch/arm/include/asm/memory.h index e263ec7c5dcb..82df0ae71bb4 100644 --- a/arch/arm/include/asm/memory.h +++ b/arch/arm/include/asm/memory.h @@ -158,7 +158,7 @@ #endif #ifndef arch_adjust_zones -#define arch_adjust_zones(node,size,holes) do { } while (0) +#define arch_adjust_zones(size,holes) do { } while (0) #elif !defined(CONFIG_ZONE_DMA) #error "custom arch_adjust_zones() requires CONFIG_ZONE_DMA" #endif diff --git a/arch/arm/mach-davinci/include/mach/memory.h b/arch/arm/mach-davinci/include/mach/memory.h index a91edfb8beea..22eb97c1c30b 100644 --- a/arch/arm/mach-davinci/include/mach/memory.h +++ b/arch/arm/mach-davinci/include/mach/memory.h @@ -48,19 +48,16 @@ * below 128M */ static inline void -__arch_adjust_zones(int node, unsigned long *size, unsigned long *holes) +__arch_adjust_zones(unsigned long *size, unsigned long *holes) { unsigned int sz = (128<<20) >> PAGE_SHIFT; - if (node != 0) - sz = 0; - size[1] = size[0] - sz; size[0] = sz; } -#define arch_adjust_zones(node, zone_size, holes) \ - if ((meminfo.bank[0].size >> 20) > 128) __arch_adjust_zones(node, zone_size, holes) +#define arch_adjust_zones(zone_size, holes) \ + if ((meminfo.bank[0].size >> 20) > 128) __arch_adjust_zones(zone_size, holes) #define ISA_DMA_THRESHOLD (PHYS_OFFSET + (128<<20) - 1) #define MAX_DMA_ADDRESS (PAGE_OFFSET + (128<<20)) diff --git a/arch/arm/mach-ixp4xx/common-pci.c b/arch/arm/mach-ixp4xx/common-pci.c index e3181534c7f9..333d04c53650 100644 --- a/arch/arm/mach-ixp4xx/common-pci.c +++ b/arch/arm/mach-ixp4xx/common-pci.c @@ -348,7 +348,7 @@ int dma_needs_bounce(struct device *dev, dma_addr_t dma_addr, size_t size) * This is really ugly and we need a better way of specifying * DMA-capable regions of memory. */ -void __init ixp4xx_adjust_zones(int node, unsigned long *zone_size, +void __init ixp4xx_adjust_zones(unsigned long *zone_size, unsigned long *zhole_size) { unsigned int sz = SZ_64M >> PAGE_SHIFT; @@ -356,7 +356,7 @@ void __init ixp4xx_adjust_zones(int node, unsigned long *zone_size, /* * Only adjust if > 64M on current system */ - if (node || (zone_size[0] <= sz)) + if (zone_size[0] <= sz) return; zone_size[1] = zone_size[0] - sz; diff --git a/arch/arm/mach-ixp4xx/include/mach/memory.h b/arch/arm/mach-ixp4xx/include/mach/memory.h index 98f5e5e20980..0136eaa29224 100644 --- a/arch/arm/mach-ixp4xx/include/mach/memory.h +++ b/arch/arm/mach-ixp4xx/include/mach/memory.h @@ -16,10 +16,10 @@ #if !defined(__ASSEMBLY__) && defined(CONFIG_PCI) -void ixp4xx_adjust_zones(int node, unsigned long *size, unsigned long *holes); +void ixp4xx_adjust_zones(unsigned long *size, unsigned long *holes); -#define arch_adjust_zones(node, size, holes) \ - ixp4xx_adjust_zones(node, size, holes) +#define arch_adjust_zones(size, holes) \ + ixp4xx_adjust_zones(size, holes) #define ISA_DMA_THRESHOLD (SZ_64M - 1) #define MAX_DMA_ADDRESS (PAGE_OFFSET + SZ_64M) diff --git a/arch/arm/mach-pxa/cm-x2xx-pci.c b/arch/arm/mach-pxa/cm-x2xx-pci.c index 161fc2d61207..0f3130599770 100644 --- a/arch/arm/mach-pxa/cm-x2xx-pci.c +++ b/arch/arm/mach-pxa/cm-x2xx-pci.c @@ -35,7 +35,7 @@ static int cmx2xx_it8152_irq_gpio; * This is really ugly and we need a better way of specifying * DMA-capable regions of memory. */ -void __init cmx2xx_pci_adjust_zones(int node, unsigned long *zone_size, +void __init cmx2xx_pci_adjust_zones(unsigned long *zone_size, unsigned long *zhole_size) { unsigned int sz = SZ_64M >> PAGE_SHIFT; @@ -46,7 +46,7 @@ void __init cmx2xx_pci_adjust_zones(int node, unsigned long *zone_size, /* * Only adjust if > 64M on current system */ - if (node || (zone_size[0] <= sz)) + if (zone_size[0] <= sz) return; zone_size[1] = zone_size[0] - sz; diff --git a/arch/arm/mach-pxa/include/mach/memory.h b/arch/arm/mach-pxa/include/mach/memory.h index 81fd4a081c82..92361a66b223 100644 --- a/arch/arm/mach-pxa/include/mach/memory.h +++ b/arch/arm/mach-pxa/include/mach/memory.h @@ -18,11 +18,10 @@ #define PHYS_OFFSET UL(0xa0000000) #if !defined(__ASSEMBLY__) && defined(CONFIG_MACH_ARMCORE) && defined(CONFIG_PCI) -void cmx2xx_pci_adjust_zones(int node, unsigned long *size, - unsigned long *holes); +void cmx2xx_pci_adjust_zones(unsigned long *size, unsigned long *holes); -#define arch_adjust_zones(node, size, holes) \ - cmx2xx_pci_adjust_zones(node, size, holes) +#define arch_adjust_zones(size, holes) \ + cmx2xx_pci_adjust_zones(size, holes) #define ISA_DMA_THRESHOLD (PHYS_OFFSET + SZ_64M - 1) #define MAX_DMA_ADDRESS (PAGE_OFFSET + SZ_64M) diff --git a/arch/arm/mach-realview/core.c b/arch/arm/mach-realview/core.c index 595be19f8ad5..1195e07c5483 100644 --- a/arch/arm/mach-realview/core.c +++ b/arch/arm/mach-realview/core.c @@ -61,12 +61,11 @@ void __iomem *gic_cpu_base_addr; /* * Adjust the zones if there are restrictions for DMA access. */ -void __init realview_adjust_zones(int node, unsigned long *size, - unsigned long *hole) +void __init realview_adjust_zones(unsigned long *size, unsigned long *hole) { unsigned long dma_size = SZ_256M >> PAGE_SHIFT; - if (!machine_is_realview_pbx() || node || (size[0] <= dma_size)) + if (!machine_is_realview_pbx() || size[0] <= dma_size) return; size[ZONE_NORMAL] = size[0] - dma_size; diff --git a/arch/arm/mach-realview/include/mach/memory.h b/arch/arm/mach-realview/include/mach/memory.h index 2417bbcf97fd..5dafc157b276 100644 --- a/arch/arm/mach-realview/include/mach/memory.h +++ b/arch/arm/mach-realview/include/mach/memory.h @@ -30,10 +30,9 @@ #endif #if !defined(__ASSEMBLY__) && defined(CONFIG_ZONE_DMA) -extern void realview_adjust_zones(int node, unsigned long *size, - unsigned long *hole); -#define arch_adjust_zones(node, size, hole) \ - realview_adjust_zones(node, size, hole) +extern void realview_adjust_zones(unsigned long *size, unsigned long *hole); +#define arch_adjust_zones(size, hole) \ + realview_adjust_zones(size, hole) #define ISA_DMA_THRESHOLD (PHYS_OFFSET + SZ_256M - 1) #define MAX_DMA_ADDRESS (PAGE_OFFSET + SZ_256M) diff --git a/arch/arm/mach-sa1100/include/mach/memory.h b/arch/arm/mach-sa1100/include/mach/memory.h index d5277f9bee77..128a1dfa96b9 100644 --- a/arch/arm/mach-sa1100/include/mach/memory.h +++ b/arch/arm/mach-sa1100/include/mach/memory.h @@ -17,10 +17,10 @@ #ifndef __ASSEMBLY__ #ifdef CONFIG_SA1111 -void sa1111_adjust_zones(int node, unsigned long *size, unsigned long *holes); +void sa1111_adjust_zones(unsigned long *size, unsigned long *holes); -#define arch_adjust_zones(node, size, holes) \ - sa1111_adjust_zones(node, size, holes) +#define arch_adjust_zones(size, holes) \ + sa1111_adjust_zones(size, holes) #define ISA_DMA_THRESHOLD (PHYS_OFFSET + SZ_1M - 1) #define MAX_DMA_ADDRESS (PAGE_OFFSET + SZ_1M) diff --git a/arch/arm/mach-shark/include/mach/memory.h b/arch/arm/mach-shark/include/mach/memory.h index 3053e5b7f168..d9c4812f1c31 100644 --- a/arch/arm/mach-shark/include/mach/memory.h +++ b/arch/arm/mach-shark/include/mach/memory.h @@ -19,9 +19,8 @@ #ifndef __ASSEMBLY__ -static inline void __arch_adjust_zones(int node, unsigned long *zone_size, unsigned long *zhole_size) +static inline void __arch_adjust_zones(unsigned long *zone_size, unsigned long *zhole_size) { - if (node != 0) return; /* Only the first 4 MB (=1024 Pages) are usable for DMA */ /* See dev / -> .properties in OpenFirmware. */ zone_size[1] = zone_size[0] - 1024; @@ -30,8 +29,8 @@ static inline void __arch_adjust_zones(int node, unsigned long *zone_size, unsig zhole_size[0] = 0; } -#define arch_adjust_zones(node, size, holes) \ - __arch_adjust_zones(node, size, holes) +#define arch_adjust_zones(size, holes) \ + __arch_adjust_zones(size, holes) #define ISA_DMA_THRESHOLD (PHYS_OFFSET + SZ_4M - 1) #define MAX_DMA_ADDRESS (PAGE_OFFSET + SZ_4M) diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c index 4011e524cb1d..4d2720888c50 100644 --- a/arch/arm/mm/init.c +++ b/arch/arm/mm/init.c @@ -318,7 +318,7 @@ static void __init arm_bootmem_free(struct meminfo *mi) * Adjust the sizes according to any special requirements for * this machine type. */ - arch_adjust_zones(0, zone_size, zhole_size); + arch_adjust_zones(zone_size, zhole_size); free_area_init_node(0, zone_size, min, zhole_size); } -- cgit v1.2.3 From 98c672cf1fa2a56f6f43e3f48b1208b83845582c Mon Sep 17 00:00:00 2001 From: Russell King Date: Sat, 22 May 2010 18:18:57 +0100 Subject: ARM: Move platform memory reservations out of generic code Move the platform specific bootmem memory reservations out of arch/arm/mm/mmu.c into their respective platform files. Signed-off-by: Russell King --- arch/arm/include/asm/mach/arch.h | 1 + arch/arm/mach-clps711x/edb7211-arch.c | 8 ++++ arch/arm/mach-integrator/common.h | 1 + arch/arm/mach-integrator/core.c | 12 ++++++ arch/arm/mach-integrator/integrator_ap.c | 3 ++ arch/arm/mach-integrator/integrator_cp.c | 3 ++ arch/arm/mach-pxa/palmt5.c | 7 ++++ arch/arm/mach-pxa/palmtreo.c | 9 +++++ arch/arm/mach-s3c2410/mach-h1940.c | 9 +++++ arch/arm/mach-s3c2440/mach-rx1950.c | 9 +++++ arch/arm/mach-s3c2440/mach-rx3715.c | 9 +++++ arch/arm/mach-u300/u300.c | 17 +++++++++ arch/arm/mm/init.c | 5 ++- arch/arm/mm/mm.h | 3 +- arch/arm/mm/mmu.c | 63 ++------------------------------ arch/arm/mm/nommu.c | 2 +- 16 files changed, 98 insertions(+), 63 deletions(-) create mode 100644 arch/arm/mach-integrator/common.h (limited to 'arch/arm/include') diff --git a/arch/arm/include/asm/mach/arch.h b/arch/arm/include/asm/mach/arch.h index c59842dc7cb8..d425f2b6efeb 100644 --- a/arch/arm/include/asm/mach/arch.h +++ b/arch/arm/include/asm/mach/arch.h @@ -37,6 +37,7 @@ struct machine_desc { void (*fixup)(struct machine_desc *, struct tag *, char **, struct meminfo *); + void (*reserve)(void);/* reserve mem blocks */ void (*map_io)(void);/* IO mapping function */ void (*init_irq)(void); struct sys_timer *timer; /* system tick timer */ diff --git a/arch/arm/mach-clps711x/edb7211-arch.c b/arch/arm/mach-clps711x/edb7211-arch.c index 41a4425617c1..077f4051a06a 100644 --- a/arch/arm/mach-clps711x/edb7211-arch.c +++ b/arch/arm/mach-clps711x/edb7211-arch.c @@ -18,6 +18,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include +#include #include #include @@ -29,6 +30,12 @@ extern void edb7211_map_io(void); +/* Reserve screen memory region at the start of main system memory. */ +static void __init edb7211_reserve(void) +{ + reserve_bootmem(PHYS_OFFSET, 0x00020000, BOOTMEM_DEFAULT); +} + static void __init fixup_edb7211(struct machine_desc *desc, struct tag *tags, char **cmdline, struct meminfo *mi) @@ -55,6 +62,7 @@ MACHINE_START(EDB7211, "CL-EDB7211 (EP7211 eval board)") .boot_params = 0xc0020100, /* 0xc0000000 - 0xc001ffff can be video RAM */ .fixup = fixup_edb7211, .map_io = edb7211_map_io, + .reserve = edb7211_reserve, .init_irq = clps711x_init_irq, .timer = &clps711x_timer, MACHINE_END diff --git a/arch/arm/mach-integrator/common.h b/arch/arm/mach-integrator/common.h new file mode 100644 index 000000000000..5f96e1518aa9 --- /dev/null +++ b/arch/arm/mach-integrator/common.h @@ -0,0 +1 @@ +void integrator_reserve(void); diff --git a/arch/arm/mach-integrator/core.c b/arch/arm/mach-integrator/core.c index b02cfc06e0ae..f815a1863f70 100644 --- a/arch/arm/mach-integrator/core.c +++ b/arch/arm/mach-integrator/core.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -30,6 +31,7 @@ #include #include #include +#include static struct amba_pl010_data integrator_uart_data; @@ -215,3 +217,13 @@ void cm_control(u32 mask, u32 set) } EXPORT_SYMBOL(cm_control); + +/* + * We need to stop things allocating the low memory; ideally we need a + * better implementation of GFP_DMA which does not assume that DMA-able + * memory starts at zero. + */ +void __init integrator_reserve(void) +{ + reserve_bootmem(PHYS_OFFSET, __pa(swapper_pg_dir) - PHYS_OFFSET, BOOTMEM_DEFAULT); +} diff --git a/arch/arm/mach-integrator/integrator_ap.c b/arch/arm/mach-integrator/integrator_ap.c index 227cf4d05088..6ab5a03ab9d8 100644 --- a/arch/arm/mach-integrator/integrator_ap.c +++ b/arch/arm/mach-integrator/integrator_ap.c @@ -48,6 +48,8 @@ #include #include +#include "common.h" + /* * All IO addresses are mapped onto VA 0xFFFx.xxxx, where x.xxxx * is the (PA >> 12). @@ -502,6 +504,7 @@ MACHINE_START(INTEGRATOR, "ARM-Integrator") .io_pg_offst = ((0xf1600000) >> 18) & 0xfffc, .boot_params = 0x00000100, .map_io = ap_map_io, + .reserve = integrator_reserve, .init_irq = ap_init_irq, .timer = &ap_timer, .init_machine = ap_init, diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c index cde57b2b83b5..05db40e3c4f7 100644 --- a/arch/arm/mach-integrator/integrator_cp.c +++ b/arch/arm/mach-integrator/integrator_cp.c @@ -43,6 +43,8 @@ #include +#include "common.h" + #define INTCP_PA_FLASH_BASE 0x24000000 #define INTCP_FLASH_SIZE SZ_32M @@ -601,6 +603,7 @@ MACHINE_START(CINTEGRATOR, "ARM-IntegratorCP") .io_pg_offst = ((0xf1600000) >> 18) & 0xfffc, .boot_params = 0x00000100, .map_io = intcp_map_io, + .reserve = integrator_reserve, .init_irq = intcp_init_irq, .timer = &cp_timer, .init_machine = intcp_init, diff --git a/arch/arm/mach-pxa/palmt5.c b/arch/arm/mach-pxa/palmt5.c index 5305a3993e69..39fd788ab63b 100644 --- a/arch/arm/mach-pxa/palmt5.c +++ b/arch/arm/mach-pxa/palmt5.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -396,6 +397,11 @@ static void __init palmt5_udc_init(void) } } +static void __init palmt5_reserve(void) +{ + reserve_bootmem(0xa0200000, 0x1000, BOOTMEM_EXCLUSIVE); +} + static void __init palmt5_init(void) { pxa2xx_mfp_config(ARRAY_AND_SIZE(palmt5_pin_config)); @@ -421,6 +427,7 @@ MACHINE_START(PALMT5, "Palm Tungsten|T5") .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, .boot_params = 0xa0000100, .map_io = pxa_map_io, + .reserve = palmt5_reserve, .init_irq = pxa27x_init_irq, .timer = &pxa_timer, .init_machine = palmt5_init diff --git a/arch/arm/mach-pxa/palmtreo.c b/arch/arm/mach-pxa/palmtreo.c index d8b4469607a1..f5db4f7d7158 100644 --- a/arch/arm/mach-pxa/palmtreo.c +++ b/arch/arm/mach-pxa/palmtreo.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -633,6 +634,12 @@ static void __init treo_lcd_power_init(void) treo_lcd_screen.pxafb_lcd_power = treo_lcd_power; } +static void __init treo_reserve(void) +{ + reserve_bootmem(0xa0000000, 0x1000, BOOTMEM_EXCLUSIVE); + reserve_bootmem(0xa2000000, 0x1000, BOOTMEM_EXCLUSIVE); +} + static void __init treo_init(void) { pxa_set_ffuart_info(NULL); @@ -668,6 +675,7 @@ MACHINE_START(TREO680, "Palm Treo 680") .io_pg_offst = io_p2v(0x40000000), .boot_params = 0xa0000100, .map_io = pxa_map_io, + .reserve = treo_reserve, .init_irq = pxa27x_init_irq, .timer = &pxa_timer, .init_machine = treo680_init, @@ -691,6 +699,7 @@ MACHINE_START(CENTRO, "Palm Centro 685") .io_pg_offst = io_p2v(0x40000000), .boot_params = 0xa0000100, .map_io = pxa_map_io, + .reserve = treo_reserve, .init_irq = pxa27x_init_irq, .timer = &pxa_timer, .init_machine = centro_init, diff --git a/arch/arm/mach-s3c2410/mach-h1940.c b/arch/arm/mach-s3c2410/mach-h1940.c index 779b45b3f80f..2407aab4d1b8 100644 --- a/arch/arm/mach-s3c2410/mach-h1940.c +++ b/arch/arm/mach-s3c2410/mach-h1940.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -304,6 +305,13 @@ static void __init h1940_map_io(void) s3c_pm_init(); } +/* H1940 and RX3715 need to reserve this for suspend */ +static void __init h1940_reserve(void) +{ + reserve_bootmem(0x30003000, 0x1000, BOOTMEM_DEFAULT); + reserve_bootmem(0x30081000, 0x1000, BOOTMEM_DEFAULT); +} + static void __init h1940_init_irq(void) { s3c24xx_init_irq(); @@ -346,6 +354,7 @@ MACHINE_START(H1940, "IPAQ-H1940") .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc, .boot_params = S3C2410_SDRAM_PA + 0x100, .map_io = h1940_map_io, + .reserve = h1940_reserve, .init_irq = h1940_init_irq, .init_machine = h1940_init, .timer = &s3c24xx_timer, diff --git a/arch/arm/mach-s3c2440/mach-rx1950.c b/arch/arm/mach-s3c2440/mach-rx1950.c index 8603b577a24b..f26d5d60c13d 100644 --- a/arch/arm/mach-s3c2440/mach-rx1950.c +++ b/arch/arm/mach-s3c2440/mach-rx1950.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -570,12 +571,20 @@ static void __init rx1950_init_machine(void) platform_add_devices(rx1950_devices, ARRAY_SIZE(rx1950_devices)); } +/* H1940 and RX3715 need to reserve this for suspend */ +static void __init rx1950_reserve(void) +{ + reserve_bootmem(0x30003000, 0x1000, BOOTMEM_DEFAULT); + reserve_bootmem(0x30081000, 0x1000, BOOTMEM_DEFAULT); +} + MACHINE_START(RX1950, "HP iPAQ RX1950") /* Maintainers: Vasily Khoruzhick */ .phys_io = S3C2410_PA_UART, .io_pg_offst = (((u32) S3C24XX_VA_UART) >> 18) & 0xfffc, .boot_params = S3C2410_SDRAM_PA + 0x100, .map_io = rx1950_map_io, + .reserve = rx1950_reserve, .init_irq = s3c24xx_init_irq, .init_machine = rx1950_init_machine, .timer = &s3c24xx_timer, diff --git a/arch/arm/mach-s3c2440/mach-rx3715.c b/arch/arm/mach-s3c2440/mach-rx3715.c index d2946de3f365..6ebdb7bcf085 100644 --- a/arch/arm/mach-s3c2440/mach-rx3715.c +++ b/arch/arm/mach-s3c2440/mach-rx3715.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -191,6 +192,13 @@ static void __init rx3715_map_io(void) s3c24xx_init_uarts(rx3715_uartcfgs, ARRAY_SIZE(rx3715_uartcfgs)); } +/* H1940 and RX3715 need to reserve this for suspend */ +static void __init rx3715_reserve(void) +{ + reserve_bootmem(0x30003000, 0x1000, BOOTMEM_DEFAULT); + reserve_bootmem(0x30081000, 0x1000, BOOTMEM_DEFAULT); +} + static void __init rx3715_init_irq(void) { s3c24xx_init_irq(); @@ -214,6 +222,7 @@ MACHINE_START(RX3715, "IPAQ-RX3715") .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc, .boot_params = S3C2410_SDRAM_PA + 0x100, .map_io = rx3715_map_io, + .reserve = rx3715_reserve, .init_irq = rx3715_init_irq, .init_machine = rx3715_init_machine, .timer = &s3c24xx_timer, diff --git a/arch/arm/mach-u300/u300.c b/arch/arm/mach-u300/u300.c index d2a0b8847a18..178dca4f9555 100644 --- a/arch/arm/mach-u300/u300.c +++ b/arch/arm/mach-u300/u300.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -22,6 +23,21 @@ #include #include +static void __init u300_reserve(void) +{ + /* + * U300 - This platform family can share physical memory + * between two ARM cpus, one running Linux and the other + * running another OS. + */ +#ifdef CONFIG_MACH_U300_SINGLE_RAM +#if ((CONFIG_MACH_U300_ACCESS_MEM_SIZE & 1) == 1) && \ + CONFIG_MACH_U300_2MB_ALIGNMENT_FIX + reserve_bootmem(PHYS_OFFSET, 0x00100000, BOOTMEM_DEFAULT); +#endif +#endif +} + static void __init u300_init_machine(void) { u300_init_devices(); @@ -49,6 +65,7 @@ MACHINE_START(U300, MACH_U300_STRING) .io_pg_offst = ((U300_AHB_PER_VIRT_BASE) >> 18) & 0xfffc, .boot_params = BOOT_PARAMS_OFFSET, .map_io = u300_map_io, + .reserve = u300_reserve, .init_irq = u300_init_irq, .timer = &u300_timer, .init_machine = u300_init_machine, diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c index 4d2720888c50..1a227eea64bd 100644 --- a/arch/arm/mm/init.c +++ b/arch/arm/mm/init.c @@ -358,7 +358,7 @@ static void arm_memory_present(struct meminfo *mi) } #endif -void __init bootmem_init(void) +void __init bootmem_init(struct machine_desc *mdesc) { struct meminfo *mi = &meminfo; unsigned long min, max_low, max_high; @@ -380,6 +380,9 @@ void __init bootmem_init(void) */ reserve_special_regions(); + if (mdesc->reserve) + mdesc->reserve(); + /* * If the initrd is present, reserve its memory. */ diff --git a/arch/arm/mm/mm.h b/arch/arm/mm/mm.h index 7b19c90ab295..afafe4fc5431 100644 --- a/arch/arm/mm/mm.h +++ b/arch/arm/mm/mm.h @@ -28,5 +28,6 @@ extern void __flush_dcache_page(struct address_space *mapping, struct page *page #endif -void __init bootmem_init(void); +struct machine_desc; +void __init bootmem_init(struct machine_desc *); void reserve_special_regions(void); diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c index ddb1bee6de73..1676d017a93a 100644 --- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c @@ -17,7 +17,6 @@ #include #include -#include #include #include #include @@ -831,8 +830,6 @@ static inline void prepare_page_table(void) */ void __init reserve_special_regions(void) { - unsigned long res_size = 0; - /* * Register the kernel text and data with bootmem. * Note that this can only be in node 0. @@ -850,68 +847,14 @@ void __init reserve_special_regions(void) reserve_bootmem(__pa(swapper_pg_dir), PTRS_PER_PGD * sizeof(pgd_t), BOOTMEM_DEFAULT); - /* - * Hmm... This should go elsewhere, but we really really need to - * stop things allocating the low memory; ideally we need a better - * implementation of GFP_DMA which does not assume that DMA-able - * memory starts at zero. - */ - if (machine_is_integrator() || machine_is_cintegrator()) - res_size = __pa(swapper_pg_dir) - PHYS_OFFSET; - - /* - * These should likewise go elsewhere. They pre-reserve the - * screen memory region at the start of main system memory. - */ - if (machine_is_edb7211()) - res_size = 0x00020000; - if (machine_is_p720t()) - res_size = 0x00014000; - - /* H1940, RX3715 and RX1950 need to reserve this for suspend */ - - if (machine_is_h1940() || machine_is_rx3715() - || machine_is_rx1950()) { - reserve_bootmem(0x30003000, 0x1000, BOOTMEM_DEFAULT); - reserve_bootmem(0x30081000, 0x1000, BOOTMEM_DEFAULT); - } - - if (machine_is_palmld() || machine_is_palmtx()) { - reserve_bootmem(0xa0000000, 0x1000, BOOTMEM_EXCLUSIVE); - reserve_bootmem(0xa0200000, 0x1000, BOOTMEM_EXCLUSIVE); - } - - if (machine_is_treo680() || machine_is_centro()) { - reserve_bootmem(0xa0000000, 0x1000, BOOTMEM_EXCLUSIVE); - reserve_bootmem(0xa2000000, 0x1000, BOOTMEM_EXCLUSIVE); - } - - if (machine_is_palmt5()) - reserve_bootmem(0xa0200000, 0x1000, BOOTMEM_EXCLUSIVE); - - /* - * U300 - This platform family can share physical memory - * between two ARM cpus, one running Linux and the other - * running another OS. - */ - if (machine_is_u300()) { -#ifdef CONFIG_MACH_U300_SINGLE_RAM -#if ((CONFIG_MACH_U300_ACCESS_MEM_SIZE & 1) == 1) && \ - CONFIG_MACH_U300_2MB_ALIGNMENT_FIX - res_size = 0x00100000; -#endif -#endif - } - #ifdef CONFIG_SA1111 /* * Because of the SA1111 DMA bug, we want to preserve our * precious DMA-able memory... */ - res_size = __pa(swapper_pg_dir) - PHYS_OFFSET; + reserve_bootmem(PHYS_OFFSET, __pa(swapper_pg_dir) - PHYS_OFFSET, + BOOTMEM_DEFAULT); #endif - if (res_size) - reserve_bootmem(PHYS_OFFSET, res_size, BOOTMEM_DEFAULT); } /* @@ -1056,7 +999,7 @@ void __init paging_init(struct machine_desc *mdesc) sanity_check_meminfo(); prepare_page_table(); map_lowmem(); - bootmem_init(); + bootmem_init(mdesc); devicemaps_init(mdesc); kmap_init(); diff --git a/arch/arm/mm/nommu.c b/arch/arm/mm/nommu.c index 25376d480b8e..ed58ddbbc5b3 100644 --- a/arch/arm/mm/nommu.c +++ b/arch/arm/mm/nommu.c @@ -46,7 +46,7 @@ void __init reserve_special_regions(void) */ void __init paging_init(struct machine_desc *mdesc) { - bootmem_init(); + bootmem_init(mdesc); } /* -- cgit v1.2.3 From 35fe2fc44ac4202261317ccce2ef69991bc01c57 Mon Sep 17 00:00:00 2001 From: Saeed Bishara Date: Thu, 3 Jun 2010 14:58:46 +0300 Subject: [ARM] PCI: add platform private data to pci_sys_data Add private_data pointer to the pci_sys_data, this pointer can be used for holding platform specific data for each pci controller. Signed-off-by: Saeed Bishara Signed-off-by: Nicolas Pitre --- arch/arm/include/asm/mach/pci.h | 1 + 1 file changed, 1 insertion(+) (limited to 'arch/arm/include') diff --git a/arch/arm/include/asm/mach/pci.h b/arch/arm/include/asm/mach/pci.h index 52f0da1e97df..16330bd0657c 100644 --- a/arch/arm/include/asm/mach/pci.h +++ b/arch/arm/include/asm/mach/pci.h @@ -46,6 +46,7 @@ struct pci_sys_data { /* IRQ mapping */ int (*map_irq)(struct pci_dev *, u8, u8); struct hw_pci *hw; + void *private_data; /* platform controller private data */ }; /* -- cgit v1.2.3 From cb9d7707cd9be57830f31616233f6a872ca8416d Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Mon, 12 Jul 2010 21:50:59 +0100 Subject: ARM: 6222/1: add memory types for the TCMs The earlier TCM memory regions were mapped as MT_MEMORY_UNCACHED which doesn't really work on platforms supporting the new v6 features like the NX bit. Add unique MT_MEMORY_[I|D]TCM types instead. Cc: Nicolas Pitre Signed-off-by: Linus Walleij Signed-off-by: Russell King --- arch/arm/include/asm/mach/map.h | 2 ++ arch/arm/kernel/tcm.c | 5 ++--- arch/arm/mm/mmu.c | 13 +++++++++++++ 3 files changed, 17 insertions(+), 3 deletions(-) (limited to 'arch/arm/include') diff --git a/arch/arm/include/asm/mach/map.h b/arch/arm/include/asm/mach/map.h index 742c2aaeb020..d2fedb5aeb1f 100644 --- a/arch/arm/include/asm/mach/map.h +++ b/arch/arm/include/asm/mach/map.h @@ -27,6 +27,8 @@ struct map_desc { #define MT_MEMORY 9 #define MT_ROM 10 #define MT_MEMORY_NONCACHED 11 +#define MT_MEMORY_DTCM 12 +#define MT_MEMORY_ITCM 13 #ifdef CONFIG_MMU extern void iotable_init(struct map_desc *, int); diff --git a/arch/arm/kernel/tcm.c b/arch/arm/kernel/tcm.c index e50303868f1b..0c62aa2c86ea 100644 --- a/arch/arm/kernel/tcm.c +++ b/arch/arm/kernel/tcm.c @@ -13,7 +13,6 @@ #include #include #include /* memcpy */ -#include /* PAGE_SHIFT */ #include #include #include @@ -53,7 +52,7 @@ static struct map_desc dtcm_iomap[] __initdata = { .virtual = DTCM_OFFSET, .pfn = __phys_to_pfn(DTCM_OFFSET), .length = (DTCM_END - DTCM_OFFSET + 1), - .type = MT_UNCACHED + .type = MT_MEMORY_DTCM } }; @@ -62,7 +61,7 @@ static struct map_desc itcm_iomap[] __initdata = { .virtual = ITCM_OFFSET, .pfn = __phys_to_pfn(ITCM_OFFSET), .length = (ITCM_END - ITCM_OFFSET + 1), - .type = MT_UNCACHED + .type = MT_MEMORY_ITCM } }; diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c index 285894171186..e53480148c05 100644 --- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c @@ -258,6 +258,19 @@ static struct mem_type mem_types[] = { .prot_sect = PMD_TYPE_SECT | PMD_SECT_AP_WRITE, .domain = DOMAIN_KERNEL, }, + [MT_MEMORY_DTCM] = { + .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | + L_PTE_DIRTY | L_PTE_WRITE, + .prot_l1 = PMD_TYPE_TABLE, + .prot_sect = PMD_TYPE_SECT | PMD_SECT_XN, + .domain = DOMAIN_KERNEL, + }, + [MT_MEMORY_ITCM] = { + .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY | + L_PTE_USER | L_PTE_EXEC, + .prot_l1 = PMD_TYPE_TABLE, + .domain = DOMAIN_IO, + }, }; const struct mem_type *get_mem_type(unsigned int type) -- cgit v1.2.3 From 392c57a2ec811db37ae45adc513704cf92ba3e69 Mon Sep 17 00:00:00 2001 From: Russell King Date: Mon, 26 Jul 2010 11:02:31 +0100 Subject: ARM: fix build warning in asm/elf.h CC kernel/elfcore.o In file included from include/linux/elf.h:7, from kernel/elfcore.c:1: arch/arm/include/asm/elf.h:124: warning: 'struct mm_struct' declared inside parameter list arch/arm/include/asm/elf.h:124: warning: its scope is only this definition or declaration, which is probably not what you want Signed-off-by: Russell King --- arch/arm/include/asm/elf.h | 1 + 1 file changed, 1 insertion(+) (limited to 'arch/arm/include') diff --git a/arch/arm/include/asm/elf.h b/arch/arm/include/asm/elf.h index 0a96e8c1b82a..6750b8e45a49 100644 --- a/arch/arm/include/asm/elf.h +++ b/arch/arm/include/asm/elf.h @@ -121,6 +121,7 @@ int dump_task_regs(struct task_struct *t, elf_gregset_t *elfregs); extern void elf_set_personality(const struct elf32_hdr *); #define SET_PERSONALITY(ex) elf_set_personality(&(ex)) +struct mm_struct; extern unsigned long arch_randomize_brk(struct mm_struct *mm); #define arch_randomize_brk arch_randomize_brk -- cgit v1.2.3 From 2778f62056ada442414392d7ccd41188bb631619 Mon Sep 17 00:00:00 2001 From: Russell King Date: Fri, 9 Jul 2010 16:27:52 +0100 Subject: ARM: initial LMB trial Acked-by: Tony Lindgren Signed-off-by: Russell King --- arch/arm/Kconfig | 1 + arch/arm/include/asm/memblock.h | 15 ++++ arch/arm/kernel/setup.c | 3 + arch/arm/mm/init.c | 164 +++++++++++----------------------------- arch/arm/mm/mm.h | 2 +- arch/arm/mm/mmu.c | 34 ++++----- arch/arm/mm/nommu.c | 19 +---- 7 files changed, 83 insertions(+), 155 deletions(-) create mode 100644 arch/arm/include/asm/memblock.h (limited to 'arch/arm/include') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 410edd65f117..36c8b5e12590 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -10,6 +10,7 @@ config ARM default y select HAVE_AOUT select HAVE_IDE + select HAVE_MEMBLOCK select RTC_LIB select SYS_SUPPORTS_APM_EMULATION select GENERIC_ATOMIC64 if (!CPU_32v6K) diff --git a/arch/arm/include/asm/memblock.h b/arch/arm/include/asm/memblock.h new file mode 100644 index 000000000000..3a1d58096f44 --- /dev/null +++ b/arch/arm/include/asm/memblock.h @@ -0,0 +1,15 @@ +#ifndef _ASM_ARM_MEMBLOCK_H +#define _ASM_ARM_MEMBLOCK_H + +#ifdef CONFIG_MMU +extern phys_addr_t lowmem_end_addr; +#define MEMBLOCK_REAL_LIMIT lowmem_end_addr +#else +#define MEMBLOCK_REAL_LIMIT 0 +#endif + +struct meminfo; + +extern void arm_memblock_init(struct meminfo *); + +#endif diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index 387d2e9cb51f..dfd293477751 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -715,6 +716,8 @@ void __init setup_arch(char **cmdline_p) parse_early_param(); + arm_memblock_init(&meminfo); + paging_init(mdesc); request_standard_resources(&meminfo, mdesc); diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c index 1a227eea64bd..4877e06308b7 100644 --- a/arch/arm/mm/init.c +++ b/arch/arm/mm/init.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -146,95 +147,21 @@ static void __init find_limits(struct meminfo *mi, } } -/* - * FIXME: We really want to avoid allocating the bootmap bitmap - * over the top of the initrd. Hopefully, this is located towards - * the start of a bank, so if we allocate the bootmap bitmap at - * the end, we won't clash. - */ -static unsigned int __init -find_bootmap_pfn(struct meminfo *mi, unsigned int bootmap_pages) -{ - unsigned int start_pfn, i, bootmap_pfn; - - start_pfn = PAGE_ALIGN(__pa(_end)) >> PAGE_SHIFT; - bootmap_pfn = 0; - - for_each_bank(i, mi) { - struct membank *bank = &mi->bank[i]; - unsigned int start, end; - - start = bank_pfn_start(bank); - end = bank_pfn_end(bank); - - if (end < start_pfn) - continue; - - if (start < start_pfn) - start = start_pfn; - - if (end <= start) - continue; - - if (end - start >= bootmap_pages) { - bootmap_pfn = start; - break; - } - } - - if (bootmap_pfn == 0) - BUG(); - - return bootmap_pfn; -} - -static int __init check_initrd(struct meminfo *mi) -{ - int initrd = -2; -#ifdef CONFIG_BLK_DEV_INITRD - unsigned long end = phys_initrd_start + phys_initrd_size; - - /* - * Make sure that the initrd is within a valid area of - * memory. - */ - if (phys_initrd_size) { - unsigned int i; - - initrd = -1; - - for (i = 0; i < mi->nr_banks; i++) { - struct membank *bank = &mi->bank[i]; - if (bank_phys_start(bank) <= phys_initrd_start && - end <= bank_phys_end(bank)) - initrd = 0; - } - } - - if (initrd == -1) { - printk(KERN_ERR "INITRD: 0x%08lx+0x%08lx extends beyond " - "physical memory - disabling initrd\n", - phys_initrd_start, phys_initrd_size); - phys_initrd_start = phys_initrd_size = 0; - } -#endif - - return initrd; -} - static void __init arm_bootmem_init(struct meminfo *mi, unsigned long start_pfn, unsigned long end_pfn) { - unsigned long boot_pfn; unsigned int boot_pages; + phys_addr_t bitmap; pg_data_t *pgdat; int i; /* - * Allocate the bootmem bitmap page. + * Allocate the bootmem bitmap page. This must be in a region + * of memory which has already been mapped. */ boot_pages = bootmem_bootmap_pages(end_pfn - start_pfn); - boot_pfn = find_bootmap_pfn(mi, boot_pages); + bitmap = memblock_alloc_base(boot_pages << PAGE_SHIFT, L1_CACHE_BYTES, + __pfn_to_phys(end_pfn)); /* * Initialise the bootmem allocator, handing the @@ -242,7 +169,7 @@ static void __init arm_bootmem_init(struct meminfo *mi, */ node_set_online(0); pgdat = NODE_DATA(0); - init_bootmem_node(pgdat, boot_pfn, start_pfn, end_pfn); + init_bootmem_node(pgdat, __phys_to_pfn(bitmap), start_pfn, end_pfn); for_each_bank(i, mi) { struct membank *bank = &mi->bank[i]; @@ -251,30 +178,16 @@ static void __init arm_bootmem_init(struct meminfo *mi, } /* - * Reserve the bootmem bitmap. + * Reserve the memblock reserved regions in bootmem. */ - reserve_bootmem(boot_pfn << PAGE_SHIFT, - boot_pages << PAGE_SHIFT, BOOTMEM_DEFAULT); -} - -static void __init bootmem_reserve_initrd(void) -{ -#ifdef CONFIG_BLK_DEV_INITRD - int res; - - res = reserve_bootmem(phys_initrd_start, - phys_initrd_size, BOOTMEM_EXCLUSIVE); - - if (res == 0) { - initrd_start = __phys_to_virt(phys_initrd_start); - initrd_end = initrd_start + phys_initrd_size; - } else { - printk(KERN_ERR - "INITRD: 0x%08lx+0x%08lx overlaps in-use " - "memory region - disabling initrd\n", - phys_initrd_start, phys_initrd_size); + for (i = 0; i < memblock.reserved.cnt; i++) { + phys_addr_t start = memblock_start_pfn(&memblock.reserved, i); + if (start >= start_pfn && + memblock_end_pfn(&memblock.reserved, i) <= end_pfn) + reserve_bootmem_node(pgdat, __pfn_to_phys(start), + memblock_size_bytes(&memblock.reserved, i), + BOOTMEM_DEFAULT); } -#endif } static void __init arm_bootmem_free(struct meminfo *mi) @@ -358,16 +271,40 @@ static void arm_memory_present(struct meminfo *mi) } #endif +void __init arm_memblock_init(struct meminfo *mi) +{ + int i; + + memblock_init(); + for (i = 0; i < mi->nr_banks; i++) + memblock_add(mi->bank[i].start, mi->bank[i].size); + + /* Register the kernel text, kernel data and initrd with memblock. */ +#ifdef CONFIG_XIP_KERNEL + memblock_reserve(__pa(_data), _end - _data); +#else + memblock_reserve(__pa(_stext), _end - _stext); +#endif +#ifdef CONFIG_BLK_DEV_INITRD + if (phys_initrd_size) { + memblock_reserve(phys_initrd_start, phys_initrd_size); + + /* Now convert initrd to virtual addresses */ + initrd_start = __phys_to_virt(phys_initrd_start); + initrd_end = initrd_start + phys_initrd_size; + } +#endif + + arm_mm_memblock_reserve(); + + memblock_analyze(); + memblock_dump_all(); +} + void __init bootmem_init(struct machine_desc *mdesc) { struct meminfo *mi = &meminfo; unsigned long min, max_low, max_high; - int initrd; - - /* - * Locate the ramdisk image, if any. - */ - initrd = check_initrd(mi); max_low = max_high = 0; @@ -375,20 +312,9 @@ void __init bootmem_init(struct machine_desc *mdesc) arm_bootmem_init(mi, min, max_low); - /* - * Reserve any special regions. - */ - reserve_special_regions(); - if (mdesc->reserve) mdesc->reserve(); - /* - * If the initrd is present, reserve its memory. - */ - if (initrd == 0) - bootmem_reserve_initrd(); - /* * Sparsemem tries to allocate bootmem in memory_present(), * so must be done after the fixed reservations diff --git a/arch/arm/mm/mm.h b/arch/arm/mm/mm.h index afafe4fc5431..fcfffae69b49 100644 --- a/arch/arm/mm/mm.h +++ b/arch/arm/mm/mm.h @@ -30,4 +30,4 @@ extern void __flush_dcache_page(struct address_space *mapping, struct page *page struct machine_desc; void __init bootmem_init(struct machine_desc *); -void reserve_special_regions(void); +void arm_mm_memblock_reserve(void); diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c index 05dbb956175b..833a6c3f70c0 100644 --- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c @@ -11,9 +11,9 @@ #include #include #include -#include #include #include +#include #include #include @@ -489,7 +489,9 @@ static void __init build_mem_type_table(void) static void __init *early_alloc(unsigned long sz) { - return alloc_bootmem_low_pages(sz); + void *ptr = __va(memblock_alloc(sz, sz)); + memset(ptr, 0, sz); + return ptr; } static pte_t * __init early_pte_alloc(pmd_t *pmd, unsigned long addr, unsigned long prot) @@ -705,10 +707,14 @@ static int __init early_vmalloc(char *arg) } early_param("vmalloc", early_vmalloc); +phys_addr_t lowmem_end_addr; + static void __init sanity_check_meminfo(void) { int i, j, highmem = 0; + lowmem_end_addr = __pa(vmalloc_min - 1) + 1; + for (i = 0, j = 0; i < meminfo.nr_banks; i++) { struct membank *bank = &meminfo.bank[j]; *bank = meminfo.bank[i]; @@ -834,34 +840,22 @@ static inline void prepare_page_table(void) } /* - * Reserve the various regions + * Reserve the special regions of memory */ -void __init reserve_special_regions(void) +void __init arm_mm_memblock_reserve(void) { - /* - * Register the kernel text and data with bootmem. - * Note that this can only be in node 0. - */ -#ifdef CONFIG_XIP_KERNEL - reserve_bootmem(__pa(_data), _end - _data, BOOTMEM_DEFAULT); -#else - reserve_bootmem(__pa(_stext), _end - _stext, BOOTMEM_DEFAULT); -#endif - /* * Reserve the page tables. These are already in use, * and can only be in node 0. */ - reserve_bootmem(__pa(swapper_pg_dir), - PTRS_PER_PGD * sizeof(pgd_t), BOOTMEM_DEFAULT); + memblock_reserve(__pa(swapper_pg_dir), PTRS_PER_PGD * sizeof(pgd_t)); #ifdef CONFIG_SA1111 /* * Because of the SA1111 DMA bug, we want to preserve our * precious DMA-able memory... */ - reserve_bootmem(PHYS_OFFSET, __pa(swapper_pg_dir) - PHYS_OFFSET, - BOOTMEM_DEFAULT); + memblock_reserve(PHYS_OFFSET, __pa(swapper_pg_dir) - PHYS_OFFSET); #endif } @@ -1004,7 +998,6 @@ void __init paging_init(struct machine_desc *mdesc) sanity_check_meminfo(); prepare_page_table(); map_lowmem(); - bootmem_init(mdesc); devicemaps_init(mdesc); kmap_init(); @@ -1012,6 +1005,9 @@ void __init paging_init(struct machine_desc *mdesc) /* allocate the zero page. */ zero_page = early_alloc(PAGE_SIZE); + + bootmem_init(mdesc); + empty_zero_page = virt_to_page(zero_page); __flush_dcache_page(NULL, empty_zero_page); } diff --git a/arch/arm/mm/nommu.c b/arch/arm/mm/nommu.c index ed58ddbbc5b3..40e38fcccc7a 100644 --- a/arch/arm/mm/nommu.c +++ b/arch/arm/mm/nommu.c @@ -6,8 +6,8 @@ #include #include #include -#include #include +#include #include #include @@ -17,27 +17,14 @@ #include "mm.h" -/* - * Reserve the various regions - */ -void __init reserve_special_regions(void) +void __init arm_mm_memblock_reserve(void) { - /* - * Register the kernel text and data with bootmem. - * Note that this can only be in node 0. - */ -#ifdef CONFIG_XIP_KERNEL - reserve_bootmem(__pa(_data), _end - _data, BOOTMEM_DEFAULT); -#else - reserve_bootmem(__pa(_stext), _end - _stext, BOOTMEM_DEFAULT); -#endif - /* * Register the exception vector page. * some architectures which the DRAM is the exception vector to trap, * alloc_page breaks with error, although it is not NULL, but "0." */ - reserve_bootmem(CONFIG_VECTORS_BASE, PAGE_SIZE, BOOTMEM_DEFAULT); + memblock_reserve(CONFIG_VECTORS_BASE, PAGE_SIZE); } /* -- cgit v1.2.3 From 8d717a52d1b0959128be5134dd12608e8e4f2115 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sat, 22 May 2010 19:47:18 +0100 Subject: ARM: Convert platform reservations to use LMB rather than bootmem Signed-off-by: Russell King --- arch/arm/include/asm/memblock.h | 3 ++- arch/arm/kernel/setup.c | 2 +- arch/arm/mach-clps711x/edb7211-arch.c | 4 ++-- arch/arm/mach-integrator/core.c | 4 ++-- arch/arm/mach-pxa/palmt5.c | 4 ++-- arch/arm/mach-pxa/palmtreo.c | 6 +++--- arch/arm/mach-s3c2410/mach-h1940.c | 6 +++--- arch/arm/mach-s3c2440/mach-rx1950.c | 6 +++--- arch/arm/mach-s3c2440/mach-rx3715.c | 6 +++--- arch/arm/mach-u300/u300.c | 4 ++-- arch/arm/mm/init.c | 11 ++++++----- arch/arm/mm/mm.h | 3 +-- arch/arm/mm/mmu.c | 2 +- arch/arm/mm/nommu.c | 2 +- 14 files changed, 32 insertions(+), 31 deletions(-) (limited to 'arch/arm/include') diff --git a/arch/arm/include/asm/memblock.h b/arch/arm/include/asm/memblock.h index 3a1d58096f44..fdbc43b2e6c0 100644 --- a/arch/arm/include/asm/memblock.h +++ b/arch/arm/include/asm/memblock.h @@ -9,7 +9,8 @@ extern phys_addr_t lowmem_end_addr; #endif struct meminfo; +struct machine_desc; -extern void arm_memblock_init(struct meminfo *); +extern void arm_memblock_init(struct meminfo *, struct machine_desc *); #endif diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index dfd293477751..31b2643bb0c6 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c @@ -716,7 +716,7 @@ void __init setup_arch(char **cmdline_p) parse_early_param(); - arm_memblock_init(&meminfo); + arm_memblock_init(&meminfo, mdesc); paging_init(mdesc); request_standard_resources(&meminfo, mdesc); diff --git a/arch/arm/mach-clps711x/edb7211-arch.c b/arch/arm/mach-clps711x/edb7211-arch.c index 077f4051a06a..4a7a2322979a 100644 --- a/arch/arm/mach-clps711x/edb7211-arch.c +++ b/arch/arm/mach-clps711x/edb7211-arch.c @@ -18,7 +18,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include -#include +#include #include #include @@ -33,7 +33,7 @@ extern void edb7211_map_io(void); /* Reserve screen memory region at the start of main system memory. */ static void __init edb7211_reserve(void) { - reserve_bootmem(PHYS_OFFSET, 0x00020000, BOOTMEM_DEFAULT); + memblock_reserve(PHYS_OFFSET, 0x00020000); } static void __init diff --git a/arch/arm/mach-integrator/core.c b/arch/arm/mach-integrator/core.c index f815a1863f70..bcb26f01b26c 100644 --- a/arch/arm/mach-integrator/core.c +++ b/arch/arm/mach-integrator/core.c @@ -14,7 +14,7 @@ #include #include #include -#include +#include #include #include #include @@ -225,5 +225,5 @@ EXPORT_SYMBOL(cm_control); */ void __init integrator_reserve(void) { - reserve_bootmem(PHYS_OFFSET, __pa(swapper_pg_dir) - PHYS_OFFSET, BOOTMEM_DEFAULT); + memblock_reserve(PHYS_OFFSET, __pa(swapper_pg_dir) - PHYS_OFFSET); } diff --git a/arch/arm/mach-pxa/palmt5.c b/arch/arm/mach-pxa/palmt5.c index 39fd788ab63b..5e92d84fe50d 100644 --- a/arch/arm/mach-pxa/palmt5.c +++ b/arch/arm/mach-pxa/palmt5.c @@ -21,7 +21,7 @@ #include #include #include -#include +#include #include #include #include @@ -399,7 +399,7 @@ static void __init palmt5_udc_init(void) static void __init palmt5_reserve(void) { - reserve_bootmem(0xa0200000, 0x1000, BOOTMEM_EXCLUSIVE); + memblock_reserve(0xa0200000, 0x1000); } static void __init palmt5_init(void) diff --git a/arch/arm/mach-pxa/palmtreo.c b/arch/arm/mach-pxa/palmtreo.c index f5db4f7d7158..3d0c9cc2a406 100644 --- a/arch/arm/mach-pxa/palmtreo.c +++ b/arch/arm/mach-pxa/palmtreo.c @@ -20,7 +20,7 @@ #include #include #include -#include +#include #include #include #include @@ -636,8 +636,8 @@ static void __init treo_lcd_power_init(void) static void __init treo_reserve(void) { - reserve_bootmem(0xa0000000, 0x1000, BOOTMEM_EXCLUSIVE); - reserve_bootmem(0xa2000000, 0x1000, BOOTMEM_EXCLUSIVE); + memblock_reserve(0xa0000000, 0x1000); + memblock_reserve(0xa2000000, 0x1000); } static void __init treo_init(void) diff --git a/arch/arm/mach-s3c2410/mach-h1940.c b/arch/arm/mach-s3c2410/mach-h1940.c index 2407aab4d1b8..3ba3bab139d0 100644 --- a/arch/arm/mach-s3c2410/mach-h1940.c +++ b/arch/arm/mach-s3c2410/mach-h1940.c @@ -15,7 +15,7 @@ #include #include #include -#include +#include #include #include #include @@ -308,8 +308,8 @@ static void __init h1940_map_io(void) /* H1940 and RX3715 need to reserve this for suspend */ static void __init h1940_reserve(void) { - reserve_bootmem(0x30003000, 0x1000, BOOTMEM_DEFAULT); - reserve_bootmem(0x30081000, 0x1000, BOOTMEM_DEFAULT); + memblock_reserve(0x30003000, 0x1000); + memblock_reserve(0x30081000, 0x1000); } static void __init h1940_init_irq(void) diff --git a/arch/arm/mach-s3c2440/mach-rx1950.c b/arch/arm/mach-s3c2440/mach-rx1950.c index f26d5d60c13d..142d1f921176 100644 --- a/arch/arm/mach-s3c2440/mach-rx1950.c +++ b/arch/arm/mach-s3c2440/mach-rx1950.c @@ -15,7 +15,7 @@ #include #include #include -#include +#include #include #include #include @@ -574,8 +574,8 @@ static void __init rx1950_init_machine(void) /* H1940 and RX3715 need to reserve this for suspend */ static void __init rx1950_reserve(void) { - reserve_bootmem(0x30003000, 0x1000, BOOTMEM_DEFAULT); - reserve_bootmem(0x30081000, 0x1000, BOOTMEM_DEFAULT); + memblock_reserve(0x30003000, 0x1000); + memblock_reserve(0x30081000, 0x1000); } MACHINE_START(RX1950, "HP iPAQ RX1950") diff --git a/arch/arm/mach-s3c2440/mach-rx3715.c b/arch/arm/mach-s3c2440/mach-rx3715.c index 6ebdb7bcf085..6bb44f75a9ce 100644 --- a/arch/arm/mach-s3c2440/mach-rx3715.c +++ b/arch/arm/mach-s3c2440/mach-rx3715.c @@ -15,7 +15,7 @@ #include #include #include -#include +#include #include #include #include @@ -195,8 +195,8 @@ static void __init rx3715_map_io(void) /* H1940 and RX3715 need to reserve this for suspend */ static void __init rx3715_reserve(void) { - reserve_bootmem(0x30003000, 0x1000, BOOTMEM_DEFAULT); - reserve_bootmem(0x30081000, 0x1000, BOOTMEM_DEFAULT); + memblock_reserve(0x30003000, 0x1000); + memblock_reserve(0x30081000, 0x1000); } static void __init rx3715_init_irq(void) diff --git a/arch/arm/mach-u300/u300.c b/arch/arm/mach-u300/u300.c index 178dca4f9555..bfcda9820888 100644 --- a/arch/arm/mach-u300/u300.c +++ b/arch/arm/mach-u300/u300.c @@ -14,7 +14,7 @@ #include #include #include -#include +#include #include #include #include @@ -33,7 +33,7 @@ static void __init u300_reserve(void) #ifdef CONFIG_MACH_U300_SINGLE_RAM #if ((CONFIG_MACH_U300_ACCESS_MEM_SIZE & 1) == 1) && \ CONFIG_MACH_U300_2MB_ALIGNMENT_FIX - reserve_bootmem(PHYS_OFFSET, 0x00100000, BOOTMEM_DEFAULT); + memblock_reserve(PHYS_OFFSET, 0x00100000); #endif #endif } diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c index 4877e06308b7..99d6bc9b89bb 100644 --- a/arch/arm/mm/init.c +++ b/arch/arm/mm/init.c @@ -271,7 +271,7 @@ static void arm_memory_present(struct meminfo *mi) } #endif -void __init arm_memblock_init(struct meminfo *mi) +void __init arm_memblock_init(struct meminfo *mi, struct machine_desc *mdesc) { int i; @@ -297,11 +297,15 @@ void __init arm_memblock_init(struct meminfo *mi) arm_mm_memblock_reserve(); + /* reserve any platform specific memblock areas */ + if (mdesc->reserve) + mdesc->reserve(); + memblock_analyze(); memblock_dump_all(); } -void __init bootmem_init(struct machine_desc *mdesc) +void __init bootmem_init(void) { struct meminfo *mi = &meminfo; unsigned long min, max_low, max_high; @@ -312,9 +316,6 @@ void __init bootmem_init(struct machine_desc *mdesc) arm_bootmem_init(mi, min, max_low); - if (mdesc->reserve) - mdesc->reserve(); - /* * Sparsemem tries to allocate bootmem in memory_present(), * so must be done after the fixed reservations diff --git a/arch/arm/mm/mm.h b/arch/arm/mm/mm.h index fcfffae69b49..6630620380a4 100644 --- a/arch/arm/mm/mm.h +++ b/arch/arm/mm/mm.h @@ -28,6 +28,5 @@ extern void __flush_dcache_page(struct address_space *mapping, struct page *page #endif -struct machine_desc; -void __init bootmem_init(struct machine_desc *); +void __init bootmem_init(void); void arm_mm_memblock_reserve(void); diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c index 833a6c3f70c0..d5541adc3520 100644 --- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c @@ -1006,7 +1006,7 @@ void __init paging_init(struct machine_desc *mdesc) /* allocate the zero page. */ zero_page = early_alloc(PAGE_SIZE); - bootmem_init(mdesc); + bootmem_init(); empty_zero_page = virt_to_page(zero_page); __flush_dcache_page(NULL, empty_zero_page); diff --git a/arch/arm/mm/nommu.c b/arch/arm/mm/nommu.c index 40e38fcccc7a..687d02319a41 100644 --- a/arch/arm/mm/nommu.c +++ b/arch/arm/mm/nommu.c @@ -33,7 +33,7 @@ void __init arm_mm_memblock_reserve(void) */ void __init paging_init(struct machine_desc *mdesc) { - bootmem_init(mdesc); + bootmem_init(); } /* -- cgit v1.2.3 From 1dbd30e9890fd69e50b17edd70ca583546b0fe4e Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Mon, 12 Jul 2010 21:53:28 +0100 Subject: ARM: 6225/1: make TCM allocation static and common for all archs This changes the TCM handling so that a fixed area is reserved at 0xfffe0000-0xfffeffff for TCM. This areas is used by XScale but XScale does not have TCM so the mechanisms are mutually exclusive. This change is needed to make TCM detection more dynamic while still being able to compile code into it, and is a must for the unified ARM goals: the current TCM allocation at different places in memory for each machine would be a nightmare if you want to compile a single image for more than one machine with TCM so it has to be nailed down in one place. Signed-off-by: Linus Walleij Signed-off-by: Russell King --- Documentation/arm/memory.txt | 8 ++- Documentation/arm/tcm.txt | 30 +++++++---- arch/arm/include/asm/memory.h | 9 ++++ arch/arm/kernel/tcm.c | 91 +++++++++++++++++--------------- arch/arm/mach-u300/include/mach/memory.h | 8 --- arch/arm/mm/init.c | 17 +++--- 6 files changed, 90 insertions(+), 73 deletions(-) (limited to 'arch/arm/include') diff --git a/Documentation/arm/memory.txt b/Documentation/arm/memory.txt index eb0fae18ffb1..771d48d3b335 100644 --- a/Documentation/arm/memory.txt +++ b/Documentation/arm/memory.txt @@ -33,7 +33,13 @@ ffff0000 ffff0fff CPU vector page. fffe0000 fffeffff XScale cache flush area. This is used in proc-xscale.S to flush the whole data - cache. Free for other usage on non-XScale. + cache. (XScale does not have TCM.) + +fffe8000 fffeffff DTCM mapping area for platforms with + DTCM mounted inside the CPU. + +fffe0000 fffe7fff ITCM mapping area for platforms with + ITCM mounted inside the CPU. fff00000 fffdffff Fixmap mapping region. Addresses provided by fix_to_virt() will be located here. diff --git a/Documentation/arm/tcm.txt b/Documentation/arm/tcm.txt index 77fd9376e6d7..7c15871c1885 100644 --- a/Documentation/arm/tcm.txt +++ b/Documentation/arm/tcm.txt @@ -19,8 +19,8 @@ defines a CPUID_TCM register that you can read out from the system control coprocessor. Documentation from ARM can be found at http://infocenter.arm.com, search for "TCM Status Register" to see documents for all CPUs. Reading this register you can -determine if ITCM (bit 0) and/or DTCM (bit 16) is present in the -machine. +determine if ITCM (bits 1-0) and/or DTCM (bit 17-16) is present +in the machine. There is further a TCM region register (search for "TCM Region Registers" at the ARM site) that can report and modify the location @@ -35,7 +35,15 @@ The TCM memory can then be remapped to another address again using the MMU, but notice that the TCM if often used in situations where the MMU is turned off. To avoid confusion the current Linux implementation will map the TCM 1 to 1 from physical to virtual -memory in the location specified by the machine. +memory in the location specified by the kernel. Currently Linux +will map ITCM to 0xfffe0000 and on, and DTCM to 0xfffe8000 and +on, supporting a maximum of 32KiB of ITCM and 32KiB of DTCM. + +Newer versions of the region registers also support dividing these +TCMs in two separate banks, so for example an 8KiB ITCM is divided +into two 4KiB banks with its own control registers. The idea is to +be able to lock and hide one of the banks for use by the secure +world (TrustZone). TCM is used for a few things: @@ -65,18 +73,18 @@ in . Using this interface it is possible to: memory. Such a heap is great for things like saving device state when shutting off device power domains. -A machine that has TCM memory shall select HAVE_TCM in -arch/arm/Kconfig for itself, and then the -rest of the functionality will depend on the physical -location and size of ITCM and DTCM to be defined in -mach/memory.h for the machine. Code that needs to use -TCM shall #include If the TCM is not located -at the place given in memory.h it will be moved using -the TCM Region registers. +A machine that has TCM memory shall select HAVE_TCM from +arch/arm/Kconfig for itself. Code that needs to use TCM shall +#include Functions to go into itcm can be tagged like this: int __tcmfunc foo(int bar); +Since these are marked to become long_calls and you may want +to have functions called locally inside the TCM without +wasting space, there is also the __tcmlocalfunc prefix that +will make the call relative. + Variables to go into dtcm can be tagged like this: int __tcmdata foo; diff --git a/arch/arm/include/asm/memory.h b/arch/arm/include/asm/memory.h index 4312ee5e3d0b..ab08d977ad49 100644 --- a/arch/arm/include/asm/memory.h +++ b/arch/arm/include/asm/memory.h @@ -123,6 +123,15 @@ #endif /* !CONFIG_MMU */ +/* + * We fix the TCM memories max 32 KiB ITCM resp DTCM at these + * locations + */ +#ifdef CONFIG_HAVE_TCM +#define ITCM_OFFSET UL(0xfffe0000) +#define DTCM_OFFSET UL(0xfffe8000) +#endif + /* * Physical vs virtual RAM address space conversion. These are * private definitions which should NOT be used outside memory.h diff --git a/arch/arm/kernel/tcm.c b/arch/arm/kernel/tcm.c index f2ead32c1aa0..26685c2f7a49 100644 --- a/arch/arm/kernel/tcm.c +++ b/arch/arm/kernel/tcm.c @@ -18,32 +18,30 @@ #include #include "tcm.h" -/* Scream and warn about misuse */ -#if !defined(ITCM_OFFSET) || !defined(ITCM_END) || \ - !defined(DTCM_OFFSET) || !defined(DTCM_END) -#error "TCM support selected but offsets not defined!" -#endif - static struct gen_pool *tcm_pool; /* TCM section definitions from the linker */ extern char __itcm_start, __sitcm_text, __eitcm_text; extern char __dtcm_start, __sdtcm_data, __edtcm_data; +/* These will be increased as we run */ +u32 dtcm_end = DTCM_OFFSET; +u32 itcm_end = ITCM_OFFSET; + /* * TCM memory resources */ static struct resource dtcm_res = { .name = "DTCM RAM", .start = DTCM_OFFSET, - .end = DTCM_END, + .end = DTCM_OFFSET, .flags = IORESOURCE_MEM }; static struct resource itcm_res = { .name = "ITCM RAM", .start = ITCM_OFFSET, - .end = ITCM_END, + .end = ITCM_OFFSET, .flags = IORESOURCE_MEM }; @@ -51,7 +49,7 @@ static struct map_desc dtcm_iomap[] __initdata = { { .virtual = DTCM_OFFSET, .pfn = __phys_to_pfn(DTCM_OFFSET), - .length = (DTCM_END - DTCM_OFFSET + 1), + .length = 0, .type = MT_MEMORY_DTCM } }; @@ -60,7 +58,7 @@ static struct map_desc itcm_iomap[] __initdata = { { .virtual = ITCM_OFFSET, .pfn = __phys_to_pfn(ITCM_OFFSET), - .length = (ITCM_END - ITCM_OFFSET + 1), + .length = 0, .type = MT_MEMORY_ITCM } }; @@ -92,8 +90,8 @@ void tcm_free(void *addr, size_t len) } EXPORT_SYMBOL(tcm_free); -static void __init setup_tcm_bank(u8 type, u8 bank, u8 banks, - u32 offset, u32 expected_size) +static int __init setup_tcm_bank(u8 type, u8 bank, u8 banks, + u32 *offset) { const int tcm_sizes[16] = { 0, -1, -1, 4, 8, 16, 32, 64, 128, 256, 512, 1024, -1, -1, -1, -1 }; @@ -120,8 +118,13 @@ static void __init setup_tcm_bank(u8 type, u8 bank, u8 banks, tcm_size = tcm_sizes[(tcm_region >> 2) & 0x0f]; if (tcm_size < 0) { - pr_err("CPU: %sTCM%d of unknown size!\n", + pr_err("CPU: %sTCM%d of unknown size\n", type ? "I" : "D", bank); + return -EINVAL; + } else if (tcm_size > 32) { + pr_err("CPU: %sTCM%d larger than 32k found\n", + type ? "I" : "D", bank); + return -EINVAL; } else { pr_info("CPU: found %sTCM%d %dk @ %08x, %senabled\n", type ? "I" : "D", @@ -131,17 +134,8 @@ static void __init setup_tcm_bank(u8 type, u8 bank, u8 banks, (tcm_region & 1) ? "" : "not "); } - if (tcm_size != (expected_size >> 10)) { - pr_crit("CPU: %sTCM%d was detected %dk but expected %dk!\n", - type ? "I" : "D", - bank, - tcm_size, - (expected_size >> 10)); - /* Adjust to the expected size? what can we do... */ - } - /* Force move the TCM bank to where we want it, enable */ - tcm_region = offset | (tcm_region & 0x00000ffeU) | 1; + tcm_region = *offset | (tcm_region & 0x00000ffeU) | 1; if (!type) asm("mcr p15, 0, %0, c9, c1, 0" @@ -152,17 +146,17 @@ static void __init setup_tcm_bank(u8 type, u8 bank, u8 banks, : /* No output operands */ : "r" (tcm_region)); + /* Increase offset */ + *offset += (tcm_size << 10); + pr_info("CPU: moved %sTCM%d %dk to %08x, enabled\n", type ? "I" : "D", bank, tcm_size, (tcm_region & 0xfffff000U)); + return 0; } -/* We expect to find what is configured for the platform */ -#define DTCM_EXPECTED (DTCM_END - DTCM_OFFSET + 1) -#define ITCM_EXPECTED (ITCM_END - ITCM_OFFSET + 1) - /* * This initializes the TCM memory */ @@ -170,40 +164,51 @@ void __init tcm_init(void) { u32 tcm_status = read_cpuid_tcmstatus(); u8 dtcm_banks = (tcm_status >> 16) & 0x03; - u32 dtcm_banksize = DTCM_EXPECTED / dtcm_banks; u8 itcm_banks = (tcm_status & 0x03); - u32 itcm_banksize = ITCM_EXPECTED / itcm_banks; char *start; char *end; char *ram; + int ret; int i; /* Setup DTCM if present */ - for (i = 0; i < dtcm_banks; i++) { - setup_tcm_bank(0, i, dtcm_banks, - DTCM_OFFSET + (i * dtcm_banksize), - dtcm_banksize); + if (dtcm_banks > 0) { + for (i = 0; i < dtcm_banks; i++) { + ret = setup_tcm_bank(0, i, dtcm_banks, &dtcm_end); + if (ret) + return; + } + dtcm_res.end = dtcm_end - 1; request_resource(&iomem_resource, &dtcm_res); + dtcm_iomap[0].length = dtcm_end - DTCM_OFFSET; iotable_init(dtcm_iomap, 1); /* Copy data from RAM to DTCM */ start = &__sdtcm_data; end = &__edtcm_data; ram = &__dtcm_start; + /* This means you compiled more code than fits into DTCM */ + BUG_ON((end - start) > (dtcm_end - DTCM_OFFSET)); memcpy(start, ram, (end-start)); pr_debug("CPU DTCM: copied data from %p - %p\n", start, end); } /* Setup ITCM if present */ - for (i = 0; i < itcm_banks; i++) { - setup_tcm_bank(1, i, itcm_banks, - ITCM_OFFSET + (i * itcm_banksize), - itcm_banksize); + if (itcm_banks > 0) { + for (i = 0; i < itcm_banks; i++) { + ret = setup_tcm_bank(1, i, itcm_banks, &itcm_end); + if (ret) + return; + } + itcm_res.end = itcm_end - 1; request_resource(&iomem_resource, &itcm_res); + itcm_iomap[0].length = itcm_end - ITCM_OFFSET; iotable_init(itcm_iomap, 1); /* Copy code from RAM to ITCM */ start = &__sitcm_text; end = &__eitcm_text; ram = &__itcm_start; + /* This means you compiled more code than fits into ITCM */ + BUG_ON((end - start) > (itcm_end - ITCM_OFFSET)); memcpy(start, ram, (end-start)); pr_debug("CPU ITCM: copied code from %p - %p\n", start, end); } @@ -232,9 +237,9 @@ static int __init setup_tcm_pool(void) /* Add the rest of DTCM to the TCM pool */ if (tcm_status & (0x03 << 16)) { - if (dtcm_pool_start < DTCM_END) { + if (dtcm_pool_start < dtcm_end) { ret = gen_pool_add(tcm_pool, dtcm_pool_start, - DTCM_END - dtcm_pool_start + 1, -1); + dtcm_end - dtcm_pool_start, -1); if (ret) { pr_err("CPU DTCM: could not add DTCM " \ "remainder to pool!\n"); @@ -242,16 +247,16 @@ static int __init setup_tcm_pool(void) } pr_debug("CPU DTCM: Added %08x bytes @ %08x to " \ "the TCM memory pool\n", - DTCM_END - dtcm_pool_start + 1, + dtcm_end - dtcm_pool_start, dtcm_pool_start); } } /* Add the rest of ITCM to the TCM pool */ if (tcm_status & 0x03) { - if (itcm_pool_start < ITCM_END) { + if (itcm_pool_start < itcm_end) { ret = gen_pool_add(tcm_pool, itcm_pool_start, - ITCM_END - itcm_pool_start + 1, -1); + itcm_end - itcm_pool_start, -1); if (ret) { pr_err("CPU ITCM: could not add ITCM " \ "remainder to pool!\n"); @@ -259,7 +264,7 @@ static int __init setup_tcm_pool(void) } pr_debug("CPU ITCM: Added %08x bytes @ %08x to " \ "the TCM memory pool\n", - ITCM_END - itcm_pool_start + 1, + itcm_end - itcm_pool_start, itcm_pool_start); } } diff --git a/arch/arm/mach-u300/include/mach/memory.h b/arch/arm/mach-u300/include/mach/memory.h index ab000df7fc03..bf134bcc129d 100644 --- a/arch/arm/mach-u300/include/mach/memory.h +++ b/arch/arm/mach-u300/include/mach/memory.h @@ -34,14 +34,6 @@ (CONFIG_MACH_U300_ACCESS_MEM_SIZE & 1))*1024*1024 + 0x100) #endif -/* - * TCM memory whereabouts - */ -#define ITCM_OFFSET 0xffff2000 -#define ITCM_END 0xffff3fff -#define DTCM_OFFSET 0xffff4000 -#define DTCM_END 0xffff5fff - /* * We enable a real big DMA buffer if need be. */ diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c index 526af48b1271..e00404e6f45b 100644 --- a/arch/arm/mm/init.c +++ b/arch/arm/mm/init.c @@ -529,6 +529,11 @@ void __init mem_init(void) { unsigned long reserved_pages, free_pages; int i, node; +#ifdef CONFIG_HAVE_TCM + /* These pointers are filled in on TCM detection */ + extern u32 dtcm_end; + extern u32 itcm_end; +#endif #ifndef CONFIG_DISCONTIGMEM max_mapnr = pfn_to_page(max_pfn + PHYS_PFN_OFFSET) - mem_map; @@ -612,12 +617,8 @@ void __init mem_init(void) printk(KERN_NOTICE "Virtual kernel memory layout:\n" " vector : 0x%08lx - 0x%08lx (%4ld kB)\n" #ifdef CONFIG_HAVE_TCM -#ifdef DTCM_OFFSET " DTCM : 0x%08lx - 0x%08lx (%4ld kB)\n" -#endif -#ifdef ITCM_OFFSET " ITCM : 0x%08lx - 0x%08lx (%4ld kB)\n" -#endif #endif " fixmap : 0x%08lx - 0x%08lx (%4ld kB)\n" #ifdef CONFIG_MMU @@ -636,12 +637,8 @@ void __init mem_init(void) MLK(UL(CONFIG_VECTORS_BASE), UL(CONFIG_VECTORS_BASE) + (PAGE_SIZE)), #ifdef CONFIG_HAVE_TCM -#ifdef DTCM_OFFSET - MLK(UL(DTCM_OFFSET), UL(DTCM_END + 1)), -#endif -#ifdef ITCM_OFFSET - MLK(UL(ITCM_OFFSET), UL(ITCM_END + 1)), -#endif + MLK(DTCM_OFFSET, (unsigned long) dtcm_end), + MLK(ITCM_OFFSET, (unsigned long) itcm_end), #endif MLK(FIXADDR_START, FIXADDR_TOP), #ifdef CONFIG_MMU -- cgit v1.2.3 From 6338a6aa7c082f11d55712251e14178c68bf5869 Mon Sep 17 00:00:00 2001 From: "Kirill A. Shutemov" Date: Thu, 22 Jul 2010 13:18:19 +0100 Subject: ARM: 6269/1: Add 'code' parameter for hook_fault_code() Add one more parameter to hook_fault_code() to be able to set 'code' field of struct fsr_info. Signed-off-by: Kirill A. Shutemov Signed-off-by: Russell King --- arch/arm/include/asm/system.h | 2 +- arch/arm/mach-integrator/pci_v3.c | 8 ++++---- arch/arm/mach-iop13xx/pci.c | 2 +- arch/arm/mach-ixp2000/pci.c | 2 +- arch/arm/mach-ixp23xx/pci.c | 2 +- arch/arm/mach-ixp4xx/common-pci.c | 3 ++- arch/arm/mach-ks8695/pci.c | 4 ++-- arch/arm/mm/alignment.c | 6 ++++-- arch/arm/mm/fault.c | 14 ++++++++------ arch/arm/plat-iop/pci.c | 2 +- 10 files changed, 25 insertions(+), 20 deletions(-) (limited to 'arch/arm/include') diff --git a/arch/arm/include/asm/system.h b/arch/arm/include/asm/system.h index 5f4f48002734..8ba1ccf82a02 100644 --- a/arch/arm/include/asm/system.h +++ b/arch/arm/include/asm/system.h @@ -83,7 +83,7 @@ void arm_notify_die(const char *str, struct pt_regs *regs, struct siginfo *info, void hook_fault_code(int nr, int (*fn)(unsigned long, unsigned int, struct pt_regs *), - int sig, const char *name); + int sig, int code, const char *name); #define xchg(ptr,x) \ ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr)))) diff --git a/arch/arm/mach-integrator/pci_v3.c b/arch/arm/mach-integrator/pci_v3.c index 9cef0590d5aa..6467d99fa2ee 100644 --- a/arch/arm/mach-integrator/pci_v3.c +++ b/arch/arm/mach-integrator/pci_v3.c @@ -505,10 +505,10 @@ void __init pci_v3_preinit(void) /* * Hook in our fault handler for PCI errors */ - hook_fault_code(4, v3_pci_fault, SIGBUS, "external abort on linefetch"); - hook_fault_code(6, v3_pci_fault, SIGBUS, "external abort on linefetch"); - hook_fault_code(8, v3_pci_fault, SIGBUS, "external abort on non-linefetch"); - hook_fault_code(10, v3_pci_fault, SIGBUS, "external abort on non-linefetch"); + hook_fault_code(4, v3_pci_fault, SIGBUS, 0, "external abort on linefetch"); + hook_fault_code(6, v3_pci_fault, SIGBUS, 0, "external abort on linefetch"); + hook_fault_code(8, v3_pci_fault, SIGBUS, 0, "external abort on non-linefetch"); + hook_fault_code(10, v3_pci_fault, SIGBUS, 0, "external abort on non-linefetch"); spin_lock_irqsave(&v3_lock, flags); diff --git a/arch/arm/mach-iop13xx/pci.c b/arch/arm/mach-iop13xx/pci.c index 6d5a90813d31..773ea0c95b9f 100644 --- a/arch/arm/mach-iop13xx/pci.c +++ b/arch/arm/mach-iop13xx/pci.c @@ -987,7 +987,7 @@ void __init iop13xx_pci_init(void) iop13xx_atux_setup(); } - hook_fault_code(16+6, iop13xx_pci_abort, SIGBUS, + hook_fault_code(16+6, iop13xx_pci_abort, SIGBUS, 0, "imprecise external abort"); } diff --git a/arch/arm/mach-ixp2000/pci.c b/arch/arm/mach-ixp2000/pci.c index 90771cad06f8..f797c5f538b0 100644 --- a/arch/arm/mach-ixp2000/pci.c +++ b/arch/arm/mach-ixp2000/pci.c @@ -209,7 +209,7 @@ ixp2000_pci_preinit(void) "the needed workaround has not been configured in"); #endif - hook_fault_code(16+6, ixp2000_pci_abort_handler, SIGBUS, + hook_fault_code(16+6, ixp2000_pci_abort_handler, SIGBUS, 0, "PCI config cycle to non-existent device"); } diff --git a/arch/arm/mach-ixp23xx/pci.c b/arch/arm/mach-ixp23xx/pci.c index 4b0e598a91c9..563819a83292 100644 --- a/arch/arm/mach-ixp23xx/pci.c +++ b/arch/arm/mach-ixp23xx/pci.c @@ -229,7 +229,7 @@ void __init ixp23xx_pci_preinit(void) { ixp23xx_pci_common_init(); - hook_fault_code(16+6, ixp23xx_pci_abort_handler, SIGBUS, + hook_fault_code(16+6, ixp23xx_pci_abort_handler, SIGBUS, 0, "PCI config cycle to non-existent device"); *IXP23XX_PCI_ADDR_EXT = 0x0000e000; diff --git a/arch/arm/mach-ixp4xx/common-pci.c b/arch/arm/mach-ixp4xx/common-pci.c index e3181534c7f9..f4fbb5ec645b 100644 --- a/arch/arm/mach-ixp4xx/common-pci.c +++ b/arch/arm/mach-ixp4xx/common-pci.c @@ -382,7 +382,8 @@ void __init ixp4xx_pci_preinit(void) /* hook in our fault handler for PCI errors */ - hook_fault_code(16+6, abort_handler, SIGBUS, "imprecise external abort"); + hook_fault_code(16+6, abort_handler, SIGBUS, 0, + "imprecise external abort"); pr_debug("setup PCI-AHB(inbound) and AHB-PCI(outbound) address mappings\n"); diff --git a/arch/arm/mach-ks8695/pci.c b/arch/arm/mach-ks8695/pci.c index 78499667eb7b..5fcd082a17f9 100644 --- a/arch/arm/mach-ks8695/pci.c +++ b/arch/arm/mach-ks8695/pci.c @@ -268,8 +268,8 @@ static void __init ks8695_pci_preinit(void) __raw_writel(0, KS8695_PCI_VA + KS8695_PIOBAC); /* hook in fault handlers */ - hook_fault_code(8, ks8695_pci_fault, SIGBUS, "external abort on non-linefetch"); - hook_fault_code(10, ks8695_pci_fault, SIGBUS, "external abort on non-linefetch"); + hook_fault_code(8, ks8695_pci_fault, SIGBUS, 0, "external abort on non-linefetch"); + hook_fault_code(10, ks8695_pci_fault, SIGBUS, 0, "external abort on non-linefetch"); } static void ks8695_show_pciregs(void) diff --git a/arch/arm/mm/alignment.c b/arch/arm/mm/alignment.c index 53a609680c10..77cfdbed9501 100644 --- a/arch/arm/mm/alignment.c +++ b/arch/arm/mm/alignment.c @@ -924,8 +924,10 @@ static int __init alignment_init(void) ai_usermode = UM_FIXUP; } - hook_fault_code(1, do_alignment, SIGBUS, "alignment exception"); - hook_fault_code(3, do_alignment, SIGBUS, "alignment exception"); + hook_fault_code(1, do_alignment, SIGBUS, BUS_ADRALN, + "alignment exception"); + hook_fault_code(3, do_alignment, SIGBUS, BUS_ADRALN, + "alignment exception"); return 0; } diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c index ce6f3a422c81..84131c832430 100644 --- a/arch/arm/mm/fault.c +++ b/arch/arm/mm/fault.c @@ -508,13 +508,15 @@ static struct fsr_info { void __init hook_fault_code(int nr, int (*fn)(unsigned long, unsigned int, struct pt_regs *), - int sig, const char *name) + int sig, int code, const char *name) { - if (nr >= 0 && nr < ARRAY_SIZE(fsr_info)) { - fsr_info[nr].fn = fn; - fsr_info[nr].sig = sig; - fsr_info[nr].name = name; - } + if (nr < 0 || nr >= ARRAY_SIZE(fsr_info)) + BUG(); + + fsr_info[nr].fn = fn; + fsr_info[nr].sig = sig; + fsr_info[nr].code = code; + fsr_info[nr].name = name; } /* diff --git a/arch/arm/plat-iop/pci.c b/arch/arm/plat-iop/pci.c index ce31f316ac75..43f2b158237c 100644 --- a/arch/arm/plat-iop/pci.c +++ b/arch/arm/plat-iop/pci.c @@ -359,7 +359,7 @@ static void __init iop3xx_atu_debug(void) DBG("ATU: IOP3XX_ATUCMD=0x%04x\n", *IOP3XX_ATUCMD); DBG("ATU: IOP3XX_ATUCR=0x%08x\n", *IOP3XX_ATUCR); - hook_fault_code(16+6, iop3xx_pci_abort, SIGBUS, "imprecise external abort"); + hook_fault_code(16+6, iop3xx_pci_abort, SIGBUS, 0, "imprecise external abort"); } /* for platforms that might be host-bus-adapters */ -- cgit v1.2.3 From e936771a76a7b61ca55a5142a3de835c2e196871 Mon Sep 17 00:00:00 2001 From: Catalin Marinas Date: Wed, 28 Jul 2010 22:00:54 +0100 Subject: ARM: 6271/1: Introduce *_relaxed() I/O accessors This patch introduces readl*_relaxed()/write*_relaxed() as the main I/O accessors (when __mem_pci is defined). The standard read*()/write*() macros are now based on the relaxed accessors. This patch is in preparation for a subsequent patch which adds barriers to the I/O accessors. Signed-off-by: Catalin Marinas Signed-off-by: Russell King --- arch/arm/include/asm/io.h | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) (limited to 'arch/arm/include') diff --git a/arch/arm/include/asm/io.h b/arch/arm/include/asm/io.h index c980156f3263..9db072df2b3d 100644 --- a/arch/arm/include/asm/io.h +++ b/arch/arm/include/asm/io.h @@ -179,25 +179,30 @@ extern void _memset_io(volatile void __iomem *, int, size_t); * IO port primitives for more information. */ #ifdef __mem_pci -#define readb(c) ({ __u8 __v = __raw_readb(__mem_pci(c)); __v; }) -#define readw(c) ({ __u16 __v = le16_to_cpu((__force __le16) \ +#define readb_relaxed(c) ({ u8 __v = __raw_readb(__mem_pci(c)); __v; }) +#define readw_relaxed(c) ({ u16 __v = le16_to_cpu((__force __le16) \ __raw_readw(__mem_pci(c))); __v; }) -#define readl(c) ({ __u32 __v = le32_to_cpu((__force __le32) \ +#define readl_relaxed(c) ({ u32 __v = le32_to_cpu((__force __le32) \ __raw_readl(__mem_pci(c))); __v; }) -#define readb_relaxed(addr) readb(addr) -#define readw_relaxed(addr) readw(addr) -#define readl_relaxed(addr) readl(addr) + +#define writeb_relaxed(v,c) ((void)__raw_writeb(v,__mem_pci(c))) +#define writew_relaxed(v,c) ((void)__raw_writew((__force u16) \ + cpu_to_le16(v),__mem_pci(c))) +#define writel_relaxed(v,c) ((void)__raw_writel((__force u32) \ + cpu_to_le32(v),__mem_pci(c))) + +#define readb(c) readb_relaxed(c) +#define readw(c) readw_relaxed(c) +#define readl(c) readl_relaxed(c) + +#define writeb(v,c) writeb_relaxed(v,c) +#define writew(v,c) writew_relaxed(v,c) +#define writel(v,c) writel_relaxed(v,c) #define readsb(p,d,l) __raw_readsb(__mem_pci(p),d,l) #define readsw(p,d,l) __raw_readsw(__mem_pci(p),d,l) #define readsl(p,d,l) __raw_readsl(__mem_pci(p),d,l) -#define writeb(v,c) __raw_writeb(v,__mem_pci(c)) -#define writew(v,c) __raw_writew((__force __u16) \ - cpu_to_le16(v),__mem_pci(c)) -#define writel(v,c) __raw_writel((__force __u32) \ - cpu_to_le32(v),__mem_pci(c)) - #define writesb(p,d,l) __raw_writesb(__mem_pci(p),d,l) #define writesw(p,d,l) __raw_writesw(__mem_pci(p),d,l) #define writesl(p,d,l) __raw_writesl(__mem_pci(p),d,l) -- cgit v1.2.3 From 79f64dbf68c8a9779a7e9a25e0a9f0217a25b57a Mon Sep 17 00:00:00 2001 From: Catalin Marinas Date: Wed, 28 Jul 2010 22:01:55 +0100 Subject: ARM: 6273/1: Add barriers to the I/O accessors if ARM_DMA_MEM_BUFFERABLE When the coherent DMA buffers are mapped as Normal Non-cacheable (ARM_DMA_MEM_BUFFERABLE enabled), buffer accesses are no longer ordered with Device memory accesses causing failures in device drivers that do not use the mandatory memory barriers before starting a DMA transfer. LKML discussions led to the conclusion that such barriers have to be added to the I/O accessors: http://thread.gmane.org/gmane.linux.kernel/683509/focus=686153 http://thread.gmane.org/gmane.linux.ide/46414 http://thread.gmane.org/gmane.linux.kernel.cross-arch/5250 This patch introduces a wmb() barrier to the write*() I/O accessors to handle the situations where Normal Non-cacheable writes are still in the processor (or L2 cache controller) write buffer before a DMA transfer command is issued. For the read*() accessors, a rmb() is introduced after the I/O to avoid speculative loads where the driver polls for a DMA transfer ready bit. Signed-off-by: Catalin Marinas Signed-off-by: Russell King --- arch/arm/include/asm/io.h | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'arch/arm/include') diff --git a/arch/arm/include/asm/io.h b/arch/arm/include/asm/io.h index 9db072df2b3d..3c91e7c80c29 100644 --- a/arch/arm/include/asm/io.h +++ b/arch/arm/include/asm/io.h @@ -26,6 +26,7 @@ #include #include #include +#include /* * ISA I/O bus memory addresses are 1:1 with the physical address. @@ -191,6 +192,15 @@ extern void _memset_io(volatile void __iomem *, int, size_t); #define writel_relaxed(v,c) ((void)__raw_writel((__force u32) \ cpu_to_le32(v),__mem_pci(c))) +#ifdef CONFIG_ARM_DMA_MEM_BUFFERABLE +#define readb(c) ({ u8 __v = readb_relaxed(c); rmb(); __v; }) +#define readw(c) ({ u16 __v = readw_relaxed(c); rmb(); __v; }) +#define readl(c) ({ u32 __v = readl_relaxed(c); rmb(); __v; }) + +#define writeb(v,c) ({ wmb(); writeb_relaxed(v,c); }) +#define writew(v,c) ({ wmb(); writew_relaxed(v,c); }) +#define writel(v,c) ({ wmb(); writel_relaxed(v,c); }) +#else #define readb(c) readb_relaxed(c) #define readw(c) readw_relaxed(c) #define readl(c) readl_relaxed(c) @@ -198,6 +208,7 @@ extern void _memset_io(volatile void __iomem *, int, size_t); #define writeb(v,c) writeb_relaxed(v,c) #define writew(v,c) writew_relaxed(v,c) #define writel(v,c) writel_relaxed(v,c) +#endif #define readsb(p,d,l) __raw_readsb(__mem_pci(p),d,l) #define readsw(p,d,l) __raw_readsw(__mem_pci(p),d,l) -- cgit v1.2.3 From b92b3612134faff171981fad4f0adb33f485e02e Mon Sep 17 00:00:00 2001 From: Russell King Date: Thu, 29 Jul 2010 11:38:05 +0100 Subject: ARM: Add barriers to io{read,write}{8,16,32} accessors as well The ioread/iowrite accessors also need barriers as they're used in place of readl/writel et.al. in portable drivers. Create __iormb() and __iowmb() which are conditionally defined to be barriers dependent on ARM_DMA_MEM_BUFFERABLE, and always use these macros in the accessors. Signed-off-by: Russell King --- arch/arm/include/asm/io.h | 38 ++++++++++++++++++-------------------- 1 file changed, 18 insertions(+), 20 deletions(-) (limited to 'arch/arm/include') diff --git a/arch/arm/include/asm/io.h b/arch/arm/include/asm/io.h index 3c91e7c80c29..1261b1f928d9 100644 --- a/arch/arm/include/asm/io.h +++ b/arch/arm/include/asm/io.h @@ -193,23 +193,21 @@ extern void _memset_io(volatile void __iomem *, int, size_t); cpu_to_le32(v),__mem_pci(c))) #ifdef CONFIG_ARM_DMA_MEM_BUFFERABLE -#define readb(c) ({ u8 __v = readb_relaxed(c); rmb(); __v; }) -#define readw(c) ({ u16 __v = readw_relaxed(c); rmb(); __v; }) -#define readl(c) ({ u32 __v = readl_relaxed(c); rmb(); __v; }) - -#define writeb(v,c) ({ wmb(); writeb_relaxed(v,c); }) -#define writew(v,c) ({ wmb(); writew_relaxed(v,c); }) -#define writel(v,c) ({ wmb(); writel_relaxed(v,c); }) +#define __iormb() rmb() +#define __iowmb() wmb() #else -#define readb(c) readb_relaxed(c) -#define readw(c) readw_relaxed(c) -#define readl(c) readl_relaxed(c) - -#define writeb(v,c) writeb_relaxed(v,c) -#define writew(v,c) writew_relaxed(v,c) -#define writel(v,c) writel_relaxed(v,c) +#define __iormb() do { } while (0) +#define __iowmb() do { } while (0) #endif +#define readb(c) ({ u8 __v = readb_relaxed(c); __iormb(); __v; }) +#define readw(c) ({ u16 __v = readw_relaxed(c); __iormb(); __v; }) +#define readl(c) ({ u32 __v = readl_relaxed(c); __iormb(); __v; }) + +#define writeb(v,c) ({ __iowmb(); writeb_relaxed(v,c); }) +#define writew(v,c) ({ __iowmb(); writew_relaxed(v,c); }) +#define writel(v,c) ({ __iowmb(); writel_relaxed(v,c); }) + #define readsb(p,d,l) __raw_readsb(__mem_pci(p),d,l) #define readsw(p,d,l) __raw_readsw(__mem_pci(p),d,l) #define readsl(p,d,l) __raw_readsl(__mem_pci(p),d,l) @@ -260,13 +258,13 @@ extern void _memset_io(volatile void __iomem *, int, size_t); * io{read,write}{8,16,32} macros */ #ifndef ioread8 -#define ioread8(p) ({ unsigned int __v = __raw_readb(p); __v; }) -#define ioread16(p) ({ unsigned int __v = le16_to_cpu((__force __le16)__raw_readw(p)); __v; }) -#define ioread32(p) ({ unsigned int __v = le32_to_cpu((__force __le32)__raw_readl(p)); __v; }) +#define ioread8(p) ({ unsigned int __v = __raw_readb(p); __iormb(); __v; }) +#define ioread16(p) ({ unsigned int __v = le16_to_cpu((__force __le16)__raw_readw(p)); __iormb(); __v; }) +#define ioread32(p) ({ unsigned int __v = le32_to_cpu((__force __le32)__raw_readl(p)); __iormb(); __v; }) -#define iowrite8(v,p) __raw_writeb(v, p) -#define iowrite16(v,p) __raw_writew((__force __u16)cpu_to_le16(v), p) -#define iowrite32(v,p) __raw_writel((__force __u32)cpu_to_le32(v), p) +#define iowrite8(v,p) ({ __iowmb(); (void)__raw_writeb(v, p); }) +#define iowrite16(v,p) ({ __iowmb(); (void)__raw_writew((__force __u16)cpu_to_le16(v), p); }) +#define iowrite32(v,p) ({ __iowmb(); (void)__raw_writel((__force __u32)cpu_to_le32(v), p); }) #define ioread8_rep(p,d,c) __raw_readsb(p,d,c) #define ioread16_rep(p,d,c) __raw_readsw(p,d,c) -- cgit v1.2.3 From 4fa5518c65df7a2c4b6c58061ac53d0b01228042 Mon Sep 17 00:00:00 2001 From: Eric Miao Date: Sat, 5 Jun 2010 15:16:17 +0800 Subject: [ARM] pxa: remove now unnecessary dma_needs_bounce() With a correct dev->dma_mask before calling dmabounce_register_dev(), dma_needs_bounce() is not necessary. The sa1111, though, is a bit complicated. Until it's fully understood and fixed, dma_needs_bounce() for sa1111 is kept if CONFIG_SA1111 is enabled with no side effect (with the condition of machine_is_*) Thanks for Mike Rapoport to fix one error in the original version of the patch and get this tested. Acked-by: Mike Rapoport Signed-off-by: Eric Miao --- arch/arm/common/it8152.c | 8 -------- arch/arm/include/asm/dma-mapping.h | 8 ++++++++ 2 files changed, 8 insertions(+), 8 deletions(-) (limited to 'arch/arm/include') diff --git a/arch/arm/common/it8152.c b/arch/arm/common/it8152.c index 7974baacafce..6c0913562455 100644 --- a/arch/arm/common/it8152.c +++ b/arch/arm/common/it8152.c @@ -263,14 +263,6 @@ static int it8152_pci_platform_notify_remove(struct device *dev) return 0; } -int dma_needs_bounce(struct device *dev, dma_addr_t dma_addr, size_t size) -{ - dev_dbg(dev, "%s: dma_addr %08x, size %08x\n", - __func__, dma_addr, size); - return (dev->bus == &pci_bus_type) && - ((dma_addr + size - PHYS_OFFSET) >= SZ_64M); -} - int __init it8152_pci_setup(int nr, struct pci_sys_data *sys) { it8152_io.start = IT8152_IO_BASE + 0x12000; diff --git a/arch/arm/include/asm/dma-mapping.h b/arch/arm/include/asm/dma-mapping.h index 69ce0727edb5..b5ccc6a993d5 100644 --- a/arch/arm/include/asm/dma-mapping.h +++ b/arch/arm/include/asm/dma-mapping.h @@ -298,7 +298,15 @@ extern void dmabounce_unregister_dev(struct device *); * DMA access and 1 if the buffer needs to be bounced. * */ +#ifdef CONFIG_SA1111 extern int dma_needs_bounce(struct device*, dma_addr_t, size_t); +#else +static inline int dma_needs_bounce(struct device *dev, dma_addr_t addr, + size_t size) +{ + return 0; +} +#endif /* * The DMA API, implemented by dmabounce.c. See below for descriptions. -- cgit v1.2.3 From 983536e7b5275d5d8a63c18b5632d9ce0771caa0 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Thu, 24 Jun 2010 16:02:11 +0200 Subject: [ARM] scoop: Add CPR register bit definitions Add bit definitions of the CPR register of the SCOOP chip into scoop.h. Also, cleanup the GPCR definitions to match coding style. Signed-off-by: Marek Vasut Signed-off-by: Eric Miao --- arch/arm/include/asm/hardware/scoop.h | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) (limited to 'arch/arm/include') diff --git a/arch/arm/include/asm/hardware/scoop.h b/arch/arm/include/asm/hardware/scoop.h index 46492a63a7c4..ebb3ceaa8fac 100644 --- a/arch/arm/include/asm/hardware/scoop.h +++ b/arch/arm/include/asm/hardware/scoop.h @@ -22,18 +22,23 @@ #define SCOOP_GPWR 0x24 #define SCOOP_GPRR 0x28 -#define SCOOP_GPCR_PA22 ( 1 << 12 ) -#define SCOOP_GPCR_PA21 ( 1 << 11 ) -#define SCOOP_GPCR_PA20 ( 1 << 10 ) -#define SCOOP_GPCR_PA19 ( 1 << 9 ) -#define SCOOP_GPCR_PA18 ( 1 << 8 ) -#define SCOOP_GPCR_PA17 ( 1 << 7 ) -#define SCOOP_GPCR_PA16 ( 1 << 6 ) -#define SCOOP_GPCR_PA15 ( 1 << 5 ) -#define SCOOP_GPCR_PA14 ( 1 << 4 ) -#define SCOOP_GPCR_PA13 ( 1 << 3 ) -#define SCOOP_GPCR_PA12 ( 1 << 2 ) -#define SCOOP_GPCR_PA11 ( 1 << 1 ) +#define SCOOP_CPR_OUT (1 << 7) +#define SCOOP_CPR_SD_3V (1 << 2) +#define SCOOP_CPR_CF_XV (1 << 1) +#define SCOOP_CPR_CF_3V (1 << 0) + +#define SCOOP_GPCR_PA22 (1 << 12) +#define SCOOP_GPCR_PA21 (1 << 11) +#define SCOOP_GPCR_PA20 (1 << 10) +#define SCOOP_GPCR_PA19 (1 << 9) +#define SCOOP_GPCR_PA18 (1 << 8) +#define SCOOP_GPCR_PA17 (1 << 7) +#define SCOOP_GPCR_PA16 (1 << 6) +#define SCOOP_GPCR_PA15 (1 << 5) +#define SCOOP_GPCR_PA14 (1 << 4) +#define SCOOP_GPCR_PA13 (1 << 3) +#define SCOOP_GPCR_PA12 (1 << 2) +#define SCOOP_GPCR_PA11 (1 << 1) struct scoop_config { unsigned short io_out; -- cgit v1.2.3 From 8dd47741d191400c46173ed9fba9d14b4033ce23 Mon Sep 17 00:00:00 2001 From: Catalin Marinas Date: Mon, 21 Jun 2010 15:10:37 +0100 Subject: ARM: 6189/1: Add support for the MOVW/MOVT relocations in Thumb-2 The patch adds handling case for the R_ARM_THM_MOVW_ABS_NC and R_ARM_THM_MOVT_ABS relocations in arch/arm/kernel/module.c. Such relocations may appear in Thumb-2 compiled kernel modules. Reported-by: Kyungmin Park Signed-off-by: Catalin Marinas Signed-off-by: Russell King --- arch/arm/include/asm/elf.h | 2 ++ arch/arm/kernel/module.c | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+) (limited to 'arch/arm/include') diff --git a/arch/arm/include/asm/elf.h b/arch/arm/include/asm/elf.h index 6750b8e45a49..5747a8baa413 100644 --- a/arch/arm/include/asm/elf.h +++ b/arch/arm/include/asm/elf.h @@ -59,6 +59,8 @@ typedef struct user_fp elf_fpregset_t; #define R_ARM_THM_CALL 10 #define R_ARM_THM_JUMP24 30 +#define R_ARM_THM_MOVW_ABS_NC 47 +#define R_ARM_THM_MOVT_ABS 48 /* * These are used to set parameters in the core dumps. diff --git a/arch/arm/kernel/module.c b/arch/arm/kernel/module.c index c628bdf6c430..ae3c80453a09 100644 --- a/arch/arm/kernel/module.c +++ b/arch/arm/kernel/module.c @@ -237,6 +237,38 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex, lower = *(u16 *)(loc + 2); break; + case R_ARM_THM_MOVW_ABS_NC: + case R_ARM_THM_MOVT_ABS: + upper = *(u16 *)loc; + lower = *(u16 *)(loc + 2); + + /* + * MOVT/MOVW instructions encoding in Thumb-2: + * + * i = upper[10] + * imm4 = upper[3:0] + * imm3 = lower[14:12] + * imm8 = lower[7:0] + * + * imm16 = imm4:i:imm3:imm8 + */ + offset = ((upper & 0x000f) << 12) | + ((upper & 0x0400) << 1) | + ((lower & 0x7000) >> 4) | (lower & 0x00ff); + offset = (offset ^ 0x8000) - 0x8000; + offset += sym->st_value; + + if (ELF32_R_TYPE(rel->r_info) == R_ARM_THM_MOVT_ABS) + offset >>= 16; + + *(u16 *)loc = (u16)((upper & 0xfbf0) | + ((offset & 0xf000) >> 12) | + ((offset & 0x0800) >> 1)); + *(u16 *)(loc + 2) = (u16)((lower & 0x8f00) | + ((offset & 0x0700) << 4) | + (offset & 0x00ff)); + break; + default: printk(KERN_ERR "%s: unknown relocation: %u\n", module->name, ELF32_R_TYPE(rel->r_info)); -- cgit v1.2.3 From 22eeef4bb2a7fd225089c0044060ed1fbf091958 Mon Sep 17 00:00:00 2001 From: Jason Wessel Date: Thu, 5 Aug 2010 09:22:21 -0500 Subject: kgdb,arm: Individual register get/set for arm Implement the ability to individually get and set registers for kdb and kgdb for arm. Signed-off-by: Jason Wessel CC: Russell King CC: linux-arm-kernel@lists.infradead.org --- arch/arm/include/asm/kgdb.h | 6 +-- arch/arm/kernel/kgdb.c | 90 +++++++++++++++++++++++---------------------- 2 files changed, 50 insertions(+), 46 deletions(-) (limited to 'arch/arm/include') diff --git a/arch/arm/include/asm/kgdb.h b/arch/arm/include/asm/kgdb.h index 67af4b841984..08265993227f 100644 --- a/arch/arm/include/asm/kgdb.h +++ b/arch/arm/include/asm/kgdb.h @@ -70,11 +70,11 @@ extern int kgdb_fault_expected; #define _GP_REGS 16 #define _FP_REGS 8 #define _EXTRA_REGS 2 -#define GDB_MAX_REGS (_GP_REGS + (_FP_REGS * 3) + _EXTRA_REGS) +#define DBG_MAX_REG_NUM (_GP_REGS + (_FP_REGS * 3) + _EXTRA_REGS) #define KGDB_MAX_NO_CPUS 1 #define BUFMAX 400 -#define NUMREGBYTES (GDB_MAX_REGS << 2) +#define NUMREGBYTES (DBG_MAX_REG_NUM << 2) #define NUMCRITREGBYTES (32 << 2) #define _R0 0 @@ -93,7 +93,7 @@ extern int kgdb_fault_expected; #define _SPT 13 #define _LR 14 #define _PC 15 -#define _CPSR (GDB_MAX_REGS - 1) +#define _CPSR (DBG_MAX_REG_NUM - 1) /* * So that we can denote the end of a frame for tracing, diff --git a/arch/arm/kernel/kgdb.c b/arch/arm/kernel/kgdb.c index c868a8864117..cf846cade354 100644 --- a/arch/arm/kernel/kgdb.c +++ b/arch/arm/kernel/kgdb.c @@ -13,54 +13,58 @@ #include #include -/* Make a local copy of the registers passed into the handler (bletch) */ -void pt_regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *kernel_regs) +struct dbg_reg_def_t dbg_reg_def[DBG_MAX_REG_NUM] = { - int regno; - - /* Initialize all to zero. */ - for (regno = 0; regno < GDB_MAX_REGS; regno++) - gdb_regs[regno] = 0; + { "r0", 4, offsetof(struct pt_regs, ARM_r0)}, + { "r1", 4, offsetof(struct pt_regs, ARM_r1)}, + { "r2", 4, offsetof(struct pt_regs, ARM_r2)}, + { "r3", 4, offsetof(struct pt_regs, ARM_r3)}, + { "r4", 4, offsetof(struct pt_regs, ARM_r4)}, + { "r5", 4, offsetof(struct pt_regs, ARM_r5)}, + { "r6", 4, offsetof(struct pt_regs, ARM_r6)}, + { "r7", 4, offsetof(struct pt_regs, ARM_r7)}, + { "r8", 4, offsetof(struct pt_regs, ARM_r8)}, + { "r9", 4, offsetof(struct pt_regs, ARM_r9)}, + { "r10", 4, offsetof(struct pt_regs, ARM_r10)}, + { "fp", 4, offsetof(struct pt_regs, ARM_fp)}, + { "ip", 4, offsetof(struct pt_regs, ARM_ip)}, + { "sp", 4, offsetof(struct pt_regs, ARM_sp)}, + { "lr", 4, offsetof(struct pt_regs, ARM_lr)}, + { "pc", 4, offsetof(struct pt_regs, ARM_pc)}, + { "f0", 12, -1 }, + { "f1", 12, -1 }, + { "f2", 12, -1 }, + { "f3", 12, -1 }, + { "f4", 12, -1 }, + { "f5", 12, -1 }, + { "f6", 12, -1 }, + { "f7", 12, -1 }, + { "fps", 4, -1 }, + { "cpsr", 4, offsetof(struct pt_regs, ARM_cpsr)}, +}; - gdb_regs[_R0] = kernel_regs->ARM_r0; - gdb_regs[_R1] = kernel_regs->ARM_r1; - gdb_regs[_R2] = kernel_regs->ARM_r2; - gdb_regs[_R3] = kernel_regs->ARM_r3; - gdb_regs[_R4] = kernel_regs->ARM_r4; - gdb_regs[_R5] = kernel_regs->ARM_r5; - gdb_regs[_R6] = kernel_regs->ARM_r6; - gdb_regs[_R7] = kernel_regs->ARM_r7; - gdb_regs[_R8] = kernel_regs->ARM_r8; - gdb_regs[_R9] = kernel_regs->ARM_r9; - gdb_regs[_R10] = kernel_regs->ARM_r10; - gdb_regs[_FP] = kernel_regs->ARM_fp; - gdb_regs[_IP] = kernel_regs->ARM_ip; - gdb_regs[_SPT] = kernel_regs->ARM_sp; - gdb_regs[_LR] = kernel_regs->ARM_lr; - gdb_regs[_PC] = kernel_regs->ARM_pc; - gdb_regs[_CPSR] = kernel_regs->ARM_cpsr; +char *dbg_get_reg(int regno, void *mem, struct pt_regs *regs) +{ + if (regno >= DBG_MAX_REG_NUM || regno < 0) + return NULL; + + if (dbg_reg_def[regno].offset != -1) + memcpy(mem, (void *)regs + dbg_reg_def[regno].offset, + dbg_reg_def[regno].size); + else + memset(mem, 0, dbg_reg_def[regno].size); + return dbg_reg_def[regno].name; } -/* Copy local gdb registers back to kgdb regs, for later copy to kernel */ -void gdb_regs_to_pt_regs(unsigned long *gdb_regs, struct pt_regs *kernel_regs) +int dbg_set_reg(int regno, void *mem, struct pt_regs *regs) { - kernel_regs->ARM_r0 = gdb_regs[_R0]; - kernel_regs->ARM_r1 = gdb_regs[_R1]; - kernel_regs->ARM_r2 = gdb_regs[_R2]; - kernel_regs->ARM_r3 = gdb_regs[_R3]; - kernel_regs->ARM_r4 = gdb_regs[_R4]; - kernel_regs->ARM_r5 = gdb_regs[_R5]; - kernel_regs->ARM_r6 = gdb_regs[_R6]; - kernel_regs->ARM_r7 = gdb_regs[_R7]; - kernel_regs->ARM_r8 = gdb_regs[_R8]; - kernel_regs->ARM_r9 = gdb_regs[_R9]; - kernel_regs->ARM_r10 = gdb_regs[_R10]; - kernel_regs->ARM_fp = gdb_regs[_FP]; - kernel_regs->ARM_ip = gdb_regs[_IP]; - kernel_regs->ARM_sp = gdb_regs[_SPT]; - kernel_regs->ARM_lr = gdb_regs[_LR]; - kernel_regs->ARM_pc = gdb_regs[_PC]; - kernel_regs->ARM_cpsr = gdb_regs[_CPSR]; + if (regno >= DBG_MAX_REG_NUM || regno < 0) + return -EINVAL; + + if (dbg_reg_def[regno].offset != -1) + memcpy((void *)regs + dbg_reg_def[regno].offset, mem, + dbg_reg_def[regno].size); + return 0; } void -- cgit v1.2.3 From 597781f3e51f48ef8e67be772196d9e9673752c4 Mon Sep 17 00:00:00 2001 From: Cesar Eduardo Barros Date: Mon, 9 Aug 2010 17:18:32 -0700 Subject: kmap_atomic: make kunmap_atomic() harder to misuse kunmap_atomic() is currently at level -4 on Rusty's "Hard To Misuse" list[1] ("Follow common convention and you'll get it wrong"), except in some architectures when CONFIG_DEBUG_HIGHMEM is set[2][3]. kunmap() takes a pointer to a struct page; kunmap_atomic(), however, takes takes a pointer to within the page itself. This seems to once in a while trip people up (the convention they are following is the one from kunmap()). Make it much harder to misuse, by moving it to level 9 on Rusty's list[4] ("The compiler/linker won't let you get it wrong"). This is done by refusing to build if the type of its first argument is a pointer to a struct page. The real kunmap_atomic() is renamed to kunmap_atomic_notypecheck() (which is what you would call in case for some strange reason calling it with a pointer to a struct page is not incorrect in your code). The previous version of this patch was compile tested on x86-64. [1] http://ozlabs.org/~rusty/index.cgi/tech/2008-04-01.html [2] In these cases, it is at level 5, "Do it right or it will always break at runtime." [3] At least mips and powerpc look very similar, and sparc also seems to share a common ancestor with both; there seems to be quite some degree of copy-and-paste coding here. The include/asm/highmem.h file for these three archs mention x86 CPUs at its top. [4] http://ozlabs.org/~rusty/index.cgi/tech/2008-03-30.html [5] As an aside, could someone tell me why mn10300 uses unsigned long as the first parameter of kunmap_atomic() instead of void *? Signed-off-by: Cesar Eduardo Barros Cc: Russell King (arch/arm) Cc: Ralf Baechle (arch/mips) Cc: David Howells (arch/frv, arch/mn10300) Cc: Koichi Yasutake (arch/mn10300) Cc: Kyle McMartin (arch/parisc) Cc: Helge Deller (arch/parisc) Cc: "James E.J. Bottomley" (arch/parisc) Cc: Benjamin Herrenschmidt (arch/powerpc) Cc: Paul Mackerras (arch/powerpc) Cc: "David S. Miller" (arch/sparc) Cc: Thomas Gleixner (arch/x86) Cc: Ingo Molnar (arch/x86) Cc: "H. Peter Anvin" (arch/x86) Cc: Arnd Bergmann (include/asm-generic) Cc: Rusty Russell ("Hard To Misuse" list) Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/arm/include/asm/highmem.h | 2 +- arch/arm/mm/highmem.c | 4 ++-- arch/frv/include/asm/highmem.h | 2 +- arch/mips/include/asm/highmem.h | 4 ++-- arch/mips/mm/highmem.c | 4 ++-- arch/mn10300/include/asm/highmem.h | 2 +- arch/parisc/include/asm/cacheflush.h | 2 +- arch/powerpc/include/asm/highmem.h | 2 +- arch/powerpc/mm/highmem.c | 4 ++-- arch/sparc/include/asm/highmem.h | 2 +- arch/sparc/mm/highmem.c | 4 ++-- arch/x86/include/asm/highmem.h | 2 +- arch/x86/mm/highmem_32.c | 4 ++-- include/linux/highmem.h | 10 +++++++++- 14 files changed, 28 insertions(+), 20 deletions(-) (limited to 'arch/arm/include') diff --git a/arch/arm/include/asm/highmem.h b/arch/arm/include/asm/highmem.h index feb988a7ec37..5aff58126602 100644 --- a/arch/arm/include/asm/highmem.h +++ b/arch/arm/include/asm/highmem.h @@ -36,7 +36,7 @@ extern void kunmap_high_l1_vipt(struct page *page, pte_t saved_pte); extern void *kmap(struct page *page); extern void kunmap(struct page *page); extern void *kmap_atomic(struct page *page, enum km_type type); -extern void kunmap_atomic(void *kvaddr, enum km_type type); +extern void kunmap_atomic_notypecheck(void *kvaddr, enum km_type type); extern void *kmap_atomic_pfn(unsigned long pfn, enum km_type type); extern struct page *kmap_atomic_to_page(const void *ptr); #endif diff --git a/arch/arm/mm/highmem.c b/arch/arm/mm/highmem.c index 6ab244062b4a..1fbdb55bfd1b 100644 --- a/arch/arm/mm/highmem.c +++ b/arch/arm/mm/highmem.c @@ -82,7 +82,7 @@ void *kmap_atomic(struct page *page, enum km_type type) } EXPORT_SYMBOL(kmap_atomic); -void kunmap_atomic(void *kvaddr, enum km_type type) +void kunmap_atomic_notypecheck(void *kvaddr, enum km_type type) { unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK; unsigned int idx = type + KM_TYPE_NR * smp_processor_id(); @@ -103,7 +103,7 @@ void kunmap_atomic(void *kvaddr, enum km_type type) } pagefault_enable(); } -EXPORT_SYMBOL(kunmap_atomic); +EXPORT_SYMBOL(kunmap_atomic_notypecheck); void *kmap_atomic_pfn(unsigned long pfn, enum km_type type) { diff --git a/arch/frv/include/asm/highmem.h b/arch/frv/include/asm/highmem.h index 68e4677fb9e7..cb4c317eaecc 100644 --- a/arch/frv/include/asm/highmem.h +++ b/arch/frv/include/asm/highmem.h @@ -152,7 +152,7 @@ do { \ asm volatile("tlbpr %0,gr0,#4,#1" : : "r"(vaddr) : "memory"); \ } while(0) -static inline void kunmap_atomic(void *kvaddr, enum km_type type) +static inline void kunmap_atomic_notypecheck(void *kvaddr, enum km_type type) { switch (type) { case 0: __kunmap_atomic_primary(0, 2); break; diff --git a/arch/mips/include/asm/highmem.h b/arch/mips/include/asm/highmem.h index 25adfb02923d..75753ca73bfd 100644 --- a/arch/mips/include/asm/highmem.h +++ b/arch/mips/include/asm/highmem.h @@ -48,14 +48,14 @@ extern void kunmap_high(struct page *page); extern void *__kmap(struct page *page); extern void __kunmap(struct page *page); extern void *__kmap_atomic(struct page *page, enum km_type type); -extern void __kunmap_atomic(void *kvaddr, enum km_type type); +extern void __kunmap_atomic_notypecheck(void *kvaddr, enum km_type type); extern void *kmap_atomic_pfn(unsigned long pfn, enum km_type type); extern struct page *__kmap_atomic_to_page(void *ptr); #define kmap __kmap #define kunmap __kunmap #define kmap_atomic __kmap_atomic -#define kunmap_atomic __kunmap_atomic +#define kunmap_atomic_notypecheck __kunmap_atomic_notypecheck #define kmap_atomic_to_page __kmap_atomic_to_page #define flush_cache_kmaps() flush_cache_all() diff --git a/arch/mips/mm/highmem.c b/arch/mips/mm/highmem.c index 127d732474bf..6a2b1bf9ef11 100644 --- a/arch/mips/mm/highmem.c +++ b/arch/mips/mm/highmem.c @@ -64,7 +64,7 @@ void *__kmap_atomic(struct page *page, enum km_type type) } EXPORT_SYMBOL(__kmap_atomic); -void __kunmap_atomic(void *kvaddr, enum km_type type) +void __kunmap_atomic_notypecheck(void *kvaddr, enum km_type type) { #ifdef CONFIG_DEBUG_HIGHMEM unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK; @@ -87,7 +87,7 @@ void __kunmap_atomic(void *kvaddr, enum km_type type) pagefault_enable(); } -EXPORT_SYMBOL(__kunmap_atomic); +EXPORT_SYMBOL(__kunmap_atomic_notypecheck); /* * This is the same as kmap_atomic() but can map memory that doesn't diff --git a/arch/mn10300/include/asm/highmem.h b/arch/mn10300/include/asm/highmem.h index 90f2abb04bfd..b0b187a29b88 100644 --- a/arch/mn10300/include/asm/highmem.h +++ b/arch/mn10300/include/asm/highmem.h @@ -91,7 +91,7 @@ static inline unsigned long kmap_atomic(struct page *page, enum km_type type) return vaddr; } -static inline void kunmap_atomic(unsigned long vaddr, enum km_type type) +static inline void kunmap_atomic_notypecheck(unsigned long vaddr, enum km_type type) { #if HIGHMEM_DEBUG enum fixed_addresses idx = type + KM_TYPE_NR * smp_processor_id(); diff --git a/arch/parisc/include/asm/cacheflush.h b/arch/parisc/include/asm/cacheflush.h index 4556d820128a..dba11aedce1b 100644 --- a/arch/parisc/include/asm/cacheflush.h +++ b/arch/parisc/include/asm/cacheflush.h @@ -132,7 +132,7 @@ static inline void *kmap_atomic(struct page *page, enum km_type idx) return page_address(page); } -static inline void kunmap_atomic(void *addr, enum km_type idx) +static inline void kunmap_atomic_notypecheck(void *addr, enum km_type idx) { kunmap_parisc(addr); pagefault_enable(); diff --git a/arch/powerpc/include/asm/highmem.h b/arch/powerpc/include/asm/highmem.h index a74c4ee6c020..d10d64a4be38 100644 --- a/arch/powerpc/include/asm/highmem.h +++ b/arch/powerpc/include/asm/highmem.h @@ -62,7 +62,7 @@ extern void *kmap_high(struct page *page); extern void kunmap_high(struct page *page); extern void *kmap_atomic_prot(struct page *page, enum km_type type, pgprot_t prot); -extern void kunmap_atomic(void *kvaddr, enum km_type type); +extern void kunmap_atomic_notypecheck(void *kvaddr, enum km_type type); static inline void *kmap(struct page *page) { diff --git a/arch/powerpc/mm/highmem.c b/arch/powerpc/mm/highmem.c index c2186c74c85a..857d4173f9c6 100644 --- a/arch/powerpc/mm/highmem.c +++ b/arch/powerpc/mm/highmem.c @@ -52,7 +52,7 @@ void *kmap_atomic_prot(struct page *page, enum km_type type, pgprot_t prot) } EXPORT_SYMBOL(kmap_atomic_prot); -void kunmap_atomic(void *kvaddr, enum km_type type) +void kunmap_atomic_notypecheck(void *kvaddr, enum km_type type) { #ifdef CONFIG_DEBUG_HIGHMEM unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK; @@ -74,4 +74,4 @@ void kunmap_atomic(void *kvaddr, enum km_type type) #endif pagefault_enable(); } -EXPORT_SYMBOL(kunmap_atomic); +EXPORT_SYMBOL(kunmap_atomic_notypecheck); diff --git a/arch/sparc/include/asm/highmem.h b/arch/sparc/include/asm/highmem.h index 3de42e776274..ec23b0a87b98 100644 --- a/arch/sparc/include/asm/highmem.h +++ b/arch/sparc/include/asm/highmem.h @@ -71,7 +71,7 @@ static inline void kunmap(struct page *page) } extern void *kmap_atomic(struct page *page, enum km_type type); -extern void kunmap_atomic(void *kvaddr, enum km_type type); +extern void kunmap_atomic_notypecheck(void *kvaddr, enum km_type type); extern struct page *kmap_atomic_to_page(void *vaddr); #define flush_cache_kmaps() flush_cache_all() diff --git a/arch/sparc/mm/highmem.c b/arch/sparc/mm/highmem.c index 7916feba6e4a..e139e9cbf5f7 100644 --- a/arch/sparc/mm/highmem.c +++ b/arch/sparc/mm/highmem.c @@ -65,7 +65,7 @@ void *kmap_atomic(struct page *page, enum km_type type) } EXPORT_SYMBOL(kmap_atomic); -void kunmap_atomic(void *kvaddr, enum km_type type) +void kunmap_atomic_notypecheck(void *kvaddr, enum km_type type) { #ifdef CONFIG_DEBUG_HIGHMEM unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK; @@ -100,7 +100,7 @@ void kunmap_atomic(void *kvaddr, enum km_type type) pagefault_enable(); } -EXPORT_SYMBOL(kunmap_atomic); +EXPORT_SYMBOL(kunmap_atomic_notypecheck); /* We may be fed a pagetable here by ptep_to_xxx and others. */ struct page *kmap_atomic_to_page(void *ptr) diff --git a/arch/x86/include/asm/highmem.h b/arch/x86/include/asm/highmem.h index a726650fc80f..8caac76ac324 100644 --- a/arch/x86/include/asm/highmem.h +++ b/arch/x86/include/asm/highmem.h @@ -61,7 +61,7 @@ void *kmap(struct page *page); void kunmap(struct page *page); void *kmap_atomic_prot(struct page *page, enum km_type type, pgprot_t prot); void *kmap_atomic(struct page *page, enum km_type type); -void kunmap_atomic(void *kvaddr, enum km_type type); +void kunmap_atomic_notypecheck(void *kvaddr, enum km_type type); void *kmap_atomic_pfn(unsigned long pfn, enum km_type type); void *kmap_atomic_prot_pfn(unsigned long pfn, enum km_type type, pgprot_t prot); struct page *kmap_atomic_to_page(void *ptr); diff --git a/arch/x86/mm/highmem_32.c b/arch/x86/mm/highmem_32.c index 63a6ba66cbe0..5e8fa12ef861 100644 --- a/arch/x86/mm/highmem_32.c +++ b/arch/x86/mm/highmem_32.c @@ -53,7 +53,7 @@ void *kmap_atomic(struct page *page, enum km_type type) return kmap_atomic_prot(page, type, kmap_prot); } -void kunmap_atomic(void *kvaddr, enum km_type type) +void kunmap_atomic_notypecheck(void *kvaddr, enum km_type type) { unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK; enum fixed_addresses idx = type + KM_TYPE_NR*smp_processor_id(); @@ -102,7 +102,7 @@ struct page *kmap_atomic_to_page(void *ptr) EXPORT_SYMBOL(kmap); EXPORT_SYMBOL(kunmap); EXPORT_SYMBOL(kmap_atomic); -EXPORT_SYMBOL(kunmap_atomic); +EXPORT_SYMBOL(kunmap_atomic_notypecheck); EXPORT_SYMBOL(kmap_atomic_prot); EXPORT_SYMBOL(kmap_atomic_to_page); diff --git a/include/linux/highmem.h b/include/linux/highmem.h index caafd0561aa1..67460f010224 100644 --- a/include/linux/highmem.h +++ b/include/linux/highmem.h @@ -2,6 +2,7 @@ #define _LINUX_HIGHMEM_H #include +#include #include #include @@ -72,7 +73,7 @@ static inline void *kmap_atomic(struct page *page, enum km_type idx) } #define kmap_atomic_prot(page, idx, prot) kmap_atomic(page, idx) -#define kunmap_atomic(addr, idx) do { pagefault_enable(); } while (0) +#define kunmap_atomic_notypecheck(addr, idx) do { pagefault_enable(); } while (0) #define kmap_atomic_pfn(pfn, idx) kmap_atomic(pfn_to_page(pfn), (idx)) #define kmap_atomic_to_page(ptr) virt_to_page(ptr) @@ -81,6 +82,13 @@ static inline void *kmap_atomic(struct page *page, enum km_type idx) #endif /* CONFIG_HIGHMEM */ +/* Prevent people trying to call kunmap_atomic() as if it were kunmap() */ +/* kunmap_atomic() should get the return value of kmap_atomic, not the page. */ +#define kunmap_atomic(addr, idx) do { \ + BUILD_BUG_ON(__same_type((addr), struct page *)); \ + kunmap_atomic_notypecheck((addr), (idx)); \ + } while (0) + /* when CONFIG_HIGHMEM is not set these will be plain clear/copy_page */ #ifndef clear_user_highpage static inline void clear_user_highpage(struct page *page, unsigned long vaddr) -- cgit v1.2.3 From 26df6d13406d1a53b0bda08bd712f1924affd7cd Mon Sep 17 00:00:00 2001 From: "hyc@symas.com" Date: Tue, 22 Jun 2010 10:14:49 -0700 Subject: tty: Add EXTPROC support for LINEMODE This patch is against the 2.6.34 source. Paraphrased from the 1989 BSD patch by David Borman @ cray.com: These are the changes needed for the kernel to support LINEMODE in the server. There is a new bit in the termios local flag word, EXTPROC. When this bit is set, several aspects of the terminal driver are disabled. Input line editing, character echo, and mapping of signals are all disabled. This allows the telnetd to turn off these functions when in linemode, but still keep track of what state the user wants the terminal to be in. New ioctl: TIOCSIG Generate a signal to processes in the current process group of the pty. There is a new mode for packet driver, the TIOCPKT_IOCTL bit. When packet mode is turned on in the pty, and the EXTPROC bit is set, then whenever the state of the pty is changed, the next read on the master side of the pty will have the TIOCPKT_IOCTL bit set. This allows the process on the server side of the pty to know when the state of the terminal has changed; it can then issue the appropriate ioctl to retrieve the new state. Since the original BSD patches accompanied the source code for telnet I've left that reference here, but obviously the feature is useful for any remote terminal protocol, including ssh. The corresponding feature has existed in the BSD tty driver since 1989. For historical reference, a good copy of the relevant files can be found here: http://anonsvn.mit.edu/viewvc/krb5/trunk/src/appl/telnet/?pathrev=17741 Signed-off-by: Howard Chu Cc: Alan Cox Signed-off-by: Greg Kroah-Hartman --- arch/alpha/include/asm/ioctls.h | 2 ++ arch/alpha/include/asm/termbits.h | 1 + arch/arm/include/asm/ioctls.h | 2 ++ arch/arm/include/asm/termbits.h | 1 + arch/avr32/include/asm/ioctls.h | 2 ++ arch/avr32/include/asm/termbits.h | 1 + arch/cris/include/asm/ioctls.h | 2 ++ arch/cris/include/asm/termbits.h | 1 + arch/frv/include/asm/ioctls.h | 2 ++ arch/frv/include/asm/termbits.h | 1 + arch/h8300/include/asm/ioctls.h | 2 ++ arch/h8300/include/asm/termbits.h | 1 + arch/ia64/include/asm/ioctls.h | 2 ++ arch/ia64/include/asm/termbits.h | 1 + arch/m32r/include/asm/ioctls.h | 2 ++ arch/m32r/include/asm/termbits.h | 1 + arch/m68k/include/asm/ioctls.h | 2 ++ arch/m68k/include/asm/termbits.h | 1 + arch/mips/include/asm/ioctls.h | 3 ++- arch/mips/include/asm/termbits.h | 1 + arch/mn10300/include/asm/ioctls.h | 2 ++ arch/mn10300/include/asm/termbits.h | 1 + arch/parisc/include/asm/ioctls.h | 2 ++ arch/parisc/include/asm/termbits.h | 1 + arch/powerpc/include/asm/ioctls.h | 2 ++ arch/powerpc/include/asm/termbits.h | 1 + arch/s390/include/asm/ioctls.h | 2 ++ arch/sh/include/asm/ioctls.h | 2 ++ arch/sparc/include/asm/ioctls.h | 2 ++ arch/sparc/include/asm/termbits.h | 1 + arch/xtensa/include/asm/ioctls.h | 2 ++ arch/xtensa/include/asm/termbits.h | 1 + drivers/char/n_tty.c | 17 ++++++++++++++--- drivers/char/pty.c | 21 +++++++++++++++++++++ drivers/char/tty_ioctl.c | 18 ++++++++++++------ fs/compat_ioctl.c | 1 + include/asm-generic/ioctls.h | 2 ++ include/asm-generic/termbits.h | 1 + include/linux/tty.h | 1 + 39 files changed, 101 insertions(+), 10 deletions(-) (limited to 'arch/arm/include') diff --git a/arch/alpha/include/asm/ioctls.h b/arch/alpha/include/asm/ioctls.h index c7b0cc61ce5b..59617c3c2be6 100644 --- a/arch/alpha/include/asm/ioctls.h +++ b/arch/alpha/include/asm/ioctls.h @@ -80,6 +80,7 @@ # define TIOCPKT_START 8 # define TIOCPKT_NOSTOP 16 # define TIOCPKT_DOSTOP 32 +# define TIOCPKT_IOCTL 64 #define TIOCNOTTY 0x5422 @@ -91,6 +92,7 @@ #define TIOCGSID 0x5429 /* Return the session ID of FD */ #define TIOCGPTN _IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */ #define TIOCSPTLCK _IOW('T',0x31, int) /* Lock/unlock Pty */ +#define TIOCSIG _IOW('T',0x36, int) /* Generate signal on Pty slave */ #define TIOCSERCONFIG 0x5453 #define TIOCSERGWILD 0x5454 diff --git a/arch/alpha/include/asm/termbits.h b/arch/alpha/include/asm/termbits.h index ad854a4a3af6..879dd3589921 100644 --- a/arch/alpha/include/asm/termbits.h +++ b/arch/alpha/include/asm/termbits.h @@ -180,6 +180,7 @@ struct ktermios { #define FLUSHO 0x00800000 #define PENDIN 0x20000000 #define IEXTEN 0x00000400 +#define EXTPROC 0x10000000 /* Values for the ACTION argument to `tcflow'. */ #define TCOOFF 0 diff --git a/arch/arm/include/asm/ioctls.h b/arch/arm/include/asm/ioctls.h index 7f0b6d13296a..0b30894b5482 100644 --- a/arch/arm/include/asm/ioctls.h +++ b/arch/arm/include/asm/ioctls.h @@ -52,6 +52,7 @@ #define TCSETSF2 _IOW('T',0x2D, struct termios2) #define TIOCGPTN _IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */ #define TIOCSPTLCK _IOW('T',0x31, int) /* Lock/unlock Pty */ +#define TIOCSIG _IOW('T',0x36, int) /* Generate signal on Pty slave */ #define TIOCGRS485 0x542E #define TIOCSRS485 0x542F @@ -81,6 +82,7 @@ #define TIOCPKT_START 8 #define TIOCPKT_NOSTOP 16 #define TIOCPKT_DOSTOP 32 +#define TIOCPKT_IOCTL 64 #define TIOCSER_TEMT 0x01 /* Transmitter physically empty */ diff --git a/arch/arm/include/asm/termbits.h b/arch/arm/include/asm/termbits.h index f784d11f40b5..704135d28d1d 100644 --- a/arch/arm/include/asm/termbits.h +++ b/arch/arm/include/asm/termbits.h @@ -177,6 +177,7 @@ struct ktermios { #define FLUSHO 0010000 #define PENDIN 0040000 #define IEXTEN 0100000 +#define EXTPROC 0200000 /* tcflow() and TCXONC use these */ #define TCOOFF 0 diff --git a/arch/avr32/include/asm/ioctls.h b/arch/avr32/include/asm/ioctls.h index 143dafb3997e..b7dd324b46a9 100644 --- a/arch/avr32/include/asm/ioctls.h +++ b/arch/avr32/include/asm/ioctls.h @@ -53,6 +53,7 @@ #define TCSETSF2 _IOW('T',0x2D, struct termios2) #define TIOCGPTN _IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */ #define TIOCSPTLCK _IOW('T',0x31, int) /* Lock/unlock Pty */ +#define TIOCSIG _IOW('T',0x36, int) /* Generate signal on Pty slave */ #define TIOCGRS485 0x542E #define TIOCSRS485 0x542F @@ -82,6 +83,7 @@ #define TIOCPKT_START 8 #define TIOCPKT_NOSTOP 16 #define TIOCPKT_DOSTOP 32 +#define TIOCPKT_IOCTL 64 #define TIOCSER_TEMT 0x01 /* Transmitter physically empty */ diff --git a/arch/avr32/include/asm/termbits.h b/arch/avr32/include/asm/termbits.h index db2daab31fdb..366adc5ebb10 100644 --- a/arch/avr32/include/asm/termbits.h +++ b/arch/avr32/include/asm/termbits.h @@ -175,6 +175,7 @@ struct ktermios { #define FLUSHO 0010000 #define PENDIN 0040000 #define IEXTEN 0100000 +#define EXTPROC 0200000 /* tcflow() and TCXONC use these */ #define TCOOFF 0 diff --git a/arch/cris/include/asm/ioctls.h b/arch/cris/include/asm/ioctls.h index bb49142dc6ab..c9129ed37443 100644 --- a/arch/cris/include/asm/ioctls.h +++ b/arch/cris/include/asm/ioctls.h @@ -54,6 +54,7 @@ #define TCSETSF2 _IOW('T',0x2D, struct termios2) #define TIOCGPTN _IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */ #define TIOCSPTLCK _IOW('T',0x31, int) /* Lock/unlock Pty */ +#define TIOCSIG _IOW('T',0x36, int) /* Generate signal on Pty slave */ #define FIONCLEX 0x5450 /* these numbers need to be adjusted. */ #define FIOCLEX 0x5451 @@ -85,6 +86,7 @@ #define TIOCPKT_START 8 #define TIOCPKT_NOSTOP 16 #define TIOCPKT_DOSTOP 32 +#define TIOCPKT_IOCTL 64 #define TIOCSER_TEMT 0x01 /* Transmitter physically empty */ diff --git a/arch/cris/include/asm/termbits.h b/arch/cris/include/asm/termbits.h index 66e1a7492a0c..1c43bc874ccf 100644 --- a/arch/cris/include/asm/termbits.h +++ b/arch/cris/include/asm/termbits.h @@ -214,6 +214,7 @@ struct ktermios { #define FLUSHO 0010000 #define PENDIN 0040000 #define IEXTEN 0100000 +#define EXTPROC 0200000 /* tcflow() and TCXONC use these */ #define TCOOFF 0 diff --git a/arch/frv/include/asm/ioctls.h b/arch/frv/include/asm/ioctls.h index d0c30e31fbda..a993e3759ccf 100644 --- a/arch/frv/include/asm/ioctls.h +++ b/arch/frv/include/asm/ioctls.h @@ -53,6 +53,7 @@ #define TCSETSF2 _IOW('T',0x2D, struct termios2) #define TIOCGPTN _IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */ #define TIOCSPTLCK _IOW('T',0x31, int) /* Lock/unlock Pty */ +#define TIOCSIG _IOW('T',0x36, int) /* Generate signal on Pty slave */ #define FIONCLEX 0x5450 /* these numbers need to be adjusted. */ #define FIOCLEX 0x5451 @@ -79,6 +80,7 @@ #define TIOCPKT_START 8 #define TIOCPKT_NOSTOP 16 #define TIOCPKT_DOSTOP 32 +#define TIOCPKT_IOCTL 64 #define TIOCSER_TEMT 0x01 /* Transmitter physically empty */ diff --git a/arch/frv/include/asm/termbits.h b/arch/frv/include/asm/termbits.h index 5568492b5086..7722e19cc349 100644 --- a/arch/frv/include/asm/termbits.h +++ b/arch/frv/include/asm/termbits.h @@ -180,6 +180,7 @@ struct ktermios { #define FLUSHO 0010000 #define PENDIN 0040000 #define IEXTEN 0100000 +#define EXTPROC 0200000 /* tcflow() and TCXONC use these */ diff --git a/arch/h8300/include/asm/ioctls.h b/arch/h8300/include/asm/ioctls.h index 98a53d067269..b6b249f9f308 100644 --- a/arch/h8300/include/asm/ioctls.h +++ b/arch/h8300/include/asm/ioctls.h @@ -53,6 +53,7 @@ #define TCSETSF2 _IOW('T',0x2D, struct termios2) #define TIOCGPTN _IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */ #define TIOCSPTLCK _IOW('T',0x31, int) /* Lock/unlock Pty */ +#define TIOCSIG _IOW('T',0x36, int) /* Generate signal on Pty slave */ #define FIONCLEX 0x5450 /* these numbers need to be adjusted. */ #define FIOCLEX 0x5451 @@ -79,6 +80,7 @@ #define TIOCPKT_START 8 #define TIOCPKT_NOSTOP 16 #define TIOCPKT_DOSTOP 32 +#define TIOCPKT_IOCTL 64 #define TIOCSER_TEMT 0x01 /* Transmitter physically empty */ diff --git a/arch/h8300/include/asm/termbits.h b/arch/h8300/include/asm/termbits.h index 31eca81db3f7..3287a6244d74 100644 --- a/arch/h8300/include/asm/termbits.h +++ b/arch/h8300/include/asm/termbits.h @@ -179,6 +179,7 @@ struct ktermios { #define FLUSHO 0010000 #define PENDIN 0040000 #define IEXTEN 0100000 +#define EXTPROC 0200000 /* tcflow() and TCXONC use these */ diff --git a/arch/ia64/include/asm/ioctls.h b/arch/ia64/include/asm/ioctls.h index f0ee86c0b5f7..b79c385114ef 100644 --- a/arch/ia64/include/asm/ioctls.h +++ b/arch/ia64/include/asm/ioctls.h @@ -59,6 +59,7 @@ #define TCSETSF2 _IOW('T',0x2D, struct termios2) #define TIOCGPTN _IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */ #define TIOCSPTLCK _IOW('T',0x31, int) /* Lock/unlock Pty */ +#define TIOCSIG _IOW('T',0x36, int) /* Generate signal on Pty slave */ #define FIONCLEX 0x5450 /* these numbers need to be adjusted. */ #define FIOCLEX 0x5451 @@ -85,6 +86,7 @@ #define TIOCPKT_START 8 #define TIOCPKT_NOSTOP 16 #define TIOCPKT_DOSTOP 32 +#define TIOCPKT_IOCTL 64 #define TIOCSER_TEMT 0x01 /* Transmitter physically empty */ diff --git a/arch/ia64/include/asm/termbits.h b/arch/ia64/include/asm/termbits.h index 9f162e0089ad..c009b94e58d9 100644 --- a/arch/ia64/include/asm/termbits.h +++ b/arch/ia64/include/asm/termbits.h @@ -187,6 +187,7 @@ struct ktermios { #define FLUSHO 0010000 #define PENDIN 0040000 #define IEXTEN 0100000 +#define EXTPROC 0200000 /* tcflow() and TCXONC use these */ #define TCOOFF 0 diff --git a/arch/m32r/include/asm/ioctls.h b/arch/m32r/include/asm/ioctls.h index f4c13a52fe48..66288063a4c0 100644 --- a/arch/m32r/include/asm/ioctls.h +++ b/arch/m32r/include/asm/ioctls.h @@ -53,6 +53,7 @@ #define TCSETSF2 _IOW('T',0x2D, struct termios2) #define TIOCGPTN _IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */ #define TIOCSPTLCK _IOW('T',0x31, int) /* Lock/unlock Pty */ +#define TIOCSIG _IOW('T',0x36, int) /* Generate signal on Pty slave */ #define FIONCLEX 0x5450 #define FIOCLEX 0x5451 @@ -79,6 +80,7 @@ #define TIOCPKT_START 8 #define TIOCPKT_NOSTOP 16 #define TIOCPKT_DOSTOP 32 +#define TIOCPKT_IOCTL 64 #define TIOCSER_TEMT 0x01 /* Transmitter physically empty */ diff --git a/arch/m32r/include/asm/termbits.h b/arch/m32r/include/asm/termbits.h index bc104008b55b..957a3c688549 100644 --- a/arch/m32r/include/asm/termbits.h +++ b/arch/m32r/include/asm/termbits.h @@ -179,6 +179,7 @@ struct ktermios { #define FLUSHO 0010000 #define PENDIN 0040000 #define IEXTEN 0100000 +#define EXTPROC 0200000 /* tcflow() and TCXONC use these */ #define TCOOFF 0 diff --git a/arch/m68k/include/asm/ioctls.h b/arch/m68k/include/asm/ioctls.h index b8d2f4be7fd7..91a57d665460 100644 --- a/arch/m68k/include/asm/ioctls.h +++ b/arch/m68k/include/asm/ioctls.h @@ -52,6 +52,7 @@ #define TCSETSF2 _IOW('T',0x2D, struct termios2) #define TIOCGPTN _IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */ #define TIOCSPTLCK _IOW('T',0x31, int) /* Lock/unlock Pty */ +#define TIOCSIG _IOW('T',0x36, int) /* Generate signal on Pty slave */ #define FIONCLEX 0x5450 /* these numbers need to be adjusted. */ #define FIOCLEX 0x5451 @@ -78,6 +79,7 @@ #define TIOCPKT_START 8 #define TIOCPKT_NOSTOP 16 #define TIOCPKT_DOSTOP 32 +#define TIOCPKT_IOCTL 64 #define TIOCSER_TEMT 0x01 /* Transmitter physically empty */ diff --git a/arch/m68k/include/asm/termbits.h b/arch/m68k/include/asm/termbits.h index 8c14170996bb..aea1e37b765a 100644 --- a/arch/m68k/include/asm/termbits.h +++ b/arch/m68k/include/asm/termbits.h @@ -179,6 +179,7 @@ struct ktermios { #define FLUSHO 0010000 #define PENDIN 0040000 #define IEXTEN 0100000 +#define EXTPROC 0200000 /* tcflow() and TCXONC use these */ diff --git a/arch/mips/include/asm/ioctls.h b/arch/mips/include/asm/ioctls.h index 2fb9e1693bf7..d87cb0465693 100644 --- a/arch/mips/include/asm/ioctls.h +++ b/arch/mips/include/asm/ioctls.h @@ -41,7 +41,7 @@ #define TIOCPKT_START 0x08 /* start output */ #define TIOCPKT_NOSTOP 0x10 /* no more ^S, ^Q */ #define TIOCPKT_DOSTOP 0x20 /* now do ^S ^Q */ -/* #define TIOCPKT_IOCTL 0x40 state change of pty driver */ +#define TIOCPKT_IOCTL 0x40 /* state change of pty driver */ #define TIOCSWINSZ _IOW('t', 103, struct winsize) /* set window size */ #define TIOCGWINSZ _IOR('t', 104, struct winsize) /* get window size */ #define TIOCNOTTY 0x5471 /* void tty association */ @@ -83,6 +83,7 @@ #define TCSETSF2 _IOW('T', 0x2D, struct termios2) #define TIOCGPTN _IOR('T', 0x30, unsigned int) /* Get Pty Number (of pty-mux device) */ #define TIOCSPTLCK _IOW('T', 0x31, int) /* Lock/unlock Pty */ +#define TIOCSIG _IOW('T', 0x36, int) /* Generate signal on Pty slave */ /* I hope the range from 0x5480 on is free ... */ #define TIOCSCTTY 0x5480 /* become controlling tty */ diff --git a/arch/mips/include/asm/termbits.h b/arch/mips/include/asm/termbits.h index c83c68444e86..76630b396fac 100644 --- a/arch/mips/include/asm/termbits.h +++ b/arch/mips/include/asm/termbits.h @@ -203,6 +203,7 @@ struct ktermios { #define PENDIN 0040000 /* Retype pending input (state). */ #define TOSTOP 0100000 /* Send SIGTTOU for background output. */ #define ITOSTOP TOSTOP +#define EXTPROC 0200000 /* External processing on pty */ /* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */ #define TIOCSER_TEMT 0x01 /* Transmitter physically empty */ diff --git a/arch/mn10300/include/asm/ioctls.h b/arch/mn10300/include/asm/ioctls.h index 638219a99b1e..cb8cf1902234 100644 --- a/arch/mn10300/include/asm/ioctls.h +++ b/arch/mn10300/include/asm/ioctls.h @@ -54,6 +54,7 @@ #define TIOCGPTN _IOR('T', 0x30, unsigned int) /* Get Pty Number * (of pty-mux device) */ #define TIOCSPTLCK _IOW('T', 0x31, int) /* Lock/unlock Pty */ +#define TIOCSIG _IOW('T', 0x36, int) /* Generate signal on Pty slave */ #define FIONCLEX 0x5450 #define FIOCLEX 0x5451 @@ -80,6 +81,7 @@ #define TIOCPKT_START 8 #define TIOCPKT_NOSTOP 16 #define TIOCPKT_DOSTOP 32 +#define TIOCPKT_IOCTL 64 #define TIOCSER_TEMT 0x01 /* Transmitter physically empty */ diff --git a/arch/mn10300/include/asm/termbits.h b/arch/mn10300/include/asm/termbits.h index eb2b0dc1f696..130d42495972 100644 --- a/arch/mn10300/include/asm/termbits.h +++ b/arch/mn10300/include/asm/termbits.h @@ -180,6 +180,7 @@ struct ktermios { #define FLUSHO 0010000 #define PENDIN 0040000 #define IEXTEN 0100000 +#define EXTPROC 0200000 /* tcflow() and TCXONC use these */ #define TCOOFF 0 diff --git a/arch/parisc/include/asm/ioctls.h b/arch/parisc/include/asm/ioctls.h index 6cc497e52532..4e0614456bea 100644 --- a/arch/parisc/include/asm/ioctls.h +++ b/arch/parisc/include/asm/ioctls.h @@ -52,6 +52,7 @@ #define TCSETSF2 _IOW('T',0x2D, struct termios2) #define TIOCGPTN _IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */ #define TIOCSPTLCK _IOW('T',0x31, int) /* Lock/unlock Pty */ +#define TIOCSIG _IOW('T',0x36, int) /* Generate signal on Pty slave */ #define FIONCLEX 0x5450 /* these numbers need to be adjusted. */ #define FIOCLEX 0x5451 @@ -82,6 +83,7 @@ #define TIOCPKT_START 8 #define TIOCPKT_NOSTOP 16 #define TIOCPKT_DOSTOP 32 +#define TIOCPKT_IOCTL 64 #define TIOCSER_TEMT 0x01 /* Transmitter physically empty */ diff --git a/arch/parisc/include/asm/termbits.h b/arch/parisc/include/asm/termbits.h index d8bbc73b16b7..d1ab92177a5c 100644 --- a/arch/parisc/include/asm/termbits.h +++ b/arch/parisc/include/asm/termbits.h @@ -180,6 +180,7 @@ struct ktermios { #define FLUSHO 0010000 #define PENDIN 0040000 #define IEXTEN 0100000 +#define EXTPROC 0200000 /* tcflow() and TCXONC use these */ #define TCOOFF 0 diff --git a/arch/powerpc/include/asm/ioctls.h b/arch/powerpc/include/asm/ioctls.h index 1842186d872c..851920052e08 100644 --- a/arch/powerpc/include/asm/ioctls.h +++ b/arch/powerpc/include/asm/ioctls.h @@ -80,6 +80,7 @@ # define TIOCPKT_START 8 # define TIOCPKT_NOSTOP 16 # define TIOCPKT_DOSTOP 32 +# define TIOCPKT_IOCTL 64 #define TIOCNOTTY 0x5422 @@ -93,6 +94,7 @@ #define TIOCSRS485 0x542f #define TIOCGPTN _IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */ #define TIOCSPTLCK _IOW('T',0x31, int) /* Lock/unlock Pty */ +#define TIOCSIG _IOW('T',0x36, int) /* Generate signal on Pty slave */ #define TIOCSERCONFIG 0x5453 #define TIOCSERGWILD 0x5454 diff --git a/arch/powerpc/include/asm/termbits.h b/arch/powerpc/include/asm/termbits.h index 6698188ca550..549d700e18f2 100644 --- a/arch/powerpc/include/asm/termbits.h +++ b/arch/powerpc/include/asm/termbits.h @@ -189,6 +189,7 @@ struct ktermios { #define FLUSHO 0x00800000 #define PENDIN 0x20000000 #define IEXTEN 0x00000400 +#define EXTPROC 0x10000000 /* Values for the ACTION argument to `tcflow'. */ #define TCOOFF 0 diff --git a/arch/s390/include/asm/ioctls.h b/arch/s390/include/asm/ioctls.h index 40e481b1b461..2f3d8736361f 100644 --- a/arch/s390/include/asm/ioctls.h +++ b/arch/s390/include/asm/ioctls.h @@ -60,6 +60,7 @@ #define TCSETSF2 _IOW('T',0x2D, struct termios2) #define TIOCGPTN _IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */ #define TIOCSPTLCK _IOW('T',0x31, int) /* Lock/unlock Pty */ +#define TIOCSIG _IOW('T',0x36, int) /* Generate signal on Pty slave */ #define FIONCLEX 0x5450 /* these numbers need to be adjusted. */ #define FIOCLEX 0x5451 @@ -86,6 +87,7 @@ #define TIOCPKT_START 8 #define TIOCPKT_NOSTOP 16 #define TIOCPKT_DOSTOP 32 +#define TIOCPKT_IOCTL 64 #define TIOCSER_TEMT 0x01 /* Transmitter physically empty */ diff --git a/arch/sh/include/asm/ioctls.h b/arch/sh/include/asm/ioctls.h index c212c371a4a5..eb6c4c687972 100644 --- a/arch/sh/include/asm/ioctls.h +++ b/arch/sh/include/asm/ioctls.h @@ -69,6 +69,7 @@ # define TIOCPKT_START 8 # define TIOCPKT_NOSTOP 16 # define TIOCPKT_DOSTOP 32 +# define TIOCPKT_IOCTL 64 #define TIOCNOTTY _IO('T', 34) /* 0x5422 */ @@ -84,6 +85,7 @@ #define TCSETSF2 _IOW('T', 45, struct termios2) #define TIOCGPTN _IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */ #define TIOCSPTLCK _IOW('T',0x31, int) /* Lock/unlock Pty */ +#define TIOCSIG _IOW('T',0x36, int) /* Generate signal on Pty slave */ #define TIOCSERCONFIG _IO('T', 83) /* 0x5453 */ #define TIOCSERGWILD _IOR('T', 84, int) /* 0x5454 */ diff --git a/arch/sparc/include/asm/ioctls.h b/arch/sparc/include/asm/ioctls.h index 1fe6855c5c18..53f4ee009bdd 100644 --- a/arch/sparc/include/asm/ioctls.h +++ b/arch/sparc/include/asm/ioctls.h @@ -80,6 +80,7 @@ /* Get minor device of a pty master's FD -- Solaris equiv is ISPTM */ #define TIOCGPTN _IOR('t', 134, unsigned int) /* Get Pty Number */ #define TIOCSPTLCK _IOW('t', 135, int) /* Lock/unlock PTY */ +#define TIOCSIG _IOW('t', 136, int) /* Generate signal on Pty slave */ /* Little f */ #define FIOCLEX _IO('f', 1) @@ -132,5 +133,6 @@ #define TIOCPKT_START 8 #define TIOCPKT_NOSTOP 16 #define TIOCPKT_DOSTOP 32 +#define TIOCPKT_IOCTL 64 #endif /* !(_ASM_SPARC_IOCTLS_H) */ diff --git a/arch/sparc/include/asm/termbits.h b/arch/sparc/include/asm/termbits.h index d72dfed1f9d7..23b10ff08df2 100644 --- a/arch/sparc/include/asm/termbits.h +++ b/arch/sparc/include/asm/termbits.h @@ -225,6 +225,7 @@ struct ktermios { #define FLUSHO 0x00002000 #define PENDIN 0x00004000 #define IEXTEN 0x00008000 +#define EXTPROC 0x00010000 /* modem lines */ #define TIOCM_LE 0x001 diff --git a/arch/xtensa/include/asm/ioctls.h b/arch/xtensa/include/asm/ioctls.h index 0ffa942954b9..ab1800012ed9 100644 --- a/arch/xtensa/include/asm/ioctls.h +++ b/arch/xtensa/include/asm/ioctls.h @@ -81,6 +81,7 @@ # define TIOCPKT_START 8 # define TIOCPKT_NOSTOP 16 # define TIOCPKT_DOSTOP 32 +# define TIOCPKT_IOCTL 64 #define TIOCNOTTY _IO('T', 34) @@ -97,6 +98,7 @@ #define TCSETSF2 _IOW('T', 45, struct termios2) #define TIOCGPTN _IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */ #define TIOCSPTLCK _IOW('T',0x31, int) /* Lock/unlock Pty */ +#define TIOCSIG _IOW('T',0x36, int) /* Generate signal on Pty slave */ #define TIOCSERCONFIG _IO('T', 83) #define TIOCSERGWILD _IOR('T', 84, int) diff --git a/arch/xtensa/include/asm/termbits.h b/arch/xtensa/include/asm/termbits.h index 85aa6a3c0b6e..0d6c8715b24f 100644 --- a/arch/xtensa/include/asm/termbits.h +++ b/arch/xtensa/include/asm/termbits.h @@ -196,6 +196,7 @@ struct ktermios { #define FLUSHO 0010000 #define PENDIN 0040000 #define IEXTEN 0100000 +#define EXTPROC 0200000 /* tcflow() and TCXONC use these */ diff --git a/drivers/char/n_tty.c b/drivers/char/n_tty.c index bdae8327143c..428f4fe0b5f7 100644 --- a/drivers/char/n_tty.c +++ b/drivers/char/n_tty.c @@ -1102,6 +1102,11 @@ static inline void n_tty_receive_char(struct tty_struct *tty, unsigned char c) if (I_IUCLC(tty) && L_IEXTEN(tty)) c = tolower(c); + if (L_EXTPROC(tty)) { + put_tty_queue(c, tty); + return; + } + if (tty->stopped && !tty->flow_stopped && I_IXON(tty) && I_IXANY(tty) && c != START_CHAR(tty) && c != STOP_CHAR(tty) && c != INTR_CHAR(tty) && c != QUIT_CHAR(tty) && c != SUSP_CHAR(tty)) { @@ -1409,7 +1414,8 @@ static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp, n_tty_set_room(tty); - if (!tty->icanon && (tty->read_cnt >= tty->minimum_to_wake)) { + if ((!tty->icanon && (tty->read_cnt >= tty->minimum_to_wake)) || + L_EXTPROC(tty)) { kill_fasync(&tty->fasync, SIGIO, POLL_IN); if (waitqueue_active(&tty->read_wait)) wake_up_interruptible(&tty->read_wait); @@ -1585,7 +1591,7 @@ static int n_tty_open(struct tty_struct *tty) static inline int input_available_p(struct tty_struct *tty, int amt) { tty_flush_to_ldisc(tty); - if (tty->icanon) { + if (tty->icanon && !L_EXTPROC(tty)) { if (tty->canon_data) return 1; } else if (tty->read_cnt >= (amt ? amt : 1)) @@ -1632,6 +1638,11 @@ static int copy_from_read_buf(struct tty_struct *tty, spin_lock_irqsave(&tty->read_lock, flags); tty->read_tail = (tty->read_tail + n) & (N_TTY_BUF_SIZE-1); tty->read_cnt -= n; + /* Turn single EOF into zero-length read */ + if (L_EXTPROC(tty) && tty->icanon && n == 1) { + if (!tty->read_cnt && (*b)[n-1] == EOF_CHAR(tty)) + n--; + } spin_unlock_irqrestore(&tty->read_lock, flags); *b += n; *nr -= n; @@ -1812,7 +1823,7 @@ do_it_again: nr--; } - if (tty->icanon) { + if (tty->icanon && !L_EXTPROC(tty)) { /* N.B. avoid overrun if nr == 0 */ while (nr && tty->read_cnt) { int eol; diff --git a/drivers/char/pty.c b/drivers/char/pty.c index d83a43130df4..b640ef29be1c 100644 --- a/drivers/char/pty.c +++ b/drivers/char/pty.c @@ -171,6 +171,23 @@ static int pty_set_lock(struct tty_struct *tty, int __user *arg) return 0; } +/* Send a signal to the slave */ +static int pty_signal(struct tty_struct *tty, int sig) +{ + unsigned long flags; + struct pid *pgrp; + + if (tty->link) { + spin_lock_irqsave(&tty->link->ctrl_lock, flags); + pgrp = get_pid(tty->link->pgrp); + spin_unlock_irqrestore(&tty->link->ctrl_lock, flags); + + kill_pgrp(pgrp, sig, 1); + put_pid(pgrp); + } + return 0; +} + static void pty_flush_buffer(struct tty_struct *tty) { struct tty_struct *to = tty->link; @@ -321,6 +338,8 @@ static int pty_bsd_ioctl(struct tty_struct *tty, struct file *file, switch (cmd) { case TIOCSPTLCK: /* Set PT Lock (disallow slave open) */ return pty_set_lock(tty, (int __user *) arg); + case TIOCSIG: /* Send signal to other side of pty */ + return pty_signal(tty, (int) arg); } return -ENOIOCTLCMD; } @@ -476,6 +495,8 @@ static int pty_unix98_ioctl(struct tty_struct *tty, struct file *file, return pty_set_lock(tty, (int __user *)arg); case TIOCGPTN: /* Get PT Number */ return put_user(tty->index, (unsigned int __user *)arg); + case TIOCSIG: /* Send signal to other side of pty */ + return pty_signal(tty, (int) arg); } return -ENOIOCTLCMD; diff --git a/drivers/char/tty_ioctl.c b/drivers/char/tty_ioctl.c index 6bd5f8866c74..0c1889971459 100644 --- a/drivers/char/tty_ioctl.c +++ b/drivers/char/tty_ioctl.c @@ -517,19 +517,25 @@ static void change_termios(struct tty_struct *tty, struct ktermios *new_termios) /* See if packet mode change of state. */ if (tty->link && tty->link->packet) { + int extproc = (old_termios.c_lflag & EXTPROC) | + (tty->termios->c_lflag & EXTPROC); int old_flow = ((old_termios.c_iflag & IXON) && (old_termios.c_cc[VSTOP] == '\023') && (old_termios.c_cc[VSTART] == '\021')); int new_flow = (I_IXON(tty) && STOP_CHAR(tty) == '\023' && START_CHAR(tty) == '\021'); - if (old_flow != new_flow) { + if ((old_flow != new_flow) || extproc) { spin_lock_irqsave(&tty->ctrl_lock, flags); - tty->ctrl_status &= ~(TIOCPKT_DOSTOP | TIOCPKT_NOSTOP); - if (new_flow) - tty->ctrl_status |= TIOCPKT_DOSTOP; - else - tty->ctrl_status |= TIOCPKT_NOSTOP; + if (old_flow != new_flow) { + tty->ctrl_status &= ~(TIOCPKT_DOSTOP | TIOCPKT_NOSTOP); + if (new_flow) + tty->ctrl_status |= TIOCPKT_DOSTOP; + else + tty->ctrl_status |= TIOCPKT_NOSTOP; + } + if (extproc) + tty->ctrl_status |= TIOCPKT_IOCTL; spin_unlock_irqrestore(&tty->ctrl_lock, flags); wake_up_interruptible(&tty->link->read_wait); } diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c index 63ae85831464..fa4bc48810fd 100644 --- a/fs/compat_ioctl.c +++ b/fs/compat_ioctl.c @@ -969,6 +969,7 @@ COMPATIBLE_IOCTL(TIOCGPGRP) COMPATIBLE_IOCTL(TIOCGPTN) COMPATIBLE_IOCTL(TIOCSPTLCK) COMPATIBLE_IOCTL(TIOCSERGETLSR) +COMPATIBLE_IOCTL(TIOCSIG) #ifdef TCGETS2 COMPATIBLE_IOCTL(TCGETS2) COMPATIBLE_IOCTL(TCSETS2) diff --git a/include/asm-generic/ioctls.h b/include/asm-generic/ioctls.h index 1375fa1a7a4d..8554cb6a81b9 100644 --- a/include/asm-generic/ioctls.h +++ b/include/asm-generic/ioctls.h @@ -69,6 +69,7 @@ #define TCSETX 0x5433 #define TCSETXF 0x5434 #define TCSETXW 0x5435 +#define TIOCSIG _IOW('T', 0x36, int) /* pty: generate signal */ #define FIONCLEX 0x5450 #define FIOCLEX 0x5451 @@ -102,6 +103,7 @@ #define TIOCPKT_START 8 #define TIOCPKT_NOSTOP 16 #define TIOCPKT_DOSTOP 32 +#define TIOCPKT_IOCTL 64 #define TIOCSER_TEMT 0x01 /* Transmitter physically empty */ diff --git a/include/asm-generic/termbits.h b/include/asm-generic/termbits.h index 1c9773d48cb0..232b4781aef3 100644 --- a/include/asm-generic/termbits.h +++ b/include/asm-generic/termbits.h @@ -178,6 +178,7 @@ struct ktermios { #define FLUSHO 0010000 #define PENDIN 0040000 #define IEXTEN 0100000 +#define EXTPROC 0200000 /* tcflow() and TCXONC use these */ #define TCOOFF 0 diff --git a/include/linux/tty.h b/include/linux/tty.h index 7802a243ee13..2df60e4ff40e 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -179,6 +179,7 @@ struct tty_bufhead { #define L_FLUSHO(tty) _L_FLAG((tty), FLUSHO) #define L_PENDIN(tty) _L_FLAG((tty), PENDIN) #define L_IEXTEN(tty) _L_FLAG((tty), IEXTEN) +#define L_EXTPROC(tty) _L_FLAG((tty), EXTPROC) struct device; struct signal_struct; -- cgit v1.2.3 From 9e354ea8e0710baf05804168fdabe90231b3d363 Mon Sep 17 00:00:00 2001 From: Alexander Shishkin Date: Wed, 4 Aug 2010 11:25:20 +0100 Subject: ARM: 6292/1: coresight: add ETM management registers Add notion of ETM OS lock, save and restore registers. Cc: linux-arm-kernel@lists.infradead.org Cc: linux-kernel@vger.kernel.org Signed-off-by: Alexander Shishkin Signed-off-by: Russell King --- arch/arm/include/asm/hardware/coresight.h | 8 ++++++-- arch/arm/kernel/etm.c | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) (limited to 'arch/arm/include') diff --git a/arch/arm/include/asm/hardware/coresight.h b/arch/arm/include/asm/hardware/coresight.h index f82b25d4f73e..212e47828c79 100644 --- a/arch/arm/include/asm/hardware/coresight.h +++ b/arch/arm/include/asm/hardware/coresight.h @@ -48,8 +48,6 @@ struct tracectx { /* CoreSight Component Registers */ #define CSCR_CLASS 0xff4 -#define CSCR_PRSR 0x314 - #define UNLOCK_MAGIC 0xc5acce55 /* ETM control register, "ETM Architecture", 3.3.1 */ @@ -132,6 +130,12 @@ struct tracectx { ETMCTRL_BRANCH_OUTPUT | \ ETMCTRL_DO_CONTEXTID) +/* ETM management registers, "ETM Architecture", 3.5.24 */ +#define ETMMR_OSLAR 0x300 +#define ETMMR_OSLSR 0x304 +#define ETMMR_OSSRR 0x308 +#define ETMMR_PDSR 0x314 + /* ETB registers, "CoreSight Components TRM", 9.3 */ #define ETBR_DEPTH 0x04 #define ETBR_STATUS 0x0c diff --git a/arch/arm/kernel/etm.c b/arch/arm/kernel/etm.c index 827753966301..9e9db63c298a 100644 --- a/arch/arm/kernel/etm.c +++ b/arch/arm/kernel/etm.c @@ -543,7 +543,7 @@ static int __init etm_probe(struct amba_device *dev, struct amba_id *id) t->etm_portsz = 1; etm_unlock(t); - ret = etm_readl(t, CSCR_PRSR); + ret = etm_readl(t, ETMMR_PDSR); t->ncmppairs = etm_readl(t, ETMR_CONFCODE) & 0xf; etm_writel(t, 0x440, ETMR_CTRL); -- cgit v1.2.3 From cdf357f1e13a08a11261edacb3083746f65c1ed9 Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Thu, 5 Aug 2010 11:20:51 +0100 Subject: ARM: 6299/1: errata: TLBIASIDIS and TLBIMVAIS operations can broadcast a faulty ASID On versions of the Cortex-A9 prior to r2p0, performing TLB invalidations by ASID match can result in the incorrect ASID being broadcast to other CPUs. As a consequence of this, the targetted TLB entries are not invalidated across the system. This workaround changes the TLB flushing routines to invalidate entries regardless of the ASID. Cc: Tested-by: Rob Clark Acked-by: Catalin Marinas Signed-off-by: Will Deacon Signed-off-by: Russell King --- arch/arm/Kconfig | 12 ++++++++++++ arch/arm/include/asm/tlbflush.h | 8 ++++++++ 2 files changed, 20 insertions(+) (limited to 'arch/arm/include') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 232f0c758252..e3956042892c 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -1040,6 +1040,18 @@ config PL310_ERRATA_588369 is not correctly implemented in PL310 as clean lines are not invalidated as a result of these operations. Note that this errata uses Texas Instrument's secure monitor api. + +config ARM_ERRATA_720789 + bool "ARM errata: TLBIASIDIS and TLBIMVAIS operations can broadcast a faulty ASID" + depends on CPU_V7 && SMP + help + This option enables the workaround for the 720789 Cortex-A9 (prior to + r2p0) erratum. A faulty ASID can be sent to the other CPUs for the + broadcasted CP15 TLB maintenance operations TLBIASIDIS and TLBIMVAIS. + As a consequence of this erratum, some TLB entries which should be + invalidated are not, resulting in an incoherency in the system page + tables. The workaround changes the TLB flushing routines to invalidate + entries regardless of the ASID. endmenu source "arch/arm/common/Kconfig" diff --git a/arch/arm/include/asm/tlbflush.h b/arch/arm/include/asm/tlbflush.h index bd863d8608cd..33b546ae72d4 100644 --- a/arch/arm/include/asm/tlbflush.h +++ b/arch/arm/include/asm/tlbflush.h @@ -378,7 +378,11 @@ static inline void local_flush_tlb_mm(struct mm_struct *mm) if (tlb_flag(TLB_V6_I_ASID)) asm("mcr p15, 0, %0, c8, c5, 2" : : "r" (asid) : "cc"); if (tlb_flag(TLB_V7_UIS_ASID)) +#ifdef CONFIG_ARM_ERRATA_720789 + asm("mcr p15, 0, %0, c8, c3, 0" : : "r" (zero) : "cc"); +#else asm("mcr p15, 0, %0, c8, c3, 2" : : "r" (asid) : "cc"); +#endif if (tlb_flag(TLB_BTB)) { /* flush the branch target cache */ @@ -424,7 +428,11 @@ local_flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr) if (tlb_flag(TLB_V6_I_PAGE)) asm("mcr p15, 0, %0, c8, c5, 1" : : "r" (uaddr) : "cc"); if (tlb_flag(TLB_V7_UIS_PAGE)) +#ifdef CONFIG_ARM_ERRATA_720789 + asm("mcr p15, 0, %0, c8, c3, 3" : : "r" (uaddr & PAGE_MASK) : "cc"); +#else asm("mcr p15, 0, %0, c8, c3, 1" : : "r" (uaddr) : "cc"); +#endif if (tlb_flag(TLB_BTB)) { /* flush the branch target cache */ -- cgit v1.2.3 From a6eb9fe105d5de0053b261148cee56c94b4720ca Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Tue, 10 Aug 2010 18:03:22 -0700 Subject: dma-mapping: rename ARCH_KMALLOC_MINALIGN to ARCH_DMA_MINALIGN Now each architecture has the own dma_get_cache_alignment implementation. dma_get_cache_alignment returns the minimum DMA alignment. Architectures define it as ARCH_KMALLOC_MINALIGN (it's used to make sure that malloc'ed buffer is DMA-safe; the buffer doesn't share a cache with the others). So we can unify dma_get_cache_alignment implementations. This patch: dma_get_cache_alignment() needs to know if an architecture defines ARCH_KMALLOC_MINALIGN or not (needs to know if architecture has DMA alignment restriction). However, slab.h define ARCH_KMALLOC_MINALIGN if architectures doesn't define it. Let's rename ARCH_KMALLOC_MINALIGN to ARCH_DMA_MINALIGN. ARCH_KMALLOC_MINALIGN is used only in the internals of slab/slob/slub (except for crypto). Signed-off-by: FUJITA Tomonori Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/arm/include/asm/cache.h | 2 +- arch/avr32/include/asm/cache.h | 2 +- arch/blackfin/include/asm/cache.h | 2 +- arch/frv/include/asm/mem-layout.h | 2 +- arch/m68k/include/asm/cache.h | 2 +- arch/microblaze/include/asm/page.h | 2 +- arch/mips/include/asm/mach-generic/kmalloc.h | 2 +- arch/mips/include/asm/mach-ip27/kmalloc.h | 2 +- arch/mips/include/asm/mach-ip32/kmalloc.h | 4 ++-- arch/mn10300/include/asm/cache.h | 2 +- arch/powerpc/include/asm/page_32.h | 2 +- arch/sh/include/asm/page.h | 2 +- arch/xtensa/include/asm/cache.h | 2 +- include/linux/slab_def.h | 4 +++- include/linux/slob_def.h | 4 +++- include/linux/slub_def.h | 8 +++++--- 16 files changed, 25 insertions(+), 19 deletions(-) (limited to 'arch/arm/include') diff --git a/arch/arm/include/asm/cache.h b/arch/arm/include/asm/cache.h index 66c160b8547f..9d6122096fbe 100644 --- a/arch/arm/include/asm/cache.h +++ b/arch/arm/include/asm/cache.h @@ -14,7 +14,7 @@ * cache before the transfer is done, causing old data to be seen by * the CPU. */ -#define ARCH_KMALLOC_MINALIGN L1_CACHE_BYTES +#define ARCH_DMA_MINALIGN L1_CACHE_BYTES /* * With EABI on ARMv5 and above we must have 64-bit aligned slab pointers. diff --git a/arch/avr32/include/asm/cache.h b/arch/avr32/include/asm/cache.h index d3cf35ab11ab..c3a58a189a91 100644 --- a/arch/avr32/include/asm/cache.h +++ b/arch/avr32/include/asm/cache.h @@ -11,7 +11,7 @@ * cache before the transfer is done, causing old data to be seen by * the CPU. */ -#define ARCH_KMALLOC_MINALIGN L1_CACHE_BYTES +#define ARCH_DMA_MINALIGN L1_CACHE_BYTES #ifndef __ASSEMBLER__ struct cache_info { diff --git a/arch/blackfin/include/asm/cache.h b/arch/blackfin/include/asm/cache.h index 93f6c634fdf4..bd0641a267f1 100644 --- a/arch/blackfin/include/asm/cache.h +++ b/arch/blackfin/include/asm/cache.h @@ -15,7 +15,7 @@ #define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT) #define SMP_CACHE_BYTES L1_CACHE_BYTES -#define ARCH_KMALLOC_MINALIGN L1_CACHE_BYTES +#define ARCH_DMA_MINALIGN L1_CACHE_BYTES #ifdef CONFIG_SMP #define __cacheline_aligned diff --git a/arch/frv/include/asm/mem-layout.h b/arch/frv/include/asm/mem-layout.h index ccae981876fa..e9a0ec85a402 100644 --- a/arch/frv/include/asm/mem-layout.h +++ b/arch/frv/include/asm/mem-layout.h @@ -35,7 +35,7 @@ * the slab must be aligned such that load- and store-double instructions don't * fault if used */ -#define ARCH_KMALLOC_MINALIGN L1_CACHE_BYTES +#define ARCH_DMA_MINALIGN L1_CACHE_BYTES #define ARCH_SLAB_MINALIGN L1_CACHE_BYTES /*****************************************************************************/ diff --git a/arch/m68k/include/asm/cache.h b/arch/m68k/include/asm/cache.h index ecafbe1718c3..0395c51e46a6 100644 --- a/arch/m68k/include/asm/cache.h +++ b/arch/m68k/include/asm/cache.h @@ -8,6 +8,6 @@ #define L1_CACHE_SHIFT 4 #define L1_CACHE_BYTES (1<< L1_CACHE_SHIFT) -#define ARCH_KMALLOC_MINALIGN L1_CACHE_BYTES +#define ARCH_DMA_MINALIGN L1_CACHE_BYTES #endif diff --git a/arch/microblaze/include/asm/page.h b/arch/microblaze/include/asm/page.h index 4f268faa0126..cf377d91da71 100644 --- a/arch/microblaze/include/asm/page.h +++ b/arch/microblaze/include/asm/page.h @@ -40,7 +40,7 @@ #ifndef __ASSEMBLY__ /* MS be sure that SLAB allocates aligned objects */ -#define ARCH_KMALLOC_MINALIGN L1_CACHE_BYTES +#define ARCH_DMA_MINALIGN L1_CACHE_BYTES #define ARCH_SLAB_MINALIGN L1_CACHE_BYTES diff --git a/arch/mips/include/asm/mach-generic/kmalloc.h b/arch/mips/include/asm/mach-generic/kmalloc.h index b8e6deba352f..a5d669086ed9 100644 --- a/arch/mips/include/asm/mach-generic/kmalloc.h +++ b/arch/mips/include/asm/mach-generic/kmalloc.h @@ -7,7 +7,7 @@ * Total overkill for most systems but need as a safe default. * Set this one if any device in the system might do non-coherent DMA. */ -#define ARCH_KMALLOC_MINALIGN 128 +#define ARCH_DMA_MINALIGN 128 #endif #endif /* __ASM_MACH_GENERIC_KMALLOC_H */ diff --git a/arch/mips/include/asm/mach-ip27/kmalloc.h b/arch/mips/include/asm/mach-ip27/kmalloc.h index 426bd049b2d7..82c23ce2afa7 100644 --- a/arch/mips/include/asm/mach-ip27/kmalloc.h +++ b/arch/mips/include/asm/mach-ip27/kmalloc.h @@ -2,7 +2,7 @@ #define __ASM_MACH_IP27_KMALLOC_H /* - * All happy, no need to define ARCH_KMALLOC_MINALIGN + * All happy, no need to define ARCH_DMA_MINALIGN */ #endif /* __ASM_MACH_IP27_KMALLOC_H */ diff --git a/arch/mips/include/asm/mach-ip32/kmalloc.h b/arch/mips/include/asm/mach-ip32/kmalloc.h index b1e0be60f720..042ca926c48f 100644 --- a/arch/mips/include/asm/mach-ip32/kmalloc.h +++ b/arch/mips/include/asm/mach-ip32/kmalloc.h @@ -3,9 +3,9 @@ #if defined(CONFIG_CPU_R5000) || defined(CONFIG_CPU_RM7000) -#define ARCH_KMALLOC_MINALIGN 32 +#define ARCH_DMA_MINALIGN 32 #else -#define ARCH_KMALLOC_MINALIGN 128 +#define ARCH_DMA_MINALIGN 128 #endif #endif /* __ASM_MACH_IP32_KMALLOC_H */ diff --git a/arch/mn10300/include/asm/cache.h b/arch/mn10300/include/asm/cache.h index 6e2fe28dde4e..781bf613366d 100644 --- a/arch/mn10300/include/asm/cache.h +++ b/arch/mn10300/include/asm/cache.h @@ -21,7 +21,7 @@ #define L1_CACHE_DISPARITY L1_CACHE_NENTRIES * L1_CACHE_BYTES #endif -#define ARCH_KMALLOC_MINALIGN L1_CACHE_BYTES +#define ARCH_DMA_MINALIGN L1_CACHE_BYTES /* data cache purge registers * - read from the register to unconditionally purge that cache line diff --git a/arch/powerpc/include/asm/page_32.h b/arch/powerpc/include/asm/page_32.h index bd0849dbcaaa..68d73b2a7bfc 100644 --- a/arch/powerpc/include/asm/page_32.h +++ b/arch/powerpc/include/asm/page_32.h @@ -10,7 +10,7 @@ #define VM_DATA_DEFAULT_FLAGS VM_DATA_DEFAULT_FLAGS32 #ifdef CONFIG_NOT_COHERENT_CACHE -#define ARCH_KMALLOC_MINALIGN L1_CACHE_BYTES +#define ARCH_DMA_MINALIGN L1_CACHE_BYTES #endif #ifdef CONFIG_PTE_64BIT diff --git a/arch/sh/include/asm/page.h b/arch/sh/include/asm/page.h index fb703d120d09..c4e0b3d472b9 100644 --- a/arch/sh/include/asm/page.h +++ b/arch/sh/include/asm/page.h @@ -180,7 +180,7 @@ typedef struct page *pgtable_t; * Some drivers need to perform DMA into kmalloc'ed buffers * and so we have to increase the kmalloc minalign for this. */ -#define ARCH_KMALLOC_MINALIGN L1_CACHE_BYTES +#define ARCH_DMA_MINALIGN L1_CACHE_BYTES #ifdef CONFIG_SUPERH64 /* diff --git a/arch/xtensa/include/asm/cache.h b/arch/xtensa/include/asm/cache.h index ed8cd3cbd499..d2fd932fdb4d 100644 --- a/arch/xtensa/include/asm/cache.h +++ b/arch/xtensa/include/asm/cache.h @@ -29,6 +29,6 @@ # define CACHE_WAY_SIZE ICACHE_WAY_SIZE #endif -#define ARCH_KMALLOC_MINALIGN L1_CACHE_BYTES +#define ARCH_DMA_MINALIGN L1_CACHE_BYTES #endif /* _XTENSA_CACHE_H */ diff --git a/include/linux/slab_def.h b/include/linux/slab_def.h index 1acfa73ce2ac..791a502f6906 100644 --- a/include/linux/slab_def.h +++ b/include/linux/slab_def.h @@ -17,7 +17,6 @@ #include -#ifndef ARCH_KMALLOC_MINALIGN /* * Enforce a minimum alignment for the kmalloc caches. * Usually, the kmalloc caches are cache_line_size() aligned, except when @@ -27,6 +26,9 @@ * ARCH_KMALLOC_MINALIGN allows that. * Note that increasing this value may disable some debug features. */ +#ifdef ARCH_DMA_MINALIGN +#define ARCH_KMALLOC_MINALIGN ARCH_DMA_MINALIGN +#else #define ARCH_KMALLOC_MINALIGN __alignof__(unsigned long long) #endif diff --git a/include/linux/slob_def.h b/include/linux/slob_def.h index 62667f72c2ef..4382db09df4f 100644 --- a/include/linux/slob_def.h +++ b/include/linux/slob_def.h @@ -1,7 +1,9 @@ #ifndef __LINUX_SLOB_DEF_H #define __LINUX_SLOB_DEF_H -#ifndef ARCH_KMALLOC_MINALIGN +#ifdef ARCH_DMA_MINALIGN +#define ARCH_KMALLOC_MINALIGN ARCH_DMA_MINALIGN +#else #define ARCH_KMALLOC_MINALIGN __alignof__(unsigned long) #endif diff --git a/include/linux/slub_def.h b/include/linux/slub_def.h index 6447a723ecb1..6d14409c4d9a 100644 --- a/include/linux/slub_def.h +++ b/include/linux/slub_def.h @@ -106,15 +106,17 @@ struct kmem_cache { /* * Kmalloc subsystem. */ -#if defined(ARCH_KMALLOC_MINALIGN) && ARCH_KMALLOC_MINALIGN > 8 -#define KMALLOC_MIN_SIZE ARCH_KMALLOC_MINALIGN +#if defined(ARCH_DMA_MINALIGN) && ARCH_DMA_MINALIGN > 8 +#define KMALLOC_MIN_SIZE ARCH_DMA_MINALIGN #else #define KMALLOC_MIN_SIZE 8 #endif #define KMALLOC_SHIFT_LOW ilog2(KMALLOC_MIN_SIZE) -#ifndef ARCH_KMALLOC_MINALIGN +#ifdef ARCH_DMA_MINALIGN +#define ARCH_KMALLOC_MINALIGN ARCH_DMA_MINALIGN +#else #define ARCH_KMALLOC_MINALIGN __alignof__(unsigned long long) #endif -- cgit v1.2.3 From 4565f0170dfc849b3629c27d769db800467baa62 Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Tue, 10 Aug 2010 18:03:22 -0700 Subject: dma-mapping: unify dma_get_cache_alignment implementations dma_get_cache_alignment returns the minimum DMA alignment. Architectures defines it as ARCH_DMA_MINALIGN (formally ARCH_KMALLOC_MINALIGN). So we can unify dma_get_cache_alignment implementations. Note that some architectures implement dma_get_cache_alignment wrongly. dma_get_cache_alignment() should return the minimum DMA alignment. So fully-coherent architectures should return 1. This patch also fixes this issue. Signed-off-by: FUJITA Tomonori Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/alpha/include/asm/dma-mapping.h | 1 - arch/arm/include/asm/dma-mapping.h | 5 ----- arch/avr32/include/asm/dma-mapping.h | 5 ----- arch/blackfin/include/asm/dma-mapping.h | 1 - arch/cris/include/asm/dma-mapping.h | 6 ------ arch/frv/include/asm/dma-mapping.h | 6 ------ arch/ia64/include/asm/dma-mapping.h | 2 -- arch/ia64/kernel/setup.c | 6 ------ arch/m68k/include/asm/dma-mapping.h | 5 ----- arch/microblaze/include/asm/dma-mapping.h | 5 ----- arch/mips/include/asm/dma-mapping.h | 7 ------- arch/mn10300/include/asm/dma-mapping.h | 6 ------ arch/parisc/include/asm/dma-mapping.h | 6 ------ arch/powerpc/include/asm/dma-mapping.h | 15 --------------- arch/sh/include/asm/dma-mapping.h | 9 --------- arch/sparc/include/asm/dma-mapping.h | 9 --------- arch/tile/include/asm/dma-mapping.h | 7 ------- arch/x86/include/asm/dma-mapping.h | 7 ------- arch/xtensa/include/asm/dma-mapping.h | 6 ------ include/linux/dma-mapping.h | 8 ++++++++ 20 files changed, 8 insertions(+), 114 deletions(-) (limited to 'arch/arm/include') diff --git a/arch/alpha/include/asm/dma-mapping.h b/arch/alpha/include/asm/dma-mapping.h index 1bce8169733c..b3423d96acc7 100644 --- a/arch/alpha/include/asm/dma-mapping.h +++ b/arch/alpha/include/asm/dma-mapping.h @@ -44,6 +44,5 @@ static inline int dma_set_mask(struct device *dev, u64 mask) #define dma_is_consistent(d, h) (1) #define dma_cache_sync(dev, va, size, dir) ((void)0) -#define dma_get_cache_alignment() L1_CACHE_BYTES #endif /* _ALPHA_DMA_MAPPING_H */ diff --git a/arch/arm/include/asm/dma-mapping.h b/arch/arm/include/asm/dma-mapping.h index 69ce0727edb5..f4a996d5ae96 100644 --- a/arch/arm/include/asm/dma-mapping.h +++ b/arch/arm/include/asm/dma-mapping.h @@ -144,11 +144,6 @@ static inline int dma_set_mask(struct device *dev, u64 dma_mask) return 0; } -static inline int dma_get_cache_alignment(void) -{ - return 32; -} - static inline int dma_is_consistent(struct device *dev, dma_addr_t handle) { return !!arch_is_coherent(); diff --git a/arch/avr32/include/asm/dma-mapping.h b/arch/avr32/include/asm/dma-mapping.h index 0399359ab5d8..af6b81655074 100644 --- a/arch/avr32/include/asm/dma-mapping.h +++ b/arch/avr32/include/asm/dma-mapping.h @@ -341,9 +341,4 @@ static inline int dma_is_consistent(struct device *dev, dma_addr_t dma_addr) return 1; } -static inline int dma_get_cache_alignment(void) -{ - return boot_cpu_data.dcache.linesz; -} - #endif /* __ASM_AVR32_DMA_MAPPING_H */ diff --git a/arch/blackfin/include/asm/dma-mapping.h b/arch/blackfin/include/asm/dma-mapping.h index 212cb80fd74b..6694a0f55de9 100644 --- a/arch/blackfin/include/asm/dma-mapping.h +++ b/arch/blackfin/include/asm/dma-mapping.h @@ -21,7 +21,6 @@ void dma_free_coherent(struct device *dev, size_t size, void *vaddr, #define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f) #define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h) #define dma_supported(d, m) (1) -#define dma_get_cache_alignment() (32) #define dma_is_consistent(d, h) (1) static inline int diff --git a/arch/cris/include/asm/dma-mapping.h b/arch/cris/include/asm/dma-mapping.h index da8ef8e8f842..fc30fd0b2a04 100644 --- a/arch/cris/include/asm/dma-mapping.h +++ b/arch/cris/include/asm/dma-mapping.h @@ -152,12 +152,6 @@ dma_set_mask(struct device *dev, u64 mask) return 0; } -static inline int -dma_get_cache_alignment(void) -{ - return (1 << INTERNODE_CACHE_SHIFT); -} - #define dma_is_consistent(d, h) (1) static inline void diff --git a/arch/frv/include/asm/dma-mapping.h b/arch/frv/include/asm/dma-mapping.h index 6af5d83e2fb2..7b05ce14177e 100644 --- a/arch/frv/include/asm/dma-mapping.h +++ b/arch/frv/include/asm/dma-mapping.h @@ -125,12 +125,6 @@ int dma_set_mask(struct device *dev, u64 mask) return 0; } -static inline -int dma_get_cache_alignment(void) -{ - return 1 << L1_CACHE_SHIFT; -} - #define dma_is_consistent(d, h) (1) static inline diff --git a/arch/ia64/include/asm/dma-mapping.h b/arch/ia64/include/asm/dma-mapping.h index 7d09a09cdaad..8d52deed3750 100644 --- a/arch/ia64/include/asm/dma-mapping.h +++ b/arch/ia64/include/asm/dma-mapping.h @@ -86,8 +86,6 @@ static inline phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr) return daddr; } -extern int dma_get_cache_alignment(void); - static inline void dma_cache_sync (struct device *dev, void *vaddr, size_t size, enum dma_data_direction dir) diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c index 41ae6a596b50..8fb958abf8d0 100644 --- a/arch/ia64/kernel/setup.c +++ b/arch/ia64/kernel/setup.c @@ -98,12 +98,6 @@ static struct resource bss_resource = { unsigned long ia64_max_cacheline_size; -int dma_get_cache_alignment(void) -{ - return ia64_max_cacheline_size; -} -EXPORT_SYMBOL(dma_get_cache_alignment); - unsigned long ia64_iobase; /* virtual address for I/O accesses */ EXPORT_SYMBOL(ia64_iobase); struct io_space io_space[MAX_IO_SPACES]; diff --git a/arch/m68k/include/asm/dma-mapping.h b/arch/m68k/include/asm/dma-mapping.h index 26f505488c11..a1ae732c7247 100644 --- a/arch/m68k/include/asm/dma-mapping.h +++ b/arch/m68k/include/asm/dma-mapping.h @@ -16,11 +16,6 @@ static inline int dma_set_mask(struct device *dev, u64 mask) return 0; } -static inline int dma_get_cache_alignment(void) -{ - return 1 << L1_CACHE_SHIFT; -} - static inline int dma_is_consistent(struct device *dev, dma_addr_t dma_addr) { return 0; diff --git a/arch/microblaze/include/asm/dma-mapping.h b/arch/microblaze/include/asm/dma-mapping.h index 507389580709..21df7cbae65e 100644 --- a/arch/microblaze/include/asm/dma-mapping.h +++ b/arch/microblaze/include/asm/dma-mapping.h @@ -132,11 +132,6 @@ static inline void dma_free_coherent(struct device *dev, size_t size, ops->free_coherent(dev, size, cpu_addr, dma_handle); } -static inline int dma_get_cache_alignment(void) -{ - return L1_CACHE_BYTES; -} - static inline void dma_cache_sync(struct device *dev, void *vaddr, size_t size, enum dma_data_direction direction) { diff --git a/arch/mips/include/asm/dma-mapping.h b/arch/mips/include/asm/dma-mapping.h index 664ba53dc32a..d724a15f0438 100644 --- a/arch/mips/include/asm/dma-mapping.h +++ b/arch/mips/include/asm/dma-mapping.h @@ -62,13 +62,6 @@ dma_set_mask(struct device *dev, u64 mask) return 0; } -static inline int -dma_get_cache_alignment(void) -{ - /* XXX Largest on any MIPS */ - return 128; -} - extern int dma_is_consistent(struct device *dev, dma_addr_t dma_addr); extern void dma_cache_sync(struct device *dev, void *vaddr, size_t size, diff --git a/arch/mn10300/include/asm/dma-mapping.h b/arch/mn10300/include/asm/dma-mapping.h index 4ed1522b38d2..8d452a657795 100644 --- a/arch/mn10300/include/asm/dma-mapping.h +++ b/arch/mn10300/include/asm/dma-mapping.h @@ -161,12 +161,6 @@ int dma_set_mask(struct device *dev, u64 mask) return 0; } -static inline -int dma_get_cache_alignment(void) -{ - return 1 << L1_CACHE_SHIFT; -} - #define dma_is_consistent(d) (1) static inline diff --git a/arch/parisc/include/asm/dma-mapping.h b/arch/parisc/include/asm/dma-mapping.h index da6943380908..44d3f62ccf9d 100644 --- a/arch/parisc/include/asm/dma-mapping.h +++ b/arch/parisc/include/asm/dma-mapping.h @@ -184,12 +184,6 @@ dma_set_mask(struct device *dev, u64 mask) return 0; } -static inline int -dma_get_cache_alignment(void) -{ - return dcache_stride; -} - static inline int dma_is_consistent(struct device *dev, dma_addr_t dma_addr) { diff --git a/arch/powerpc/include/asm/dma-mapping.h b/arch/powerpc/include/asm/dma-mapping.h index c85ef230135b..a77ba280af04 100644 --- a/arch/powerpc/include/asm/dma-mapping.h +++ b/arch/powerpc/include/asm/dma-mapping.h @@ -215,21 +215,6 @@ static inline phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr) #define dma_is_consistent(d, h) (1) #endif -static inline int dma_get_cache_alignment(void) -{ -#ifdef CONFIG_PPC64 - /* no easy way to get cache size on all processors, so return - * the maximum possible, to be safe */ - return (1 << INTERNODE_CACHE_SHIFT); -#else - /* - * Each processor family will define its own L1_CACHE_SHIFT, - * L1_CACHE_BYTES wraps to this, so this is always safe. - */ - return L1_CACHE_BYTES; -#endif -} - static inline void dma_cache_sync(struct device *dev, void *vaddr, size_t size, enum dma_data_direction direction) { diff --git a/arch/sh/include/asm/dma-mapping.h b/arch/sh/include/asm/dma-mapping.h index bea3337a426a..6bb5cc9decf8 100644 --- a/arch/sh/include/asm/dma-mapping.h +++ b/arch/sh/include/asm/dma-mapping.h @@ -48,15 +48,6 @@ void dma_cache_sync(struct device *dev, void *vaddr, size_t size, #define dma_is_consistent(d, h) (0) #endif -static inline int dma_get_cache_alignment(void) -{ - /* - * Each processor family will define its own L1_CACHE_SHIFT, - * L1_CACHE_BYTES wraps to this, so this is always safe. - */ - return L1_CACHE_BYTES; -} - static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) { struct dma_map_ops *ops = get_dma_ops(dev); diff --git a/arch/sparc/include/asm/dma-mapping.h b/arch/sparc/include/asm/dma-mapping.h index 4b4a0c0b0ccd..74db853ec2cf 100644 --- a/arch/sparc/include/asm/dma-mapping.h +++ b/arch/sparc/include/asm/dma-mapping.h @@ -52,15 +52,6 @@ static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) return (dma_addr == DMA_ERROR_CODE); } -static inline int dma_get_cache_alignment(void) -{ - /* - * no easy way to get cache size on all processors, so return - * the maximum possible, to be safe - */ - return (1 << INTERNODE_CACHE_SHIFT); -} - static inline int dma_set_mask(struct device *dev, u64 mask) { #ifdef CONFIG_PCI diff --git a/arch/tile/include/asm/dma-mapping.h b/arch/tile/include/asm/dma-mapping.h index cf466b39aa13..1326b910fec6 100644 --- a/arch/tile/include/asm/dma-mapping.h +++ b/arch/tile/include/asm/dma-mapping.h @@ -90,13 +90,6 @@ dma_set_mask(struct device *dev, u64 mask) return 0; } -static inline int -dma_get_cache_alignment(void) -{ - return L2_CACHE_BYTES; -} - #define dma_is_consistent(d, h) (1) - #endif /* _ASM_TILE_DMA_MAPPING_H */ diff --git a/arch/x86/include/asm/dma-mapping.h b/arch/x86/include/asm/dma-mapping.h index ac91eed21061..f9c67e83f648 100644 --- a/arch/x86/include/asm/dma-mapping.h +++ b/arch/x86/include/asm/dma-mapping.h @@ -87,13 +87,6 @@ dma_cache_sync(struct device *dev, void *vaddr, size_t size, flush_write_buffers(); } -static inline int dma_get_cache_alignment(void) -{ - /* no easy way to get cache size on all x86, so return the - * maximum possible, to be safe */ - return boot_cpu_data.x86_clflush_size; -} - static inline unsigned long dma_alloc_coherent_mask(struct device *dev, gfp_t gfp) { diff --git a/arch/xtensa/include/asm/dma-mapping.h b/arch/xtensa/include/asm/dma-mapping.h index 51882ae3db4d..7104f2f9823e 100644 --- a/arch/xtensa/include/asm/dma-mapping.h +++ b/arch/xtensa/include/asm/dma-mapping.h @@ -161,12 +161,6 @@ dma_set_mask(struct device *dev, u64 mask) return 0; } -static inline int -dma_get_cache_alignment(void) -{ - return L1_CACHE_BYTES; -} - #define dma_is_consistent(d, h) (1) static inline void diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h index 89b7e1a605b8..e0670a512056 100644 --- a/include/linux/dma-mapping.h +++ b/include/linux/dma-mapping.h @@ -142,6 +142,14 @@ static inline int dma_set_seg_boundary(struct device *dev, unsigned long mask) return -EIO; } +static inline int dma_get_cache_alignment(void) +{ +#ifdef ARCH_DMA_MINALIGN + return ARCH_DMA_MINALIGN; +#endif + return 1; +} + /* flags for the coherent memory api */ #define DMA_MEMORY_MAP 0x01 #define DMA_MEMORY_IO 0x02 -- cgit v1.2.3 From 3b9c6c11f519718d618f5d7c9508daf78b207f6f Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Tue, 10 Aug 2010 18:03:25 -0700 Subject: dma-mapping: remove dma_is_consistent API Architectures implement dma_is_consistent() in different ways (some misinterpret the definition of API in DMA-API.txt). So it hasn't been so useful for drivers. We have only one user of the API in tree. Unlikely out-of-tree drivers use the API. Even if we fix dma_is_consistent() in some architectures, it doesn't look useful at all. It was invented long ago for some old systems that can't allocate coherent memory at all. It's better to export only APIs that are definitely necessary for drivers. Let's remove this API. Signed-off-by: FUJITA Tomonori Cc: James Bottomley Reviewed-by: Konrad Rzeszutek Wilk Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- Documentation/DMA-API.txt | 6 ------ arch/alpha/include/asm/dma-mapping.h | 1 - arch/arm/include/asm/dma-mapping.h | 5 ----- arch/avr32/include/asm/dma-mapping.h | 5 ----- arch/blackfin/include/asm/dma-mapping.h | 1 - arch/cris/include/asm/dma-mapping.h | 2 -- arch/frv/include/asm/dma-mapping.h | 2 -- arch/ia64/include/asm/dma-mapping.h | 2 -- arch/m68k/include/asm/dma-mapping.h | 5 ----- arch/microblaze/include/asm/dma-mapping.h | 1 - arch/mips/include/asm/dma-mapping.h | 2 -- arch/mips/mm/dma-default.c | 7 ------- arch/mn10300/include/asm/dma-mapping.h | 2 -- arch/parisc/include/asm/dma-mapping.h | 6 ------ arch/powerpc/include/asm/dma-mapping.h | 5 ----- arch/sh/include/asm/dma-mapping.h | 6 ------ arch/sparc/include/asm/dma-mapping.h | 1 - arch/tile/include/asm/dma-mapping.h | 2 -- arch/um/include/asm/dma-mapping.h | 1 - arch/x86/include/asm/dma-mapping.h | 1 - arch/xtensa/include/asm/dma-mapping.h | 2 -- include/asm-generic/dma-mapping-broken.h | 3 --- 22 files changed, 68 deletions(-) (limited to 'arch/arm/include') diff --git a/Documentation/DMA-API.txt b/Documentation/DMA-API.txt index 05e2ae236865..fe2326906610 100644 --- a/Documentation/DMA-API.txt +++ b/Documentation/DMA-API.txt @@ -455,12 +455,6 @@ Free memory allocated by the nonconsistent API. All parameters must be identical to those passed in (and returned by dma_alloc_noncoherent()). -int -dma_is_consistent(struct device *dev, dma_addr_t dma_handle) - -Returns true if the device dev is performing consistent DMA on the memory -area pointed to by the dma_handle. - int dma_get_cache_alignment(void) diff --git a/arch/alpha/include/asm/dma-mapping.h b/arch/alpha/include/asm/dma-mapping.h index b3423d96acc7..4567aca6fdd6 100644 --- a/arch/alpha/include/asm/dma-mapping.h +++ b/arch/alpha/include/asm/dma-mapping.h @@ -41,7 +41,6 @@ static inline int dma_set_mask(struct device *dev, u64 mask) #define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f) #define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h) -#define dma_is_consistent(d, h) (1) #define dma_cache_sync(dev, va, size, dir) ((void)0) diff --git a/arch/arm/include/asm/dma-mapping.h b/arch/arm/include/asm/dma-mapping.h index f4a996d5ae96..c568da7dcae4 100644 --- a/arch/arm/include/asm/dma-mapping.h +++ b/arch/arm/include/asm/dma-mapping.h @@ -144,11 +144,6 @@ static inline int dma_set_mask(struct device *dev, u64 dma_mask) return 0; } -static inline int dma_is_consistent(struct device *dev, dma_addr_t handle) -{ - return !!arch_is_coherent(); -} - /* * DMA errors are defined by all-bits-set in the DMA address. */ diff --git a/arch/avr32/include/asm/dma-mapping.h b/arch/avr32/include/asm/dma-mapping.h index af6b81655074..aaf5199d8fcb 100644 --- a/arch/avr32/include/asm/dma-mapping.h +++ b/arch/avr32/include/asm/dma-mapping.h @@ -336,9 +336,4 @@ dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, #define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f) #define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h) -static inline int dma_is_consistent(struct device *dev, dma_addr_t dma_addr) -{ - return 1; -} - #endif /* __ASM_AVR32_DMA_MAPPING_H */ diff --git a/arch/blackfin/include/asm/dma-mapping.h b/arch/blackfin/include/asm/dma-mapping.h index 6694a0f55de9..bbf461076a0a 100644 --- a/arch/blackfin/include/asm/dma-mapping.h +++ b/arch/blackfin/include/asm/dma-mapping.h @@ -21,7 +21,6 @@ void dma_free_coherent(struct device *dev, size_t size, void *vaddr, #define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f) #define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h) #define dma_supported(d, m) (1) -#define dma_is_consistent(d, h) (1) static inline int dma_set_mask(struct device *dev, u64 dma_mask) diff --git a/arch/cris/include/asm/dma-mapping.h b/arch/cris/include/asm/dma-mapping.h index fc30fd0b2a04..8588b2ccf854 100644 --- a/arch/cris/include/asm/dma-mapping.h +++ b/arch/cris/include/asm/dma-mapping.h @@ -152,8 +152,6 @@ dma_set_mask(struct device *dev, u64 mask) return 0; } -#define dma_is_consistent(d, h) (1) - static inline void dma_cache_sync(struct device *dev, void *vaddr, size_t size, enum dma_data_direction direction) diff --git a/arch/frv/include/asm/dma-mapping.h b/arch/frv/include/asm/dma-mapping.h index 7b05ce14177e..dfb811002c64 100644 --- a/arch/frv/include/asm/dma-mapping.h +++ b/arch/frv/include/asm/dma-mapping.h @@ -125,8 +125,6 @@ int dma_set_mask(struct device *dev, u64 mask) return 0; } -#define dma_is_consistent(d, h) (1) - static inline void dma_cache_sync(struct device *dev, void *vaddr, size_t size, enum dma_data_direction direction) diff --git a/arch/ia64/include/asm/dma-mapping.h b/arch/ia64/include/asm/dma-mapping.h index 8d52deed3750..a2e7368a0150 100644 --- a/arch/ia64/include/asm/dma-mapping.h +++ b/arch/ia64/include/asm/dma-mapping.h @@ -97,6 +97,4 @@ dma_cache_sync (struct device *dev, void *vaddr, size_t size, mb(); } -#define dma_is_consistent(d, h) (1) /* all we do is coherent memory... */ - #endif /* _ASM_IA64_DMA_MAPPING_H */ diff --git a/arch/m68k/include/asm/dma-mapping.h b/arch/m68k/include/asm/dma-mapping.h index a1ae732c7247..17f7a45948ea 100644 --- a/arch/m68k/include/asm/dma-mapping.h +++ b/arch/m68k/include/asm/dma-mapping.h @@ -16,11 +16,6 @@ static inline int dma_set_mask(struct device *dev, u64 mask) return 0; } -static inline int dma_is_consistent(struct device *dev, dma_addr_t dma_addr) -{ - return 0; -} - extern void *dma_alloc_coherent(struct device *, size_t, dma_addr_t *, gfp_t); extern void dma_free_coherent(struct device *, size_t, diff --git a/arch/microblaze/include/asm/dma-mapping.h b/arch/microblaze/include/asm/dma-mapping.h index 21df7cbae65e..8fbb0ec10233 100644 --- a/arch/microblaze/include/asm/dma-mapping.h +++ b/arch/microblaze/include/asm/dma-mapping.h @@ -106,7 +106,6 @@ static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) #define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f) #define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h) -#define dma_is_consistent(d, h) (1) static inline void *dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t flag) diff --git a/arch/mips/include/asm/dma-mapping.h b/arch/mips/include/asm/dma-mapping.h index d724a15f0438..18fbf7af8e93 100644 --- a/arch/mips/include/asm/dma-mapping.h +++ b/arch/mips/include/asm/dma-mapping.h @@ -62,8 +62,6 @@ dma_set_mask(struct device *dev, u64 mask) return 0; } -extern int dma_is_consistent(struct device *dev, dma_addr_t dma_addr); - extern void dma_cache_sync(struct device *dev, void *vaddr, size_t size, enum dma_data_direction direction); diff --git a/arch/mips/mm/dma-default.c b/arch/mips/mm/dma-default.c index 9547bc0cf188..7ba890860d98 100644 --- a/arch/mips/mm/dma-default.c +++ b/arch/mips/mm/dma-default.c @@ -357,13 +357,6 @@ int dma_supported(struct device *dev, u64 mask) EXPORT_SYMBOL(dma_supported); -int dma_is_consistent(struct device *dev, dma_addr_t dma_addr) -{ - return plat_device_is_coherent(dev); -} - -EXPORT_SYMBOL(dma_is_consistent); - void dma_cache_sync(struct device *dev, void *vaddr, size_t size, enum dma_data_direction direction) { diff --git a/arch/mn10300/include/asm/dma-mapping.h b/arch/mn10300/include/asm/dma-mapping.h index 8d452a657795..c1be4397b1ed 100644 --- a/arch/mn10300/include/asm/dma-mapping.h +++ b/arch/mn10300/include/asm/dma-mapping.h @@ -161,8 +161,6 @@ int dma_set_mask(struct device *dev, u64 mask) return 0; } -#define dma_is_consistent(d) (1) - static inline void dma_cache_sync(void *vaddr, size_t size, enum dma_data_direction direction) diff --git a/arch/parisc/include/asm/dma-mapping.h b/arch/parisc/include/asm/dma-mapping.h index 44d3f62ccf9d..4ef73b09b168 100644 --- a/arch/parisc/include/asm/dma-mapping.h +++ b/arch/parisc/include/asm/dma-mapping.h @@ -184,12 +184,6 @@ dma_set_mask(struct device *dev, u64 mask) return 0; } -static inline int -dma_is_consistent(struct device *dev, dma_addr_t dma_addr) -{ - return (hppa_dma_ops->dma_sync_single_for_cpu == NULL); -} - static inline void dma_cache_sync(struct device *dev, void *vaddr, size_t size, enum dma_data_direction direction) diff --git a/arch/powerpc/include/asm/dma-mapping.h b/arch/powerpc/include/asm/dma-mapping.h index a77ba280af04..8c9c6ad2004e 100644 --- a/arch/powerpc/include/asm/dma-mapping.h +++ b/arch/powerpc/include/asm/dma-mapping.h @@ -209,11 +209,6 @@ static inline phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr) #define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f) #define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h) -#ifdef CONFIG_NOT_COHERENT_CACHE -#define dma_is_consistent(d, h) (0) -#else -#define dma_is_consistent(d, h) (1) -#endif static inline void dma_cache_sync(struct device *dev, void *vaddr, size_t size, enum dma_data_direction direction) diff --git a/arch/sh/include/asm/dma-mapping.h b/arch/sh/include/asm/dma-mapping.h index 6bb5cc9decf8..1a73c3e759a7 100644 --- a/arch/sh/include/asm/dma-mapping.h +++ b/arch/sh/include/asm/dma-mapping.h @@ -42,12 +42,6 @@ void dma_cache_sync(struct device *dev, void *vaddr, size_t size, #define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f) #define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h) -#ifdef CONFIG_DMA_COHERENT -#define dma_is_consistent(d, h) (1) -#else -#define dma_is_consistent(d, h) (0) -#endif - static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) { struct dma_map_ops *ops = get_dma_ops(dev); diff --git a/arch/sparc/include/asm/dma-mapping.h b/arch/sparc/include/asm/dma-mapping.h index 74db853ec2cf..8c0e4f7bb204 100644 --- a/arch/sparc/include/asm/dma-mapping.h +++ b/arch/sparc/include/asm/dma-mapping.h @@ -11,7 +11,6 @@ extern int dma_supported(struct device *dev, u64 mask); #define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f) #define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h) -#define dma_is_consistent(d, h) (1) extern struct dma_map_ops *dma_ops, pci32_dma_ops; extern struct bus_type pci_bus_type; diff --git a/arch/tile/include/asm/dma-mapping.h b/arch/tile/include/asm/dma-mapping.h index 1326b910fec6..15e1dceecc64 100644 --- a/arch/tile/include/asm/dma-mapping.h +++ b/arch/tile/include/asm/dma-mapping.h @@ -90,6 +90,4 @@ dma_set_mask(struct device *dev, u64 mask) return 0; } -#define dma_is_consistent(d, h) (1) - #endif /* _ASM_TILE_DMA_MAPPING_H */ diff --git a/arch/um/include/asm/dma-mapping.h b/arch/um/include/asm/dma-mapping.h index b948c14a7867..17a2cb5a4178 100644 --- a/arch/um/include/asm/dma-mapping.h +++ b/arch/um/include/asm/dma-mapping.h @@ -94,7 +94,6 @@ dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nelems, #define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f) #define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h) -#define dma_is_consistent(d, h) (1) static inline int dma_get_cache_alignment(void) diff --git a/arch/x86/include/asm/dma-mapping.h b/arch/x86/include/asm/dma-mapping.h index f9c67e83f648..d4c419f883a0 100644 --- a/arch/x86/include/asm/dma-mapping.h +++ b/arch/x86/include/asm/dma-mapping.h @@ -54,7 +54,6 @@ static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) #define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f) #define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h) -#define dma_is_consistent(d, h) (1) extern int dma_supported(struct device *hwdev, u64 mask); extern int dma_set_mask(struct device *dev, u64 mask); diff --git a/arch/xtensa/include/asm/dma-mapping.h b/arch/xtensa/include/asm/dma-mapping.h index 7104f2f9823e..492c95790ad5 100644 --- a/arch/xtensa/include/asm/dma-mapping.h +++ b/arch/xtensa/include/asm/dma-mapping.h @@ -161,8 +161,6 @@ dma_set_mask(struct device *dev, u64 mask) return 0; } -#define dma_is_consistent(d, h) (1) - static inline void dma_cache_sync(struct device *dev, void *vaddr, size_t size, enum dma_data_direction direction) diff --git a/include/asm-generic/dma-mapping-broken.h b/include/asm-generic/dma-mapping-broken.h index 82cd0cb1c3fe..ccf7b4f34a3c 100644 --- a/include/asm-generic/dma-mapping-broken.h +++ b/include/asm-generic/dma-mapping-broken.h @@ -72,9 +72,6 @@ dma_set_mask(struct device *dev, u64 mask); extern int dma_get_cache_alignment(void); -extern int -dma_is_consistent(struct device *dev, dma_addr_t dma_handle); - extern void dma_cache_sync(struct device *dev, void *vaddr, size_t size, enum dma_data_direction direction); -- cgit v1.2.3 From d92342df2a06baa8f5d7bf609b0bc0dc87067e82 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Mon, 9 Aug 2010 12:47:52 +0200 Subject: DMAENGINE: correct PL080 register header file This PL008 among all other variables named PL080 doesn't seem right. Fix it. Also add some missing defined that I use in the new PL08x driver. Acked-by: Ben Dooks Signed-off-by: Linus Walleij Signed-off-by: Ben Dooks --- arch/arm/include/asm/hardware/pl080.h | 4 +++- arch/arm/mach-s3c64xx/dma.c | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'arch/arm/include') diff --git a/arch/arm/include/asm/hardware/pl080.h b/arch/arm/include/asm/hardware/pl080.h index 6a6c66be7f65..f35b86e68dd5 100644 --- a/arch/arm/include/asm/hardware/pl080.h +++ b/arch/arm/include/asm/hardware/pl080.h @@ -43,7 +43,7 @@ /* Per channel configuration registers */ -#define PL008_Cx_STRIDE (0x20) +#define PL080_Cx_STRIDE (0x20) #define PL080_Cx_BASE(x) ((0x100 + (x * 0x20))) #define PL080_Cx_SRC_ADDR(x) ((0x100 + (x * 0x20))) #define PL080_Cx_DST_ADDR(x) ((0x104 + (x * 0x20))) @@ -68,6 +68,8 @@ #define PL080_CONTROL_TC_IRQ_EN (1 << 31) #define PL080_CONTROL_PROT_MASK (0x7 << 28) #define PL080_CONTROL_PROT_SHIFT (28) +#define PL080_CONTROL_PROT_CACHE (1 << 30) +#define PL080_CONTROL_PROT_BUFF (1 << 29) #define PL080_CONTROL_PROT_SYS (1 << 28) #define PL080_CONTROL_DST_INCR (1 << 27) #define PL080_CONTROL_SRC_INCR (1 << 26) diff --git a/arch/arm/mach-s3c64xx/dma.c b/arch/arm/mach-s3c64xx/dma.c index 5567e037b0d1..e7d03ab41d80 100644 --- a/arch/arm/mach-s3c64xx/dma.c +++ b/arch/arm/mach-s3c64xx/dma.c @@ -697,7 +697,7 @@ static int s3c64xx_dma_init1(int chno, enum dma_ch chbase, chptr->number = chno; chptr->dmac = dmac; chptr->regs = regptr; - regptr += PL008_Cx_STRIDE; + regptr += PL080_Cx_STRIDE; } /* for the moment, permanently enable the controller */ -- cgit v1.2.3 From bf56fba6703592149e1bcd19220c60eb42dff9b7 Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Sat, 14 Aug 2010 10:20:19 +0200 Subject: archs: replace unifdef-y with header-y unifdef-y and header-y have same semantic, so drop unifdef-y Signed-off-by: Sam Ravnborg --- arch/alpha/include/asm/Kbuild | 11 ++++----- arch/arm/include/asm/Kbuild | 2 +- arch/blackfin/include/asm/Kbuild | 4 +-- arch/cris/include/asm/Kbuild | 5 ++-- arch/frv/include/asm/Kbuild | 3 +-- arch/ia64/include/asm/Kbuild | 9 +++---- arch/parisc/include/asm/Kbuild | 2 +- arch/powerpc/include/asm/Kbuild | 53 ++++++++++++++++++++-------------------- arch/s390/include/asm/Kbuild | 11 ++++----- arch/sh/include/asm/Kbuild | 9 +++---- arch/x86/include/asm/Kbuild | 29 +++++++++++----------- 11 files changed, 65 insertions(+), 73 deletions(-) (limited to 'arch/arm/include') diff --git a/arch/alpha/include/asm/Kbuild b/arch/alpha/include/asm/Kbuild index b7c8f188b313..e423defed91e 100644 --- a/arch/alpha/include/asm/Kbuild +++ b/arch/alpha/include/asm/Kbuild @@ -1,11 +1,10 @@ include include/asm-generic/Kbuild.asm +header-y += compiler.h +header-y += console.h +header-y += fpu.h header-y += gentrap.h -header-y += regdef.h header-y += pal.h header-y += reg.h - -unifdef-y += console.h -unifdef-y += fpu.h -unifdef-y += sysinfo.h -unifdef-y += compiler.h +header-y += regdef.h +header-y += sysinfo.h diff --git a/arch/arm/include/asm/Kbuild b/arch/arm/include/asm/Kbuild index 73237bd130a2..6550db3aa5c7 100644 --- a/arch/arm/include/asm/Kbuild +++ b/arch/arm/include/asm/Kbuild @@ -1,3 +1,3 @@ include include/asm-generic/Kbuild.asm -unifdef-y += hwcap.h +header-y += hwcap.h diff --git a/arch/blackfin/include/asm/Kbuild b/arch/blackfin/include/asm/Kbuild index 09c31418cc08..d9eb29e2555c 100644 --- a/arch/blackfin/include/asm/Kbuild +++ b/arch/blackfin/include/asm/Kbuild @@ -1,4 +1,4 @@ include include/asm-generic/Kbuild.asm -unifdef-y += bfin_sport.h -unifdef-y += fixed_code.h +header-y += bfin_sport.h +header-y += fixed_code.h diff --git a/arch/cris/include/asm/Kbuild b/arch/cris/include/asm/Kbuild index d5b631935ec8..956eea246b97 100644 --- a/arch/cris/include/asm/Kbuild +++ b/arch/cris/include/asm/Kbuild @@ -4,8 +4,7 @@ header-y += arch-v10/ header-y += arch-v32/ header-y += ethernet.h +header-y += etraxgpio.h +header-y += rs485.h header-y += rtc.h header-y += sync_serial.h - -unifdef-y += etraxgpio.h -unifdef-y += rs485.h diff --git a/arch/frv/include/asm/Kbuild b/arch/frv/include/asm/Kbuild index 0f8956def738..5be6663cfee5 100644 --- a/arch/frv/include/asm/Kbuild +++ b/arch/frv/include/asm/Kbuild @@ -1,5 +1,4 @@ include include/asm-generic/Kbuild.asm header-y += registers.h - -unifdef-y += termios.h +header-y += termios.h diff --git a/arch/ia64/include/asm/Kbuild b/arch/ia64/include/asm/Kbuild index c7d0a71b9242..241d1c53ba69 100644 --- a/arch/ia64/include/asm/Kbuild +++ b/arch/ia64/include/asm/Kbuild @@ -2,14 +2,13 @@ include include/asm-generic/Kbuild.asm header-y += break.h header-y += fpu.h +header-y += gcc_intrin.h header-y += ia64regs.h header-y += intel_intrin.h +header-y += intrinsics.h +header-y += perfmon.h header-y += perfmon_default_smpl.h header-y += ptrace_offsets.h header-y += rse.h header-y += ucontext.h - -unifdef-y += gcc_intrin.h -unifdef-y += intrinsics.h -unifdef-y += perfmon.h -unifdef-y += ustack.h +header-y += ustack.h diff --git a/arch/parisc/include/asm/Kbuild b/arch/parisc/include/asm/Kbuild index f88b252e419c..19a434f55059 100644 --- a/arch/parisc/include/asm/Kbuild +++ b/arch/parisc/include/asm/Kbuild @@ -1,3 +1,3 @@ include include/asm-generic/Kbuild.asm -unifdef-y += pdc.h +header-y += pdc.h diff --git a/arch/powerpc/include/asm/Kbuild b/arch/powerpc/include/asm/Kbuild index 5ab7d7fe198c..d51df17c7e6f 100644 --- a/arch/powerpc/include/asm/Kbuild +++ b/arch/powerpc/include/asm/Kbuild @@ -1,37 +1,36 @@ include include/asm-generic/Kbuild.asm header-y += auxvec.h -header-y += ioctls.h -header-y += sembuf.h -header-y += siginfo.h -header-y += stat.h +header-y += bootx.h +header-y += byteorder.h +header-y += cputable.h +header-y += elf.h header-y += errno.h -header-y += ipcbuf.h -header-y += msgbuf.h -header-y += shmbuf.h -header-y += socket.h -header-y += termbits.h header-y += fcntl.h -header-y += poll.h -header-y += sockios.h -header-y += ucontext.h header-y += ioctl.h +header-y += ioctls.h +header-y += ipcbuf.h header-y += linkage.h +header-y += msgbuf.h +header-y += nvram.h +header-y += param.h +header-y += poll.h +header-y += posix_types.h +header-y += ps3fb.h header-y += resource.h +header-y += seccomp.h +header-y += sembuf.h +header-y += shmbuf.h header-y += sigcontext.h +header-y += siginfo.h +header-y += signal.h +header-y += socket.h +header-y += sockios.h +header-y += spu_info.h +header-y += stat.h header-y += statfs.h -header-y += ps3fb.h - -unifdef-y += bootx.h -unifdef-y += byteorder.h -unifdef-y += cputable.h -unifdef-y += elf.h -unifdef-y += nvram.h -unifdef-y += param.h -unifdef-y += posix_types.h -unifdef-y += seccomp.h -unifdef-y += signal.h -unifdef-y += spu_info.h -unifdef-y += termios.h -unifdef-y += types.h -unifdef-y += unistd.h +header-y += termbits.h +header-y += termios.h +header-y += types.h +header-y += ucontext.h +header-y += unistd.h diff --git a/arch/s390/include/asm/Kbuild b/arch/s390/include/asm/Kbuild index 63a23415fba6..42e512ba8b43 100644 --- a/arch/s390/include/asm/Kbuild +++ b/arch/s390/include/asm/Kbuild @@ -1,15 +1,14 @@ include include/asm-generic/Kbuild.asm +header-y += chpid.h +header-y += chsc.h +header-y += cmb.h header-y += dasd.h +header-y += debug.h header-y += monwriter.h header-y += qeth.h +header-y += schid.h header-y += tape390.h header-y += ucontext.h header-y += vtoc.h header-y += zcrypt.h -header-y += chsc.h - -unifdef-y += cmb.h -unifdef-y += debug.h -unifdef-y += chpid.h -unifdef-y += schid.h diff --git a/arch/sh/include/asm/Kbuild b/arch/sh/include/asm/Kbuild index 46cb93477bcb..0eed47b236ab 100644 --- a/arch/sh/include/asm/Kbuild +++ b/arch/sh/include/asm/Kbuild @@ -3,8 +3,7 @@ include include/asm-generic/Kbuild.asm header-y += cachectl.h header-y += cpu-features.h header-y += hw_breakpoint.h - -unifdef-y += unistd_32.h -unifdef-y += unistd_64.h -unifdef-y += posix_types_32.h -unifdef-y += posix_types_64.h +header-y += posix_types_32.h +header-y += posix_types_64.h +header-y += unistd_32.h +header-y += unistd_64.h diff --git a/arch/x86/include/asm/Kbuild b/arch/x86/include/asm/Kbuild index 493092efaa3b..6fa90a845e4c 100644 --- a/arch/x86/include/asm/Kbuild +++ b/arch/x86/include/asm/Kbuild @@ -3,24 +3,23 @@ include include/asm-generic/Kbuild.asm header-y += boot.h header-y += bootparam.h header-y += debugreg.h +header-y += e820.h +header-y += hw_breakpoint.h +header-y += hyperv.h +header-y += ist.h header-y += ldt.h +header-y += mce.h header-y += msr-index.h +header-y += msr.h +header-y += mtrr.h +header-y += posix_types_32.h +header-y += posix_types_64.h header-y += prctl.h +header-y += processor-flags.h header-y += ptrace-abi.h header-y += sigcontext32.h header-y += ucontext.h -header-y += processor-flags.h -header-y += hw_breakpoint.h -header-y += hyperv.h - -unifdef-y += e820.h -unifdef-y += ist.h -unifdef-y += mce.h -unifdef-y += msr.h -unifdef-y += mtrr.h -unifdef-y += posix_types_32.h -unifdef-y += posix_types_64.h -unifdef-y += unistd_32.h -unifdef-y += unistd_64.h -unifdef-y += vm86.h -unifdef-y += vsyscall.h +header-y += unistd_32.h +header-y += unistd_64.h +header-y += vm86.h +header-y += vsyscall.h -- cgit v1.2.3