From 9a244b95ddb62a17b62f4b061b6e13ca4d177942 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Wed, 11 Oct 2006 19:30:03 +0100 Subject: [MIPS] Pass NULL not 0 for pointer value. Signed-off-by: Ralf Baechle --- arch/mips/kernel/smp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/mips/kernel') diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c index 1af3612a1ce8..db80957ada89 100644 --- a/arch/mips/kernel/smp.c +++ b/arch/mips/kernel/smp.c @@ -310,7 +310,7 @@ static void flush_tlb_all_ipi(void *info) void flush_tlb_all(void) { - on_each_cpu(flush_tlb_all_ipi, 0, 1, 1); + on_each_cpu(flush_tlb_all_ipi, NULL, 1, 1); } static void flush_tlb_mm_ipi(void *mm) -- cgit v1.2.3 From 55b7428303d390c53d3a1bc587de8592ce65900e Mon Sep 17 00:00:00 2001 From: Franck Bui-Huu Date: Fri, 13 Oct 2006 13:37:35 +0200 Subject: [MIPS] Use kallsyms_lookup_size_offset() instead of kallsyms_lookup() This new routine doesn't lookup for symbol names. So we needn't to pass any char buffers or pointer since we don't care about names. Signed-off-by: Franck Bui-Huu Signed-off-by: Ralf Baechle --- arch/mips/kernel/process.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'arch/mips/kernel') diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c index 9f307eb1a31e..ec8209f3a0c6 100644 --- a/arch/mips/kernel/process.c +++ b/arch/mips/kernel/process.c @@ -358,10 +358,8 @@ static int __init frame_info_init(void) unsigned long size = 0; #ifdef CONFIG_KALLSYMS unsigned long ofs; - char *modname; - char namebuf[KSYM_NAME_LEN + 1]; - kallsyms_lookup((unsigned long)schedule, &size, &ofs, &modname, namebuf); + kallsyms_lookup_size_offset((unsigned long)schedule, &size, &ofs); #endif schedule_mfi.func = schedule; schedule_mfi.func_size = size; @@ -403,8 +401,6 @@ unsigned long unwind_stack(struct task_struct *task, unsigned long *sp, { unsigned long stack_page; struct mips_frame_info info; - char *modname; - char namebuf[KSYM_NAME_LEN + 1]; unsigned long size, ofs; int leaf; extern void ret_from_irq(void); @@ -433,7 +429,7 @@ unsigned long unwind_stack(struct task_struct *task, unsigned long *sp, } return 0; } - if (!kallsyms_lookup(pc, &size, &ofs, &modname, namebuf)) + if (!kallsyms_lookup_size_offset(pc, &size, &ofs)) return 0; /* * Return ra if an exception occured at the first instruction -- cgit v1.2.3 From 53571ce47010562f5e67782ea00206f379a5cd65 Mon Sep 17 00:00:00 2001 From: Thiemo Seufer Date: Sun, 13 Aug 2006 00:53:29 +0100 Subject: [MIPS] Fix O32 personality(2) call with 0xffffffff argument. A sign extension bug did result in sys_personality being invoked with a 0xffffffffffffffffUL argument, so querying the current personality didn't work. Signed-off-by: Thiemo Seufer Signed-off-by: Ralf Baechle --- arch/mips/kernel/linux32.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'arch/mips/kernel') diff --git a/arch/mips/kernel/linux32.c b/arch/mips/kernel/linux32.c index 53f4171fc188..7a3ebbeba1f3 100644 --- a/arch/mips/kernel/linux32.c +++ b/arch/mips/kernel/linux32.c @@ -1055,7 +1055,9 @@ asmlinkage long sys32_newuname(struct new_utsname __user * name) asmlinkage int sys32_personality(unsigned long personality) { int ret; - if (current->personality == PER_LINUX32 && personality == PER_LINUX) + personality &= 0xffffffff; + if (personality(current->personality) == PER_LINUX32 && + personality == PER_LINUX) personality = PER_LINUX32; ret = sys_personality(personality); if (ret == PER_LINUX32) -- cgit v1.2.3 From 089c7e7f2da7c3245de47377252683bd9edae738 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Mon, 16 Oct 2006 16:49:37 +0100 Subject: [MIPS] Use compat_sys_mount. This fixes mount problems with smbfs, ncpfs and NFSv4. Signed-off-by: Ralf Baechle --- arch/mips/kernel/scall64-n32.S | 2 +- arch/mips/kernel/scall64-o32.S | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'arch/mips/kernel') diff --git a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S index 6d9f18727ac5..8c453f8ffea6 100644 --- a/arch/mips/kernel/scall64-n32.S +++ b/arch/mips/kernel/scall64-n32.S @@ -280,7 +280,7 @@ EXPORT(sysn32_call_table) PTR sys_sync PTR sys_acct PTR sys32_settimeofday - PTR sys_mount /* 6160 */ + PTR compat_sys_mount /* 6160 */ PTR sys_umount PTR sys_swapon PTR sys_swapoff diff --git a/arch/mips/kernel/scall64-o32.S b/arch/mips/kernel/scall64-o32.S index 2e6d0673163e..d105917d6d93 100644 --- a/arch/mips/kernel/scall64-o32.S +++ b/arch/mips/kernel/scall64-o32.S @@ -226,7 +226,7 @@ sys_call_table: PTR sys_ni_syscall /* was sys_stat */ PTR sys_lseek PTR sys_getpid /* 4020 */ - PTR sys_mount + PTR compat_sys_mount PTR sys_oldumount PTR sys_setuid PTR sys_getuid -- cgit v1.2.3 From eea32d4c6e272b6c324c8c22df4c28274fcb5a21 Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Mon, 16 Oct 2006 22:48:49 +0900 Subject: [MIPS] save_context_stack fix CONFIG_KALLSYMS=n case is obviously wrong, though it is harmless since CONFIG_KALLSYMS is always enabled with CONFIG_STACKTRACE for now. Signed-off-by: Atsushi Nemoto Signed-off-by: Ralf Baechle --- arch/mips/kernel/stacktrace.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/mips/kernel') diff --git a/arch/mips/kernel/stacktrace.c b/arch/mips/kernel/stacktrace.c index 4aabe526a68e..a586aba337a7 100644 --- a/arch/mips/kernel/stacktrace.c +++ b/arch/mips/kernel/stacktrace.c @@ -57,7 +57,7 @@ static void save_context_stack(struct stack_trace *trace, pc = unwind_stack(task, &sp, pc, &ra); } while (pc); #else - save_raw_context_stack(sp); + save_raw_context_stack(trace, sp); #endif } -- cgit v1.2.3 From d2bcf87d0fcdc10d1be65b03fd032bec05efe49f Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Wed, 18 Oct 2006 23:52:17 +0100 Subject: [MIPS] Reserve syscall numbers for kexec_load. Signed-off-by: Ralf Baechle --- arch/mips/kernel/scall32-o32.S | 3 ++- arch/mips/kernel/scall64-64.S | 1 + arch/mips/kernel/scall64-n32.S | 1 + arch/mips/kernel/scall64-o32.S | 1 + include/asm-mips/unistd.h | 15 +++++++++------ 5 files changed, 14 insertions(+), 7 deletions(-) (limited to 'arch/mips/kernel') diff --git a/arch/mips/kernel/scall32-o32.S b/arch/mips/kernel/scall32-o32.S index 61362e6fa9ec..720fac3435d5 100644 --- a/arch/mips/kernel/scall32-o32.S +++ b/arch/mips/kernel/scall32-o32.S @@ -652,7 +652,8 @@ einval: li v0, -EINVAL sys sys_vmsplice 4 sys sys_move_pages 6 sys sys_set_robust_list 2 - sys sys_get_robust_list 3 + sys sys_get_robust_list 3 /* 4310 */ + sys sys_ni_syscall 0 .endm /* We pre-compute the number of _instruction_ bytes needed to diff --git a/arch/mips/kernel/scall64-64.S b/arch/mips/kernel/scall64-64.S index 6c7b5ed0ea6e..3a34f62c8b1b 100644 --- a/arch/mips/kernel/scall64-64.S +++ b/arch/mips/kernel/scall64-64.S @@ -468,3 +468,4 @@ sys_call_table: PTR sys_move_pages PTR sys_set_robust_list PTR sys_get_robust_list + PTR sys_ni_syscall /* 5270 */ diff --git a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S index 8c453f8ffea6..67b92a1d6c72 100644 --- a/arch/mips/kernel/scall64-n32.S +++ b/arch/mips/kernel/scall64-n32.S @@ -394,3 +394,4 @@ EXPORT(sysn32_call_table) PTR sys_move_pages PTR compat_sys_set_robust_list PTR compat_sys_get_robust_list + PTR sys_ni_syscall diff --git a/arch/mips/kernel/scall64-o32.S b/arch/mips/kernel/scall64-o32.S index d105917d6d93..2875c4a3fa58 100644 --- a/arch/mips/kernel/scall64-o32.S +++ b/arch/mips/kernel/scall64-o32.S @@ -516,4 +516,5 @@ sys_call_table: PTR compat_sys_move_pages PTR compat_sys_set_robust_list PTR compat_sys_get_robust_list /* 4310 */ + PTR sys_ni_syscall .size sys_call_table,.-sys_call_table diff --git a/include/asm-mips/unistd.h b/include/asm-mips/unistd.h index 685c91467e63..30240a445dbb 100644 --- a/include/asm-mips/unistd.h +++ b/include/asm-mips/unistd.h @@ -331,16 +331,17 @@ #define __NR_move_pages (__NR_Linux + 308) #define __NR_set_robust_list (__NR_Linux + 309) #define __NR_get_robust_list (__NR_Linux + 310) +#define __NR_kexec_load (__NR_Linux + 311) /* * Offset of the last Linux o32 flavoured syscall */ -#define __NR_Linux_syscalls 310 +#define __NR_Linux_syscalls 311 #endif /* _MIPS_SIM == _MIPS_SIM_ABI32 */ #define __NR_O32_Linux 4000 -#define __NR_O32_Linux_syscalls 310 +#define __NR_O32_Linux_syscalls 311 #if _MIPS_SIM == _MIPS_SIM_ABI64 @@ -618,16 +619,17 @@ #define __NR_move_pages (__NR_Linux + 267) #define __NR_set_robust_list (__NR_Linux + 268) #define __NR_get_robust_list (__NR_Linux + 269) +#define __NR_kexec_load (__NR_Linux + 270) /* * Offset of the last Linux 64-bit flavoured syscall */ -#define __NR_Linux_syscalls 269 +#define __NR_Linux_syscalls 270 #endif /* _MIPS_SIM == _MIPS_SIM_ABI64 */ #define __NR_64_Linux 5000 -#define __NR_64_Linux_syscalls 269 +#define __NR_64_Linux_syscalls 270 #if _MIPS_SIM == _MIPS_SIM_NABI32 @@ -909,16 +911,17 @@ #define __NR_move_pages (__NR_Linux + 271) #define __NR_set_robust_list (__NR_Linux + 272) #define __NR_get_robust_list (__NR_Linux + 273) +#define __NR_kexec_load (__NR_Linux + 274) /* * Offset of the last N32 flavoured syscall */ -#define __NR_Linux_syscalls 273 +#define __NR_Linux_syscalls 274 #endif /* _MIPS_SIM == _MIPS_SIM_NABI32 */ #define __NR_N32_Linux 6000 -#define __NR_N32_Linux_syscalls 273 +#define __NR_N32_Linux_syscalls 274 #ifdef __KERNEL__ -- cgit v1.2.3 From 61ce1efe6e40233663d27ab8ac9ba9710eebcaad Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Fri, 27 Oct 2006 11:41:44 -0700 Subject: [PATCH] vmlinux.lds: consolidate initcall sections Add a vmlinux.lds.h helper macro for defining the eight-level initcall table, teach all the architectures to use it. This is a prerequisite for a patch which performs initcall synchronisation for multithreaded-probing. Cc: Greg KH Signed-off-by: Andrew Morton [ Added AVR32 as well ] Signed-off-by: Haavard Skinnemoen Signed-off-by: Linus Torvalds --- arch/alpha/kernel/vmlinux.lds.S | 8 +------- arch/arm/kernel/vmlinux.lds.S | 8 +------- arch/avr32/kernel/vmlinux.lds.c | 8 +------- arch/frv/kernel/vmlinux.lds.S | 8 +------- arch/h8300/kernel/vmlinux.lds.S | 8 +------- arch/i386/kernel/vmlinux.lds.S | 8 +------- arch/ia64/kernel/vmlinux.lds.S | 8 +------- arch/m32r/kernel/vmlinux.lds.S | 8 +------- arch/m68knommu/kernel/vmlinux.lds.S | 8 +------- arch/mips/kernel/vmlinux.lds.S | 8 +------- arch/parisc/kernel/vmlinux.lds.S | 8 +------- arch/powerpc/kernel/vmlinux.lds.S | 8 +------- arch/ppc/kernel/vmlinux.lds.S | 8 +------- arch/s390/kernel/vmlinux.lds.S | 8 +------- arch/sh/kernel/vmlinux.lds.S | 8 +------- arch/sh64/kernel/vmlinux.lds.S | 8 +------- arch/sparc/kernel/vmlinux.lds.S | 8 +------- arch/sparc64/kernel/vmlinux.lds.S | 8 +------- arch/v850/kernel/vmlinux.lds.S | 8 +------- arch/x86_64/kernel/vmlinux.lds.S | 8 +------- arch/xtensa/kernel/vmlinux.lds.S | 8 +------- include/asm-generic/vmlinux.lds.h | 10 ++++++++++ 22 files changed, 31 insertions(+), 147 deletions(-) (limited to 'arch/mips/kernel') diff --git a/arch/alpha/kernel/vmlinux.lds.S b/arch/alpha/kernel/vmlinux.lds.S index 71470e9d93ba..76bf071e376c 100644 --- a/arch/alpha/kernel/vmlinux.lds.S +++ b/arch/alpha/kernel/vmlinux.lds.S @@ -48,13 +48,7 @@ SECTIONS . = ALIGN(8); __initcall_start = .; .initcall.init : { - *(.initcall1.init) - *(.initcall2.init) - *(.initcall3.init) - *(.initcall4.init) - *(.initcall5.init) - *(.initcall6.init) - *(.initcall7.init) + INITCALLS } __initcall_end = .; diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S index 3ca574ee2772..a8fa75ea07a9 100644 --- a/arch/arm/kernel/vmlinux.lds.S +++ b/arch/arm/kernel/vmlinux.lds.S @@ -45,13 +45,7 @@ SECTIONS *(.early_param.init) __early_end = .; __initcall_start = .; - *(.initcall1.init) - *(.initcall2.init) - *(.initcall3.init) - *(.initcall4.init) - *(.initcall5.init) - *(.initcall6.init) - *(.initcall7.init) + INITCALLS __initcall_end = .; __con_initcall_start = .; *(.con_initcall.init) diff --git a/arch/avr32/kernel/vmlinux.lds.c b/arch/avr32/kernel/vmlinux.lds.c index cdd627c6b7dc..5c4424e362b5 100644 --- a/arch/avr32/kernel/vmlinux.lds.c +++ b/arch/avr32/kernel/vmlinux.lds.c @@ -38,13 +38,7 @@ SECTIONS __setup_end = .; . = ALIGN(4); __initcall_start = .; - *(.initcall1.init) - *(.initcall2.init) - *(.initcall3.init) - *(.initcall4.init) - *(.initcall5.init) - *(.initcall6.init) - *(.initcall7.init) + INITCALLS __initcall_end = .; __con_initcall_start = .; *(.con_initcall.init) diff --git a/arch/frv/kernel/vmlinux.lds.S b/arch/frv/kernel/vmlinux.lds.S index f474534ba78a..9c1fb12367fa 100644 --- a/arch/frv/kernel/vmlinux.lds.S +++ b/arch/frv/kernel/vmlinux.lds.S @@ -44,13 +44,7 @@ SECTIONS __initcall_start = .; .initcall.init : { - *(.initcall1.init) - *(.initcall2.init) - *(.initcall3.init) - *(.initcall4.init) - *(.initcall5.init) - *(.initcall6.init) - *(.initcall7.init) + INITCALLS } __initcall_end = .; __con_initcall_start = .; diff --git a/arch/h8300/kernel/vmlinux.lds.S b/arch/h8300/kernel/vmlinux.lds.S index 6406c388f88a..756325dd480e 100644 --- a/arch/h8300/kernel/vmlinux.lds.S +++ b/arch/h8300/kernel/vmlinux.lds.S @@ -118,13 +118,7 @@ SECTIONS . = ALIGN(0x4) ; ___setup_end = .; ___initcall_start = .; - *(.initcall1.init) - *(.initcall2.init) - *(.initcall3.init) - *(.initcall4.init) - *(.initcall5.init) - *(.initcall6.init) - *(.initcall7.init) + INITCALLS ___initcall_end = .; ___con_initcall_start = .; *(.con_initcall.init) diff --git a/arch/i386/kernel/vmlinux.lds.S b/arch/i386/kernel/vmlinux.lds.S index 1e7ac1c44ddc..adc1f232afee 100644 --- a/arch/i386/kernel/vmlinux.lds.S +++ b/arch/i386/kernel/vmlinux.lds.S @@ -126,13 +126,7 @@ SECTIONS __setup_end = .; __initcall_start = .; .initcall.init : AT(ADDR(.initcall.init) - LOAD_OFFSET) { - *(.initcall1.init) - *(.initcall2.init) - *(.initcall3.init) - *(.initcall4.init) - *(.initcall5.init) - *(.initcall6.init) - *(.initcall7.init) + INITCALLS } __initcall_end = .; __con_initcall_start = .; diff --git a/arch/ia64/kernel/vmlinux.lds.S b/arch/ia64/kernel/vmlinux.lds.S index b3b2e389d6b2..d6083a0936f4 100644 --- a/arch/ia64/kernel/vmlinux.lds.S +++ b/arch/ia64/kernel/vmlinux.lds.S @@ -128,13 +128,7 @@ SECTIONS .initcall.init : AT(ADDR(.initcall.init) - LOAD_OFFSET) { __initcall_start = .; - *(.initcall1.init) - *(.initcall2.init) - *(.initcall3.init) - *(.initcall4.init) - *(.initcall5.init) - *(.initcall6.init) - *(.initcall7.init) + INITCALLS __initcall_end = .; } diff --git a/arch/m32r/kernel/vmlinux.lds.S b/arch/m32r/kernel/vmlinux.lds.S index 13c7bb698e37..358b9cee2c65 100644 --- a/arch/m32r/kernel/vmlinux.lds.S +++ b/arch/m32r/kernel/vmlinux.lds.S @@ -83,13 +83,7 @@ SECTIONS __setup_end = .; __initcall_start = .; .initcall.init : { - *(.initcall1.init) - *(.initcall2.init) - *(.initcall3.init) - *(.initcall4.init) - *(.initcall5.init) - *(.initcall6.init) - *(.initcall7.init) + INITCALLS } __initcall_end = .; __con_initcall_start = .; diff --git a/arch/m68knommu/kernel/vmlinux.lds.S b/arch/m68knommu/kernel/vmlinux.lds.S index ccd2ceb05cfb..58afa8be604e 100644 --- a/arch/m68knommu/kernel/vmlinux.lds.S +++ b/arch/m68knommu/kernel/vmlinux.lds.S @@ -140,13 +140,7 @@ SECTIONS { *(.init.setup) __setup_end = .; __initcall_start = .; - *(.initcall1.init) - *(.initcall2.init) - *(.initcall3.init) - *(.initcall4.init) - *(.initcall5.init) - *(.initcall6.init) - *(.initcall7.init) + INITCALLS __initcall_end = .; __con_initcall_start = .; *(.con_initcall.init) diff --git a/arch/mips/kernel/vmlinux.lds.S b/arch/mips/kernel/vmlinux.lds.S index 0bb9cd889456..25ed3337ce35 100644 --- a/arch/mips/kernel/vmlinux.lds.S +++ b/arch/mips/kernel/vmlinux.lds.S @@ -91,13 +91,7 @@ SECTIONS __initcall_start = .; .initcall.init : { - *(.initcall1.init) - *(.initcall2.init) - *(.initcall3.init) - *(.initcall4.init) - *(.initcall5.init) - *(.initcall6.init) - *(.initcall7.init) + INITCALLS } __initcall_end = .; diff --git a/arch/parisc/kernel/vmlinux.lds.S b/arch/parisc/kernel/vmlinux.lds.S index b3677fc8eef5..7b943b45f7cd 100644 --- a/arch/parisc/kernel/vmlinux.lds.S +++ b/arch/parisc/kernel/vmlinux.lds.S @@ -153,13 +153,7 @@ SECTIONS __setup_end = .; __initcall_start = .; .initcall.init : { - *(.initcall1.init) - *(.initcall2.init) - *(.initcall3.init) - *(.initcall4.init) - *(.initcall5.init) - *(.initcall6.init) - *(.initcall7.init) + INITCALLS } __initcall_end = .; __con_initcall_start = .; diff --git a/arch/powerpc/kernel/vmlinux.lds.S b/arch/powerpc/kernel/vmlinux.lds.S index cb0e8d46c3e8..e8342d867536 100644 --- a/arch/powerpc/kernel/vmlinux.lds.S +++ b/arch/powerpc/kernel/vmlinux.lds.S @@ -108,13 +108,7 @@ SECTIONS .initcall.init : { __initcall_start = .; - *(.initcall1.init) - *(.initcall2.init) - *(.initcall3.init) - *(.initcall4.init) - *(.initcall5.init) - *(.initcall6.init) - *(.initcall7.init) + INITCALLS __initcall_end = .; } diff --git a/arch/ppc/kernel/vmlinux.lds.S b/arch/ppc/kernel/vmlinux.lds.S index 095fd3323323..16e8661e1fec 100644 --- a/arch/ppc/kernel/vmlinux.lds.S +++ b/arch/ppc/kernel/vmlinux.lds.S @@ -115,13 +115,7 @@ SECTIONS __setup_end = .; __initcall_start = .; .initcall.init : { - *(.initcall1.init) - *(.initcall2.init) - *(.initcall3.init) - *(.initcall4.init) - *(.initcall5.init) - *(.initcall6.init) - *(.initcall7.init) + INITCALLS } __initcall_end = .; diff --git a/arch/s390/kernel/vmlinux.lds.S b/arch/s390/kernel/vmlinux.lds.S index af9e69a03011..fe0f2e97ba7b 100644 --- a/arch/s390/kernel/vmlinux.lds.S +++ b/arch/s390/kernel/vmlinux.lds.S @@ -83,13 +83,7 @@ SECTIONS __setup_end = .; __initcall_start = .; .initcall.init : { - *(.initcall1.init) - *(.initcall2.init) - *(.initcall3.init) - *(.initcall4.init) - *(.initcall5.init) - *(.initcall6.init) - *(.initcall7.init) + INITCALLS } __initcall_end = .; __con_initcall_start = .; diff --git a/arch/sh/kernel/vmlinux.lds.S b/arch/sh/kernel/vmlinux.lds.S index 5eb930918186..77b4026d5688 100644 --- a/arch/sh/kernel/vmlinux.lds.S +++ b/arch/sh/kernel/vmlinux.lds.S @@ -76,13 +76,7 @@ SECTIONS __setup_end = .; __initcall_start = .; .initcall.init : { - *(.initcall1.init) - *(.initcall2.init) - *(.initcall3.init) - *(.initcall4.init) - *(.initcall5.init) - *(.initcall6.init) - *(.initcall7.init) + INITCALLS } __initcall_end = .; __con_initcall_start = .; diff --git a/arch/sh64/kernel/vmlinux.lds.S b/arch/sh64/kernel/vmlinux.lds.S index a8fcc3a71585..95c4d753e357 100644 --- a/arch/sh64/kernel/vmlinux.lds.S +++ b/arch/sh64/kernel/vmlinux.lds.S @@ -108,13 +108,7 @@ SECTIONS __setup_end = .; __initcall_start = .; .initcall.init : C_PHYS(.initcall.init) { - *(.initcall1.init) - *(.initcall2.init) - *(.initcall3.init) - *(.initcall4.init) - *(.initcall5.init) - *(.initcall6.init) - *(.initcall7.init) + INITCALLS } __initcall_end = .; __con_initcall_start = .; diff --git a/arch/sparc/kernel/vmlinux.lds.S b/arch/sparc/kernel/vmlinux.lds.S index 1dd78c84888a..5cc5ff7f8824 100644 --- a/arch/sparc/kernel/vmlinux.lds.S +++ b/arch/sparc/kernel/vmlinux.lds.S @@ -49,13 +49,7 @@ SECTIONS __setup_end = .; __initcall_start = .; .initcall.init : { - *(.initcall1.init) - *(.initcall2.init) - *(.initcall3.init) - *(.initcall4.init) - *(.initcall5.init) - *(.initcall6.init) - *(.initcall7.init) + INITCALLS } __initcall_end = .; __con_initcall_start = .; diff --git a/arch/sparc64/kernel/vmlinux.lds.S b/arch/sparc64/kernel/vmlinux.lds.S index b097379a49a8..bd9de8c2a2aa 100644 --- a/arch/sparc64/kernel/vmlinux.lds.S +++ b/arch/sparc64/kernel/vmlinux.lds.S @@ -57,13 +57,7 @@ SECTIONS __setup_end = .; __initcall_start = .; .initcall.init : { - *(.initcall1.init) - *(.initcall2.init) - *(.initcall3.init) - *(.initcall4.init) - *(.initcall5.init) - *(.initcall6.init) - *(.initcall7.init) + INITCALLS } __initcall_end = .; __con_initcall_start = .; diff --git a/arch/v850/kernel/vmlinux.lds.S b/arch/v850/kernel/vmlinux.lds.S index 63399219cd9f..88d087f527c9 100644 --- a/arch/v850/kernel/vmlinux.lds.S +++ b/arch/v850/kernel/vmlinux.lds.S @@ -140,13 +140,7 @@ ___setup_end = . ; \ ___initcall_start = . ; \ *(.initcall.init) \ - *(.initcall1.init) \ - *(.initcall2.init) \ - *(.initcall3.init) \ - *(.initcall4.init) \ - *(.initcall5.init) \ - *(.initcall6.init) \ - *(.initcall7.init) \ + INITCALLS \ . = ALIGN (4) ; \ ___initcall_end = . ; \ ___con_initcall_start = .; \ diff --git a/arch/x86_64/kernel/vmlinux.lds.S b/arch/x86_64/kernel/vmlinux.lds.S index 1283614c9b24..edb24aa714b4 100644 --- a/arch/x86_64/kernel/vmlinux.lds.S +++ b/arch/x86_64/kernel/vmlinux.lds.S @@ -175,13 +175,7 @@ SECTIONS __setup_end = .; __initcall_start = .; .initcall.init : AT(ADDR(.initcall.init) - LOAD_OFFSET) { - *(.initcall1.init) - *(.initcall2.init) - *(.initcall3.init) - *(.initcall4.init) - *(.initcall5.init) - *(.initcall6.init) - *(.initcall7.init) + INITCALLS } __initcall_end = .; __con_initcall_start = .; diff --git a/arch/xtensa/kernel/vmlinux.lds.S b/arch/xtensa/kernel/vmlinux.lds.S index ab6cdbd5eb68..cfe75f528725 100644 --- a/arch/xtensa/kernel/vmlinux.lds.S +++ b/arch/xtensa/kernel/vmlinux.lds.S @@ -184,13 +184,7 @@ SECTIONS __initcall_start = .; .initcall.init : { - *(.initcall1.init) - *(.initcall2.init) - *(.initcall3.init) - *(.initcall4.init) - *(.initcall5.init) - *(.initcall6.init) - *(.initcall7.init) + INITCALLS } __initcall_end = .; diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h index 9d0d11c180d9..e3e83bcaf710 100644 --- a/include/asm-generic/vmlinux.lds.h +++ b/include/asm-generic/vmlinux.lds.h @@ -213,3 +213,13 @@ #define NOTES \ .notes : { *(.note.*) } :note + +#define INITCALLS \ + *(.initcall1.init) \ + *(.initcall2.init) \ + *(.initcall3.init) \ + *(.initcall4.init) \ + *(.initcall5.init) \ + *(.initcall6.init) \ + *(.initcall7.init) + -- cgit v1.2.3 From 991ea26dcbc2524a054f37911ea375e631cb8891 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Sun, 29 Oct 2006 21:07:40 +0000 Subject: [MIPS] Wire up getcpu(2) and epoll_wait(2) syscalls. Signed-off-by: Ralf Baechle --- arch/mips/kernel/scall32-o32.S | 2 ++ arch/mips/kernel/scall64-64.S | 2 ++ arch/mips/kernel/scall64-n32.S | 2 ++ arch/mips/kernel/scall64-o32.S | 2 ++ include/asm-mips/unistd.h | 18 ++++++++++++------ 5 files changed, 20 insertions(+), 6 deletions(-) (limited to 'arch/mips/kernel') diff --git a/arch/mips/kernel/scall32-o32.S b/arch/mips/kernel/scall32-o32.S index 720fac3435d5..a95f37de080e 100644 --- a/arch/mips/kernel/scall32-o32.S +++ b/arch/mips/kernel/scall32-o32.S @@ -654,6 +654,8 @@ einval: li v0, -EINVAL sys sys_set_robust_list 2 sys sys_get_robust_list 3 /* 4310 */ sys sys_ni_syscall 0 + sys sys_getcpu 3 + sys sys_epoll_pwait 6 .endm /* We pre-compute the number of _instruction_ bytes needed to diff --git a/arch/mips/kernel/scall64-64.S b/arch/mips/kernel/scall64-64.S index 3a34f62c8b1b..8fb0f60f657b 100644 --- a/arch/mips/kernel/scall64-64.S +++ b/arch/mips/kernel/scall64-64.S @@ -469,3 +469,5 @@ sys_call_table: PTR sys_set_robust_list PTR sys_get_robust_list PTR sys_ni_syscall /* 5270 */ + PTR sys_getcpu + PTR sys_epoll_pwait diff --git a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S index 67b92a1d6c72..0da5ca2040ff 100644 --- a/arch/mips/kernel/scall64-n32.S +++ b/arch/mips/kernel/scall64-n32.S @@ -395,3 +395,5 @@ EXPORT(sysn32_call_table) PTR compat_sys_set_robust_list PTR compat_sys_get_robust_list PTR sys_ni_syscall + PTR sys_getcpu + PTR sys_epoll_pwait diff --git a/arch/mips/kernel/scall64-o32.S b/arch/mips/kernel/scall64-o32.S index 2875c4a3fa58..b9d00cae8b5f 100644 --- a/arch/mips/kernel/scall64-o32.S +++ b/arch/mips/kernel/scall64-o32.S @@ -517,4 +517,6 @@ sys_call_table: PTR compat_sys_set_robust_list PTR compat_sys_get_robust_list /* 4310 */ PTR sys_ni_syscall + PTR sys_getcpu + PTR sys_epoll_pwait .size sys_call_table,.-sys_call_table diff --git a/include/asm-mips/unistd.h b/include/asm-mips/unistd.h index 30240a445dbb..f1ef98cc8699 100644 --- a/include/asm-mips/unistd.h +++ b/include/asm-mips/unistd.h @@ -332,16 +332,18 @@ #define __NR_set_robust_list (__NR_Linux + 309) #define __NR_get_robust_list (__NR_Linux + 310) #define __NR_kexec_load (__NR_Linux + 311) +#define __NR_getcpu (__NR_Linux + 312) +#define __NR_epoll_pwait (__NR_Linux + 313) /* * Offset of the last Linux o32 flavoured syscall */ -#define __NR_Linux_syscalls 311 +#define __NR_Linux_syscalls 313 #endif /* _MIPS_SIM == _MIPS_SIM_ABI32 */ #define __NR_O32_Linux 4000 -#define __NR_O32_Linux_syscalls 311 +#define __NR_O32_Linux_syscalls 313 #if _MIPS_SIM == _MIPS_SIM_ABI64 @@ -620,16 +622,18 @@ #define __NR_set_robust_list (__NR_Linux + 268) #define __NR_get_robust_list (__NR_Linux + 269) #define __NR_kexec_load (__NR_Linux + 270) +#define __NR_getcpu (__NR_Linux + 271) +#define __NR_epoll_pwait (__NR_Linux + 272) /* * Offset of the last Linux 64-bit flavoured syscall */ -#define __NR_Linux_syscalls 270 +#define __NR_Linux_syscalls 272 #endif /* _MIPS_SIM == _MIPS_SIM_ABI64 */ #define __NR_64_Linux 5000 -#define __NR_64_Linux_syscalls 270 +#define __NR_64_Linux_syscalls 272 #if _MIPS_SIM == _MIPS_SIM_NABI32 @@ -912,16 +916,18 @@ #define __NR_set_robust_list (__NR_Linux + 272) #define __NR_get_robust_list (__NR_Linux + 273) #define __NR_kexec_load (__NR_Linux + 274) +#define __NR_getcpu (__NR_Linux + 275) +#define __NR_epoll_pwait (__NR_Linux + 276) /* * Offset of the last N32 flavoured syscall */ -#define __NR_Linux_syscalls 274 +#define __NR_Linux_syscalls 276 #endif /* _MIPS_SIM == _MIPS_SIM_NABI32 */ #define __NR_N32_Linux 6000 -#define __NR_N32_Linux_syscalls 274 +#define __NR_N32_Linux_syscalls 276 #ifdef __KERNEL__ -- cgit v1.2.3 From 3ab0f40f333007eb31dc1e08f578ec224c7d71c2 Mon Sep 17 00:00:00 2001 From: Yoichi Yuasa Date: Tue, 31 Oct 2006 13:44:38 +0900 Subject: [MIPS] Fix warning of printk format in mips_srs_init() arch/mips/kernel/traps.c:1115: warning: int format, long unsigned int arg (arg 2) Signed-off-by: Yoichi Yuasa Signed-off-by: Ralf Baechle --- arch/mips/kernel/traps.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/mips/kernel') diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index cce8313ec27d..9fda1b8be3a7 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c @@ -1111,7 +1111,7 @@ static struct shadow_registers { static void mips_srs_init(void) { shadow_registers.sr_supported = ((read_c0_srsctl() >> 26) & 0x0f) + 1; - printk(KERN_INFO "%d MIPSR2 register sets available\n", + printk(KERN_INFO "%ld MIPSR2 register sets available\n", shadow_registers.sr_supported); shadow_registers.sr_allocated = 1; /* Set 0 used by kernel */ } -- cgit v1.2.3 From 781b0f8d4f9c90137ea32771346ab49f0e5319b3 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Tue, 31 Oct 2006 18:25:10 +0000 Subject: [MIPS] VSMP: Fix initialization ordering bug. Signed-off-by: Ralf Baechle --- arch/mips/kernel/smp-mt.c | 152 +++++++++++++++++++++++++--------------------- 1 file changed, 83 insertions(+), 69 deletions(-) (limited to 'arch/mips/kernel') diff --git a/arch/mips/kernel/smp-mt.c b/arch/mips/kernel/smp-mt.c index 3b5f3b632622..06b29fa73f56 100644 --- a/arch/mips/kernel/smp-mt.c +++ b/arch/mips/kernel/smp-mt.c @@ -140,15 +140,88 @@ static struct irqaction irq_call = { .name = "IPI_call" }; +static void __init smp_copy_vpe_config(void) +{ + write_vpe_c0_status( + (read_c0_status() & ~(ST0_IM | ST0_IE | ST0_KSU)) | ST0_CU0); + + /* set config to be the same as vpe0, particularly kseg0 coherency alg */ + write_vpe_c0_config( read_c0_config()); + + /* make sure there are no software interrupts pending */ + write_vpe_c0_cause(0); + + /* Propagate Config7 */ + write_vpe_c0_config7(read_c0_config7()); +} + +static unsigned int __init smp_vpe_init(unsigned int tc, unsigned int mvpconf0, + unsigned int ncpu) +{ + if (tc > ((mvpconf0 & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT)) + return ncpu; + + /* Deactivate all but VPE 0 */ + if (tc != 0) { + unsigned long tmp = read_vpe_c0_vpeconf0(); + + tmp &= ~VPECONF0_VPA; + + /* master VPE */ + tmp |= VPECONF0_MVP; + write_vpe_c0_vpeconf0(tmp); + + /* Record this as available CPU */ + cpu_set(tc, phys_cpu_present_map); + __cpu_number_map[tc] = ++ncpu; + __cpu_logical_map[ncpu] = tc; + } + + /* Disable multi-threading with TC's */ + write_vpe_c0_vpecontrol(read_vpe_c0_vpecontrol() & ~VPECONTROL_TE); + + if (tc != 0) + smp_copy_vpe_config(); + + return ncpu; +} + +static void __init smp_tc_init(unsigned int tc, unsigned int mvpconf0) +{ + unsigned long tmp; + + if (!tc) + return; + + /* bind a TC to each VPE, May as well put all excess TC's + on the last VPE */ + if (tc >= (((mvpconf0 & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT)+1)) + write_tc_c0_tcbind(read_tc_c0_tcbind() | ((mvpconf0 & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT)); + else { + write_tc_c0_tcbind(read_tc_c0_tcbind() | tc); + + /* and set XTC */ + write_vpe_c0_vpeconf0(read_vpe_c0_vpeconf0() | (tc << VPECONF0_XTC_SHIFT)); + } + + tmp = read_tc_c0_tcstatus(); + + /* mark not allocated and not dynamically allocatable */ + tmp &= ~(TCSTATUS_A | TCSTATUS_DA); + tmp |= TCSTATUS_IXMT; /* interrupt exempt */ + write_tc_c0_tcstatus(tmp); + + write_tc_c0_tchalt(TCHALT_H); +} + /* * Common setup before any secondaries are started * Make sure all CPU's are in a sensible state before we boot any of the * secondarys */ -void plat_smp_setup(void) +void __init plat_smp_setup(void) { - unsigned long val; - int i, num; + unsigned int mvpconf0, ntc, tc, ncpu = 0; #ifdef CONFIG_MIPS_MT_FPAFF /* If we have an FPU, enroll ourselves in the FPU-full mask */ @@ -167,75 +240,16 @@ void plat_smp_setup(void) /* Put MVPE's into 'configuration state' */ set_c0_mvpcontrol(MVPCONTROL_VPC); - val = read_c0_mvpconf0(); + mvpconf0 = read_c0_mvpconf0(); + ntc = (mvpconf0 & MVPCONF0_PTC) >> MVPCONF0_PTC_SHIFT; /* we'll always have more TC's than VPE's, so loop setting everything to a sensible state */ - for (i = 0, num = 0; i <= ((val & MVPCONF0_PTC) >> MVPCONF0_PTC_SHIFT); i++) { - settc(i); - - /* VPE's */ - if (i <= ((val & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT)) { - - /* deactivate all but vpe0 */ - if (i != 0) { - unsigned long tmp = read_vpe_c0_vpeconf0(); - - tmp &= ~VPECONF0_VPA; - - /* master VPE */ - tmp |= VPECONF0_MVP; - write_vpe_c0_vpeconf0(tmp); - - /* Record this as available CPU */ - cpu_set(i, phys_cpu_present_map); - __cpu_number_map[i] = ++num; - __cpu_logical_map[num] = i; - } - - /* disable multi-threading with TC's */ - write_vpe_c0_vpecontrol(read_vpe_c0_vpecontrol() & ~VPECONTROL_TE); - - if (i != 0) { - write_vpe_c0_status((read_c0_status() & ~(ST0_IM | ST0_IE | ST0_KSU)) | ST0_CU0); + for (tc = 0; tc <= ntc; tc++) { + settc(tc); - /* set config to be the same as vpe0, particularly kseg0 coherency alg */ - write_vpe_c0_config( read_c0_config()); - - /* make sure there are no software interrupts pending */ - write_vpe_c0_cause(0); - - /* Propagate Config7 */ - write_vpe_c0_config7(read_c0_config7()); - } - - } - - /* TC's */ - - if (i != 0) { - unsigned long tmp; - - /* bind a TC to each VPE, May as well put all excess TC's - on the last VPE */ - if ( i >= (((val & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT)+1) ) - write_tc_c0_tcbind(read_tc_c0_tcbind() | ((val & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT) ); - else { - write_tc_c0_tcbind( read_tc_c0_tcbind() | i); - - /* and set XTC */ - write_vpe_c0_vpeconf0( read_vpe_c0_vpeconf0() | (i << VPECONF0_XTC_SHIFT)); - } - - tmp = read_tc_c0_tcstatus(); - - /* mark not allocated and not dynamically allocatable */ - tmp &= ~(TCSTATUS_A | TCSTATUS_DA); - tmp |= TCSTATUS_IXMT; /* interrupt exempt */ - write_tc_c0_tcstatus(tmp); - - write_tc_c0_tchalt(TCHALT_H); - } + smp_tc_init(tc, mvpconf0); + ncpu = smp_vpe_init(tc, mvpconf0, ncpu); } /* Release config state */ @@ -243,7 +257,7 @@ void plat_smp_setup(void) /* We'll wait until starting the secondaries before starting MVPE */ - printk(KERN_INFO "Detected %i available secondary CPU(s)\n", num); + printk(KERN_INFO "Detected %i available secondary CPU(s)\n", ncpu); } void __init plat_prepare_cpus(unsigned int max_cpus) -- cgit v1.2.3 From 70e46f48cb5933119712ee27945309a4bfc98282 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Tue, 31 Oct 2006 18:33:09 +0000 Subject: [MIPS] VSMP: Synchronize cp0 counters on bootup. Signed-off-by: Ralf Baechle --- arch/mips/kernel/smp-mt.c | 2 ++ arch/mips/mips-boards/generic/time.c | 5 +++-- include/asm-mips/mipsmtregs.h | 2 ++ 3 files changed, 7 insertions(+), 2 deletions(-) (limited to 'arch/mips/kernel') diff --git a/arch/mips/kernel/smp-mt.c b/arch/mips/kernel/smp-mt.c index 06b29fa73f56..2ac19a6cbf68 100644 --- a/arch/mips/kernel/smp-mt.c +++ b/arch/mips/kernel/smp-mt.c @@ -153,6 +153,8 @@ static void __init smp_copy_vpe_config(void) /* Propagate Config7 */ write_vpe_c0_config7(read_c0_config7()); + + write_vpe_c0_count(read_c0_count()); } static unsigned int __init smp_vpe_init(unsigned int tc, unsigned int mvpconf0, diff --git a/arch/mips/mips-boards/generic/time.c b/arch/mips/mips-boards/generic/time.c index 659706705005..d817c60c5ca5 100644 --- a/arch/mips/mips-boards/generic/time.c +++ b/arch/mips/mips-boards/generic/time.c @@ -209,6 +209,7 @@ static unsigned int __init estimate_cpu_frequency(void) #endif #if defined(CONFIG_MIPS_ATLAS) || defined(CONFIG_MIPS_MALTA) unsigned long flags; + unsigned int start; local_irq_save(flags); @@ -217,13 +218,13 @@ static unsigned int __init estimate_cpu_frequency(void) while (!(CMOS_READ(RTC_REG_A) & RTC_UIP)); /* Start r4k counter. */ - write_c0_count(0); + start = read_c0_count(); /* Read counter exactly on falling edge of update flag */ while (CMOS_READ(RTC_REG_A) & RTC_UIP); while (!(CMOS_READ(RTC_REG_A) & RTC_UIP)); - count = read_c0_count(); + count = read_c0_count() - start; /* restore interrupts */ local_irq_restore(flags); diff --git a/include/asm-mips/mipsmtregs.h b/include/asm-mips/mipsmtregs.h index f637ce70758f..3e9468f424f4 100644 --- a/include/asm-mips/mipsmtregs.h +++ b/include/asm-mips/mipsmtregs.h @@ -352,6 +352,8 @@ do { \ #define write_vpe_c0_vpecontrol(val) mttc0(1, 1, val) #define read_vpe_c0_vpeconf0() mftc0(1, 2) #define write_vpe_c0_vpeconf0(val) mttc0(1, 2, val) +#define read_vpe_c0_count() mftc0(9, 0) +#define write_vpe_c0_count(val) mttc0(9, 0, val) #define read_vpe_c0_status() mftc0(12, 0) #define write_vpe_c0_status(val) mttc0(12, 0, val) #define read_vpe_c0_cause() mftc0(13, 0) -- cgit v1.2.3 From 16b7b2ac0148e839da86af8747b6fa4aad43a9b7 Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Tue, 24 Oct 2006 00:21:27 +0900 Subject: [MIPS] Fixup migration to GENERIC_TIME Since we already moved to GENERIC_TIME, we should implement alternatives of old do_gettimeoffset routines to get sub-jiffies resolution from gettimeofday(). This patch includes: * MIPS clocksource support (based on works by Manish Lachwani). * remove unused gettimeoffset routines and related codes. * remove unised 64bit do_div64_32(). * simplify mips_hpt_init. (no argument needed, __init tag) * simplify c0_hpt_timer_init. (no need to write to c0_count) * remove some hpt_init routines. * mips_hpt_mask variable to specify bitmask of hpt value. * convert jmr3927_do_gettimeoffset to jmr3927_hpt_read. * convert ip27_do_gettimeoffset to ip27_hpt_read. * convert bcm1480_do_gettimeoffset to bcm1480_hpt_read. * simplify sb1250 hpt functions. (no need to subtract and shift) Signed-off-by: Atsushi Nemoto Signed-off-by: Ralf Baechle --- Documentation/mips/time.README | 39 +--- arch/mips/au1000/common/time.c | 98 ---------- arch/mips/dec/time.c | 9 +- arch/mips/jmr3927/rbhma3100/setup.c | 40 +--- arch/mips/kernel/time.c | 319 ++++++-------------------------- arch/mips/philips/pnx8550/common/time.c | 4 +- arch/mips/pmc-sierra/yosemite/smp.c | 6 +- arch/mips/sgi-ip27/ip27-timer.c | 16 +- arch/mips/sibyte/bcm1480/time.c | 33 ++-- arch/mips/sibyte/sb1250/time.c | 28 +-- include/asm-mips/div64.h | 21 --- include/asm-mips/sibyte/sb1250.h | 2 +- include/asm-mips/time.h | 10 +- 13 files changed, 103 insertions(+), 522 deletions(-) (limited to 'arch/mips/kernel') diff --git a/Documentation/mips/time.README b/Documentation/mips/time.README index e1304b6bc483..a4ce603ed3b3 100644 --- a/Documentation/mips/time.README +++ b/Documentation/mips/time.README @@ -38,19 +38,14 @@ The new time code provide the following services: a) Implements functions required by Linux common code: time_init - do_gettimeofday - do_settimeofday b) provides an abstraction of RTC and null RTC implementation as default. extern unsigned long (*rtc_get_time)(void); extern int (*rtc_set_time)(unsigned long); - c) a set of gettimeoffset functions for different CPUs and different - needs. - - d) high-level and low-level timer interrupt routines where the timer - interrupt source may or may not be the CPU timer. The high-level - routine is dispatched through do_IRQ() while the low-level is + c) high-level and low-level timer interrupt routines where the timer + interrupt source may or may not be the CPU timer. The high-level + routine is dispatched through do_IRQ() while the low-level is dispatched in assemably code (usually int-handler.S) @@ -73,8 +68,7 @@ the following functions or values: c) (optional) board-specific RTC routines. d) (optional) mips_hpt_frequency - It must be definied if the board - is using CPU counter for timer interrupt or it is using fixed rate - gettimeoffset(). + is using CPU counter for timer interrupt. PORTING GUIDE @@ -89,16 +83,6 @@ Step 1: decide how you like to implement the time services. If the answer is no, you need a timer to provide the timer interrupt at 100 HZ speed. - You cannot use the fast gettimeoffset functions, i.e., - - unsigned long fixed_rate_gettimeoffset(void); - unsigned long calibrate_div32_gettimeoffset(void); - unsigned long calibrate_div64_gettimeoffset(void); - - You can use null_gettimeoffset() will gives the same time resolution as - jiffy. Or you can implement your own gettimeoffset (probably based on - some ad hoc hardware on your machine.) - c) The following sub steps assume your CPU has counter register. Do you plan to use the CPU counter register as the timer interrupt or use an exnternal timer? @@ -123,8 +107,8 @@ Step 3: implement rtc routines, board_time_init() and plat_timer_setup() board_time_init() - a) (optional) set up RTC routines, b) (optional) calibrate and set the mips_hpt_frequency - (only needed if you intended to use fixed_rate_gettimeoffset - or use cpu counter as timer interrupt source) + (only needed if you intended to use cpu counter as timer interrupt + source) plat_timer_setup() - a) (optional) over-write any choices made above by time_init(). @@ -154,8 +138,8 @@ for some of the functions in time.c. For example, you may define your own timer interrupt routine, which does some of its own processing and then calls timer_interrupt(). -You can also over-ride any of the built-in functions (gettimeoffset, -RTC routines and/or timer interrupt routine). +You can also over-ride any of the built-in functions (RTC routines +and/or timer interrupt routine). PORTING NOTES FOR SMP @@ -187,10 +171,3 @@ You need to decide on your timer interrupt sources. You can also do the low-level version of those interrupt routines, following similar dispatching routes described above. - -Note about do_gettimeoffset(): - - It is very likely the CPU counter registers are not sync'ed up in a SMP box. - Therefore you cannot really use the many of the existing routines that - are based on CPU counter. You should wirte your own gettimeoffset rouinte - if you want intra-jiffy resolution. diff --git a/arch/mips/au1000/common/time.c b/arch/mips/au1000/common/time.c index 6768638883ea..fa1c62f05515 100644 --- a/arch/mips/au1000/common/time.c +++ b/arch/mips/au1000/common/time.c @@ -53,9 +53,6 @@ static unsigned long r4k_cur; /* What counter should be at next timer irq */ int no_au1xxx_32khz; extern int allow_au1k_wait; /* default off for CP0 Counter */ -/* Cycle counter value at the previous timer interrupt.. */ -static unsigned int timerhi = 0, timerlo = 0; - #ifdef CONFIG_PM #if HZ < 100 || HZ > 1000 #error "unsupported HZ value! Must be in [100,1000]" @@ -90,10 +87,6 @@ void mips_timer_interrupt(void) goto null; do { - count = read_c0_count(); - timerhi += (count < timerlo); /* Wrap around */ - timerlo = count; - kstat_this_cpu.irqs[irq]++; do_timer(1); #ifndef CONFIG_SMP @@ -297,88 +290,6 @@ unsigned long cal_r4koff(void) return (cpu_speed / HZ); } -/* This is for machines which generate the exact clock. */ -#define USECS_PER_JIFFY (1000000/HZ) -#define USECS_PER_JIFFY_FRAC (0x100000000LL*1000000/HZ&0xffffffff) - -static unsigned long -div64_32(unsigned long v1, unsigned long v2, unsigned long v3) -{ - unsigned long r0; - do_div64_32(r0, v1, v2, v3); - return r0; -} - -static unsigned long do_fast_cp0_gettimeoffset(void) -{ - u32 count; - unsigned long res, tmp; - unsigned long r0; - - /* Last jiffy when do_fast_gettimeoffset() was called. */ - static unsigned long last_jiffies=0; - unsigned long quotient; - - /* - * Cached "1/(clocks per usec)*2^32" value. - * It has to be recalculated once each jiffy. - */ - static unsigned long cached_quotient=0; - - tmp = jiffies; - - quotient = cached_quotient; - - if (tmp && last_jiffies != tmp) { - last_jiffies = tmp; - if (last_jiffies != 0) { - r0 = div64_32(timerhi, timerlo, tmp); - quotient = div64_32(USECS_PER_JIFFY, USECS_PER_JIFFY_FRAC, r0); - cached_quotient = quotient; - } - } - - /* Get last timer tick in absolute kernel time */ - count = read_c0_count(); - - /* .. relative to previous jiffy (32 bits is enough) */ - count -= timerlo; - - __asm__("multu\t%1,%2\n\t" - "mfhi\t%0" - : "=r" (res) - : "r" (count), "r" (quotient) - : "hi", "lo", GCC_REG_ACCUM); - - /* - * Due to possible jiffies inconsistencies, we need to check - * the result so that we'll get a timer that is monotonic. - */ - if (res >= USECS_PER_JIFFY) - res = USECS_PER_JIFFY-1; - - return res; -} - -#ifdef CONFIG_PM -static unsigned long do_fast_pm_gettimeoffset(void) -{ - unsigned long pc0; - unsigned long offset; - - pc0 = au_readl(SYS_TOYREAD); - au_sync(); - offset = pc0 - last_pc0; - if (offset > 2*MATCH20_INC) { - printk("huge offset %x, last_pc0 %x last_match20 %x pc0 %x\n", - (unsigned)offset, (unsigned)last_pc0, - (unsigned)last_match20, (unsigned)pc0); - } - offset = (unsigned long)((offset * 305) / 10); - return offset; -} -#endif - void __init plat_timer_setup(struct irqaction *irq) { unsigned int est_freq; @@ -416,7 +327,6 @@ void __init plat_timer_setup(struct irqaction *irq) unsigned int c0_status; printk("WARNING: no 32KHz clock found.\n"); - do_gettimeoffset = do_fast_cp0_gettimeoffset; /* Ensure we get CPO_COUNTER interrupts. */ @@ -441,19 +351,11 @@ void __init plat_timer_setup(struct irqaction *irq) while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20); startup_match20_interrupt(counter0_irq); - do_gettimeoffset = do_fast_pm_gettimeoffset; - /* We can use the real 'wait' instruction. */ allow_au1k_wait = 1; } -#else - /* We have to do this here instead of in timer_init because - * the generic code in arch/mips/kernel/time.c will write - * over our function pointer. - */ - do_gettimeoffset = do_fast_cp0_gettimeoffset; #endif } diff --git a/arch/mips/dec/time.c b/arch/mips/dec/time.c index 4cf0c06e2414..69e424e9ab6f 100644 --- a/arch/mips/dec/time.c +++ b/arch/mips/dec/time.c @@ -160,11 +160,6 @@ static unsigned int dec_ioasic_hpt_read(void) return ioasic_read(IO_REG_FCTR); } -static void dec_ioasic_hpt_init(unsigned int count) -{ - ioasic_write(IO_REG_FCTR, ioasic_read(IO_REG_FCTR) - count); -} - void __init dec_time_init(void) { @@ -174,11 +169,9 @@ void __init dec_time_init(void) mips_timer_state = dec_timer_state; mips_timer_ack = dec_timer_ack; - if (!cpu_has_counter && IOASIC) { + if (!cpu_has_counter && IOASIC) /* For pre-R4k systems we use the I/O ASIC's counter. */ mips_hpt_read = dec_ioasic_hpt_read; - mips_hpt_init = dec_ioasic_hpt_init; - } /* Set up the rate of periodic DS1287 interrupts. */ CMOS_WRITE(RTC_REF_CLCK_32KHZ | (16 - __ffs(HZ)), RTC_REG_A); diff --git a/arch/mips/jmr3927/rbhma3100/setup.c b/arch/mips/jmr3927/rbhma3100/setup.c index 025434054ed0..16e5dfe7aa8a 100644 --- a/arch/mips/jmr3927/rbhma3100/setup.c +++ b/arch/mips/jmr3927/rbhma3100/setup.c @@ -170,12 +170,20 @@ static void jmr3927_machine_power_off(void) while (1); } +static unsigned int jmr3927_hpt_read(void) +{ + /* We assume this function is called xtime_lock held. */ + return jiffies * (JMR3927_TIMER_CLK / HZ) + jmr3927_tmrptr->trr; +} + #define USE_RTC_DS1742 #ifdef USE_RTC_DS1742 extern void rtc_ds1742_init(unsigned long base); #endif static void __init jmr3927_time_init(void) { + mips_hpt_read = jmr3927_hpt_read; + mips_hpt_frequency = JMR3927_TIMER_CLK; #ifdef USE_RTC_DS1742 if (jmr3927_have_nvram()) { rtc_ds1742_init(JMR3927_IOC_NVRAMB_ADDR); @@ -183,12 +191,8 @@ static void __init jmr3927_time_init(void) #endif } -unsigned long jmr3927_do_gettimeoffset(void); - void __init plat_timer_setup(struct irqaction *irq) { - do_gettimeoffset = jmr3927_do_gettimeoffset; - jmr3927_tmrptr->cpra = JMR3927_TIMER_CLK / HZ; jmr3927_tmrptr->itmr = TXx927_TMTITMR_TIIE | TXx927_TMTITMR_TZCE; jmr3927_tmrptr->ccdr = JMR3927_TIMER_CCD; @@ -200,34 +204,6 @@ void __init plat_timer_setup(struct irqaction *irq) #define USECS_PER_JIFFY (1000000/HZ) -unsigned long jmr3927_do_gettimeoffset(void) -{ - unsigned long count; - unsigned long res = 0; - - /* MUST read TRR before TISR. */ - count = jmr3927_tmrptr->trr; - - if (jmr3927_tmrptr->tisr & TXx927_TMTISR_TIIS) { - /* timer interrupt is pending. use Max value. */ - res = USECS_PER_JIFFY - 1; - } else { - /* convert to usec */ - /* res = count / (JMR3927_TIMER_CLK / 1000000); */ - res = (count << 7) / ((JMR3927_TIMER_CLK << 7) / 1000000); - - /* - * Due to possible jiffies inconsistencies, we need to check - * the result so that we'll get a timer that is monotonic. - */ - if (res >= USECS_PER_JIFFY) - res = USECS_PER_JIFFY-1; - } - - return res; -} - - //#undef DO_WRITE_THROUGH #define DO_WRITE_THROUGH #define DO_ENABLE_CACHE diff --git a/arch/mips/kernel/time.c b/arch/mips/kernel/time.c index debe86c2f691..e535f86efa2f 100644 --- a/arch/mips/kernel/time.c +++ b/arch/mips/kernel/time.c @@ -11,6 +11,7 @@ * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. */ +#include #include #include #include @@ -67,15 +68,9 @@ int (*rtc_mips_set_time)(unsigned long) = null_rtc_set_time; int (*rtc_mips_set_mmss)(unsigned long); -/* usecs per counter cycle, shifted to left by 32 bits */ -static unsigned int sll32_usecs_per_cycle; - /* how many counter cycles in a jiffy */ static unsigned long cycles_per_jiffy __read_mostly; -/* Cycle counter value at the previous timer interrupt.. */ -static unsigned int timerhi, timerlo; - /* expirelo is the count value for next CPU timer interrupt */ static unsigned int expirelo; @@ -93,7 +88,7 @@ static unsigned int null_hpt_read(void) return 0; } -static void null_hpt_init(unsigned int count) +static void __init null_hpt_init(void) { /* nothing */ } @@ -128,186 +123,18 @@ static unsigned int c0_hpt_read(void) return read_c0_count(); } -/* For use solely as a high precision timer. */ -static void c0_hpt_init(unsigned int count) -{ - write_c0_count(read_c0_count() - count); -} - /* For use both as a high precision timer and an interrupt source. */ -static void c0_hpt_timer_init(unsigned int count) +static void __init c0_hpt_timer_init(void) { - count = read_c0_count() - count; - expirelo = (count / cycles_per_jiffy + 1) * cycles_per_jiffy; - write_c0_count(expirelo - cycles_per_jiffy); + expirelo = read_c0_count() + cycles_per_jiffy; write_c0_compare(expirelo); - write_c0_count(count); } int (*mips_timer_state)(void); void (*mips_timer_ack)(void); unsigned int (*mips_hpt_read)(void); -void (*mips_hpt_init)(unsigned int); - -/* - * Gettimeoffset routines. These routines returns the time duration - * since last timer interrupt in usecs. - * - * If the exact CPU counter frequency is known, use fixed_rate_gettimeoffset. - * Otherwise use calibrate_gettimeoffset() - * - * If the CPU does not have the counter register, you can either supply - * your own gettimeoffset() routine, or use null_gettimeoffset(), which - * gives the same resolution as HZ. - */ - -static unsigned long null_gettimeoffset(void) -{ - return 0; -} - - -/* The function pointer to one of the gettimeoffset funcs. */ -unsigned long (*do_gettimeoffset)(void) = null_gettimeoffset; - - -static unsigned long fixed_rate_gettimeoffset(void) -{ - u32 count; - unsigned long res; - - /* Get last timer tick in absolute kernel time */ - count = mips_hpt_read(); - - /* .. relative to previous jiffy (32 bits is enough) */ - count -= timerlo; - - __asm__("multu %1,%2" - : "=h" (res) - : "r" (count), "r" (sll32_usecs_per_cycle) - : "lo", GCC_REG_ACCUM); - - /* - * Due to possible jiffies inconsistencies, we need to check - * the result so that we'll get a timer that is monotonic. - */ - if (res >= USECS_PER_JIFFY) - res = USECS_PER_JIFFY - 1; - - return res; -} - - -/* - * Cached "1/(clocks per usec) * 2^32" value. - * It has to be recalculated once each jiffy. - */ -static unsigned long cached_quotient; - -/* Last jiffy when calibrate_divXX_gettimeoffset() was called. */ -static unsigned long last_jiffies; - -/* - * This is moved from dec/time.c:do_ioasic_gettimeoffset() by Maciej. - */ -static unsigned long calibrate_div32_gettimeoffset(void) -{ - u32 count; - unsigned long res, tmp; - unsigned long quotient; - - tmp = jiffies; - - quotient = cached_quotient; - - if (last_jiffies != tmp) { - last_jiffies = tmp; - if (last_jiffies != 0) { - unsigned long r0; - do_div64_32(r0, timerhi, timerlo, tmp); - do_div64_32(quotient, USECS_PER_JIFFY, - USECS_PER_JIFFY_FRAC, r0); - cached_quotient = quotient; - } - } - - /* Get last timer tick in absolute kernel time */ - count = mips_hpt_read(); - - /* .. relative to previous jiffy (32 bits is enough) */ - count -= timerlo; - - __asm__("multu %1,%2" - : "=h" (res) - : "r" (count), "r" (quotient) - : "lo", GCC_REG_ACCUM); - - /* - * Due to possible jiffies inconsistencies, we need to check - * the result so that we'll get a timer that is monotonic. - */ - if (res >= USECS_PER_JIFFY) - res = USECS_PER_JIFFY - 1; - - return res; -} - -static unsigned long calibrate_div64_gettimeoffset(void) -{ - u32 count; - unsigned long res, tmp; - unsigned long quotient; - - tmp = jiffies; - - quotient = cached_quotient; - - if (last_jiffies != tmp) { - last_jiffies = tmp; - if (last_jiffies) { - unsigned long r0; - __asm__(".set push\n\t" - ".set mips3\n\t" - "lwu %0,%3\n\t" - "dsll32 %1,%2,0\n\t" - "or %1,%1,%0\n\t" - "ddivu $0,%1,%4\n\t" - "mflo %1\n\t" - "dsll32 %0,%5,0\n\t" - "or %0,%0,%6\n\t" - "ddivu $0,%0,%1\n\t" - "mflo %0\n\t" - ".set pop" - : "=&r" (quotient), "=&r" (r0) - : "r" (timerhi), "m" (timerlo), - "r" (tmp), "r" (USECS_PER_JIFFY), - "r" (USECS_PER_JIFFY_FRAC) - : "hi", "lo", GCC_REG_ACCUM); - cached_quotient = quotient; - } - } - - /* Get last timer tick in absolute kernel time */ - count = mips_hpt_read(); - - /* .. relative to previous jiffy (32 bits is enough) */ - count -= timerlo; - - __asm__("multu %1,%2" - : "=h" (res) - : "r" (count), "r" (quotient) - : "lo", GCC_REG_ACCUM); - - /* - * Due to possible jiffies inconsistencies, we need to check - * the result so that we'll get a timer that is monotonic. - */ - if (res >= USECS_PER_JIFFY) - res = USECS_PER_JIFFY - 1; - - return res; -} - +void (*mips_hpt_init)(void) __initdata = null_hpt_init; +unsigned int mips_hpt_mask = 0xffffffff; /* last time when xtime and rtc are sync'ed up */ static long last_rtc_update; @@ -334,18 +161,10 @@ void local_timer_interrupt(int irq, void *dev_id) */ irqreturn_t timer_interrupt(int irq, void *dev_id) { - unsigned long j; - unsigned int count; - write_seqlock(&xtime_lock); - count = mips_hpt_read(); mips_timer_ack(); - /* Update timerhi/timerlo for intra-jiffy calibration. */ - timerhi += count < timerlo; /* Wrap around */ - timerlo = count; - /* * call the generic timer interrupt handling */ @@ -368,47 +187,6 @@ irqreturn_t timer_interrupt(int irq, void *dev_id) } } - /* - * If jiffies has overflown in this timer_interrupt, we must - * update the timer[hi]/[lo] to make fast gettimeoffset funcs - * quotient calc still valid. -arca - * - * The first timer interrupt comes late as interrupts are - * enabled long after timers are initialized. Therefore the - * high precision timer is fast, leading to wrong gettimeoffset() - * calculations. We deal with it by setting it based on the - * number of its ticks between the second and the third interrupt. - * That is still somewhat imprecise, but it's a good estimate. - * --macro - */ - j = jiffies; - if (j < 4) { - static unsigned int prev_count; - static int hpt_initialized; - - switch (j) { - case 0: - timerhi = timerlo = 0; - mips_hpt_init(count); - break; - case 2: - prev_count = count; - break; - case 3: - if (!hpt_initialized) { - unsigned int c3 = 3 * (count - prev_count); - - timerhi = 0; - timerlo = c3; - mips_hpt_init(count - c3); - hpt_initialized = 1; - } - break; - default: - break; - } - } - write_sequnlock(&xtime_lock); /* @@ -476,12 +254,11 @@ asmlinkage void ll_local_timer_interrupt(int irq) * 1) board_time_init() - * a) (optional) set up RTC routines, * b) (optional) calibrate and set the mips_hpt_frequency - * (only needed if you intended to use fixed_rate_gettimeoffset - * or use cpu counter as timer interrupt source) + * (only needed if you intended to use cpu counter as timer interrupt + * source) * 2) setup xtime based on rtc_mips_get_time(). - * 3) choose a appropriate gettimeoffset routine. - * 4) calculate a couple of cached variables for later usage - * 5) plat_timer_setup() - + * 3) calculate a couple of cached variables for later usage + * 4) plat_timer_setup() - * a) (optional) over-write any choices made above by time_init(). * b) machine specific code should setup the timer irqaction. * c) enable the timer interrupt @@ -533,13 +310,48 @@ static unsigned int __init calibrate_hpt(void) } while (--i); hpt_end = mips_hpt_read(); - hpt_count = hpt_end - hpt_start; + hpt_count = (hpt_end - hpt_start) & mips_hpt_mask; hz = HZ; frequency = (u64)hpt_count * (u64)hz; return frequency >> log_2_loops; } +static cycle_t read_mips_hpt(void) +{ + return (cycle_t)mips_hpt_read(); +} + +static struct clocksource clocksource_mips = { + .name = "MIPS", + .read = read_mips_hpt, + .is_continuous = 1, +}; + +static void __init init_mips_clocksource(void) +{ + u64 temp; + u32 shift; + + if (!mips_hpt_frequency || mips_hpt_read == null_hpt_read) + return; + + /* Calclate a somewhat reasonable rating value */ + clocksource_mips.rating = 200 + mips_hpt_frequency / 10000000; + /* Find a shift value */ + for (shift = 32; shift > 0; shift--) { + temp = (u64) NSEC_PER_SEC << shift; + do_div(temp, mips_hpt_frequency); + if ((temp >> 32) == 0) + break; + } + clocksource_mips.shift = shift; + clocksource_mips.mult = (u32)temp; + clocksource_mips.mask = mips_hpt_mask; + + clocksource_register(&clocksource_mips); +} + void __init time_init(void) { if (board_time_init) @@ -555,41 +367,21 @@ void __init time_init(void) -xtime.tv_sec, -xtime.tv_nsec); /* Choose appropriate high precision timer routines. */ - if (!cpu_has_counter && !mips_hpt_read) { + if (!cpu_has_counter && !mips_hpt_read) /* No high precision timer -- sorry. */ mips_hpt_read = null_hpt_read; - mips_hpt_init = null_hpt_init; - } else if (!mips_hpt_frequency && !mips_timer_state) { + else if (!mips_hpt_frequency && !mips_timer_state) { /* A high precision timer of unknown frequency. */ - if (!mips_hpt_read) { + if (!mips_hpt_read) /* No external high precision timer -- use R4k. */ mips_hpt_read = c0_hpt_read; - mips_hpt_init = c0_hpt_init; - } - - if (cpu_has_mips32r1 || cpu_has_mips32r2 || - (current_cpu_data.isa_level == MIPS_CPU_ISA_I) || - (current_cpu_data.isa_level == MIPS_CPU_ISA_II)) - /* - * We need to calibrate the counter but we don't have - * 64-bit division. - */ - do_gettimeoffset = calibrate_div32_gettimeoffset; - else - /* - * We need to calibrate the counter but we *do* have - * 64-bit division. - */ - do_gettimeoffset = calibrate_div64_gettimeoffset; } else { /* We know counter frequency. Or we can get it. */ if (!mips_hpt_read) { /* No external high precision timer -- use R4k. */ mips_hpt_read = c0_hpt_read; - if (mips_timer_state) - mips_hpt_init = c0_hpt_init; - else { + if (!mips_timer_state) { /* No external timer interrupt -- use R4k. */ mips_hpt_init = c0_hpt_timer_init; mips_timer_ack = c0_timer_ack; @@ -598,16 +390,9 @@ void __init time_init(void) if (!mips_hpt_frequency) mips_hpt_frequency = calibrate_hpt(); - do_gettimeoffset = fixed_rate_gettimeoffset; - /* Calculate cache parameters. */ cycles_per_jiffy = (mips_hpt_frequency + HZ / 2) / HZ; - /* sll32_usecs_per_cycle = 10^6 * 2^32 / mips_counter_freq */ - do_div64_32(sll32_usecs_per_cycle, - 1000000, mips_hpt_frequency / 2, - mips_hpt_frequency); - /* Report the high precision timer rate for a reference. */ printk("Using %u.%03u MHz high precision timer.\n", ((mips_hpt_frequency + 500) / 1000) / 1000, @@ -619,7 +404,7 @@ void __init time_init(void) mips_timer_ack = null_timer_ack; /* This sets up the high precision timer for the first interrupt. */ - mips_hpt_init(mips_hpt_read()); + mips_hpt_init(); /* * Call board specific timer interrupt setup. @@ -633,6 +418,8 @@ void __init time_init(void) * is not invoked accidentally. */ plat_timer_setup(&timer_irqaction); + + init_mips_clocksource(); } #define FEBRUARY 2 diff --git a/arch/mips/philips/pnx8550/common/time.c b/arch/mips/philips/pnx8550/common/time.c index 0af655b1f330..65c440e8480b 100644 --- a/arch/mips/philips/pnx8550/common/time.c +++ b/arch/mips/philips/pnx8550/common/time.c @@ -41,8 +41,8 @@ extern unsigned int mips_hpt_frequency; * 1) board_time_init() - * a) (optional) set up RTC routines, * b) (optional) calibrate and set the mips_hpt_frequency - * (only needed if you intended to use fixed_rate_gettimeoffset - * or use cpu counter as timer interrupt source) + * (only needed if you intended to use cpu counter as timer interrupt + * source) */ void pnx8550_time_init(void) diff --git a/arch/mips/pmc-sierra/yosemite/smp.c b/arch/mips/pmc-sierra/yosemite/smp.c index 65fa3a23ea5e..3cc0436db6cf 100644 --- a/arch/mips/pmc-sierra/yosemite/smp.c +++ b/arch/mips/pmc-sierra/yosemite/smp.c @@ -3,9 +3,7 @@ #include #include - -extern unsigned int (*mips_hpt_read)(void); -extern void (*mips_hpt_init)(unsigned int); +#include #define LAUNCHSTACK_SIZE 256 @@ -101,7 +99,7 @@ void prom_cpus_done(void) */ void prom_init_secondary(void) { - mips_hpt_init(mips_hpt_read()); + mips_hpt_init(); set_c0_status(ST0_CO | ST0_IE | ST0_IM); } diff --git a/arch/mips/sgi-ip27/ip27-timer.c b/arch/mips/sgi-ip27/ip27-timer.c index 4e870fc4469b..c965705f3427 100644 --- a/arch/mips/sgi-ip27/ip27-timer.c +++ b/arch/mips/sgi-ip27/ip27-timer.c @@ -134,13 +134,6 @@ again: irq_exit(); } -unsigned long ip27_do_gettimeoffset(void) -{ - unsigned long ct_cur1; - ct_cur1 = REMOTE_HUB_L(cputonasid(0), PI_RT_COUNT) + CYCLES_PER_JIFFY; - return (ct_cur1 - ct_cur[0]) * NSEC_PER_CYCLE / 1000; -} - /* Includes for ioc3_init(). */ #include #include @@ -248,12 +241,17 @@ void __init plat_timer_setup(struct irqaction *irq) setup_irq(irqno, &rt_irqaction); } +static unsigned int ip27_hpt_read(void) +{ + return REMOTE_HUB_L(cputonasid(0), PI_RT_COUNT); +} + void __init ip27_time_init(void) { + mips_hpt_read = ip27_hpt_read; + mips_hpt_frequency = CYCLES_PER_SEC; xtime.tv_sec = get_m48t35_time(); xtime.tv_nsec = 0; - - do_gettimeoffset = ip27_do_gettimeoffset; } void __init cpu_time_init(void) diff --git a/arch/mips/sibyte/bcm1480/time.c b/arch/mips/sibyte/bcm1480/time.c index bf12af46132e..e136bde5248e 100644 --- a/arch/mips/sibyte/bcm1480/time.c +++ b/arch/mips/sibyte/bcm1480/time.c @@ -47,6 +47,12 @@ #define IMR_IP3_VAL K_BCM1480_INT_MAP_I1 #define IMR_IP4_VAL K_BCM1480_INT_MAP_I2 +#ifdef CONFIG_SIMULATION +#define BCM1480_HPT_VALUE 50000 +#else +#define BCM1480_HPT_VALUE 1000000 +#endif + extern int bcm1480_steal_irq(int irq); void bcm1480_time_init(void) @@ -59,11 +65,6 @@ void bcm1480_time_init(void) BUG(); } - if (!cpu) { - /* Use our own gettimeoffset() routine */ - do_gettimeoffset = bcm1480_gettimeoffset; - } - bcm1480_mask_irq(cpu, irq); /* Map the timer interrupt to ip[4] of this cpu */ @@ -74,11 +75,7 @@ void bcm1480_time_init(void) /* Disable the timer and set up the count */ __raw_writeq(0, IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG))); __raw_writeq( -#ifndef CONFIG_SIMULATION - 1000000/HZ -#else - 50000/HZ -#endif + BCM1480_HPT_VALUE/HZ , IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_INIT))); /* Set the timer running */ @@ -122,16 +119,16 @@ void bcm1480_timer_interrupt(void) } } -/* - * We use our own do_gettimeoffset() instead of the generic one, - * because the generic one does not work for SMP case. - * In addition, since we use general timer 0 for system time, - * we can get accurate intra-jiffy offset without calibration. - */ -unsigned long bcm1480_gettimeoffset(void) +static unsigned int bcm1480_hpt_read(void) { + /* We assume this function is called xtime_lock held. */ unsigned long count = __raw_readq(IOADDR(A_SCD_TIMER_REGISTER(0, R_SCD_TIMER_CNT))); + return (jiffies + 1) * (BCM1480_HPT_VALUE / HZ) - count; +} - return 1000000/HZ - count; +void __init bcm1480_hpt_setup(void) +{ + mips_hpt_read = bcm1480_hpt_read; + mips_hpt_frequency = BCM1480_HPT_VALUE; } diff --git a/arch/mips/sibyte/sb1250/time.c b/arch/mips/sibyte/sb1250/time.c index 0ccf1796dd78..bcb74f2c1948 100644 --- a/arch/mips/sibyte/sb1250/time.c +++ b/arch/mips/sibyte/sb1250/time.c @@ -47,15 +47,11 @@ #define SB1250_HPT_NUM 3 #define SB1250_HPT_VALUE M_SCD_TIMER_CNT /* max value */ -#define SB1250_HPT_SHIFT ((sizeof(unsigned int)*8)-V_SCD_TIMER_WIDTH) extern int sb1250_steal_irq(int irq); static unsigned int sb1250_hpt_read(void); -static void sb1250_hpt_init(unsigned int); - -static unsigned int hpt_offset; void __init sb1250_hpt_setup(void) { @@ -69,13 +65,9 @@ void __init sb1250_hpt_setup(void) __raw_writeq(M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS, IOADDR(A_SCD_TIMER_REGISTER(SB1250_HPT_NUM, R_SCD_TIMER_CFG))); - /* - * we need to fill 32 bits, so just use the upper 23 bits and pretend - * the timer is going 512Mhz instead of 1Mhz - */ - mips_hpt_frequency = V_SCD_TIMER_FREQ << SB1250_HPT_SHIFT; - mips_hpt_init = sb1250_hpt_init; + mips_hpt_frequency = V_SCD_TIMER_FREQ; mips_hpt_read = sb1250_hpt_read; + mips_hpt_mask = M_SCD_TIMER_INIT; } } @@ -149,11 +141,7 @@ void sb1250_timer_interrupt(void) /* * The HPT is free running from SB1250_HPT_VALUE down to 0 then starts over - * again. There's no easy way to set to a specific value so store init value - * in hpt_offset and subtract each time. - * - * Note: Timer isn't full 32bits so shift it into the upper part making - * it appear to run at a higher frequency. + * again. */ static unsigned int sb1250_hpt_read(void) { @@ -161,13 +149,5 @@ static unsigned int sb1250_hpt_read(void) count = G_SCD_TIMER_CNT(__raw_readq(IOADDR(A_SCD_TIMER_REGISTER(SB1250_HPT_NUM, R_SCD_TIMER_CNT)))); - count = (SB1250_HPT_VALUE - count) << SB1250_HPT_SHIFT; - - return count - hpt_offset; -} - -static void sb1250_hpt_init(unsigned int count) -{ - hpt_offset = count; - return; + return SB1250_HPT_VALUE - count; } diff --git a/include/asm-mips/div64.h b/include/asm-mips/div64.h index 5f7dcf5452e7..d107832de1b6 100644 --- a/include/asm-mips/div64.h +++ b/include/asm-mips/div64.h @@ -82,27 +82,6 @@ #if (_MIPS_SZLONG == 64) -/* - * Don't use this one in new code - */ -#define do_div64_32(res, high, low, base) ({ \ - unsigned int __quot, __mod; \ - unsigned long __div; \ - unsigned int __low, __high, __base; \ - \ - __high = (high); \ - __low = (low); \ - __div = __high; \ - __div = __div << 32 | __low; \ - __base = (base); \ - \ - __mod = __div % __base; \ - __div = __div / __base; \ - \ - __quot = __div; \ - (res) = __quot; \ - __mod; }) - /* * Hey, we're already 64-bit, no * need to play games.. diff --git a/include/asm-mips/sibyte/sb1250.h b/include/asm-mips/sibyte/sb1250.h index b09e16c93ca0..2ba6988ddc8e 100644 --- a/include/asm-mips/sibyte/sb1250.h +++ b/include/asm-mips/sibyte/sb1250.h @@ -51,8 +51,8 @@ extern void sb1250_mask_irq(int cpu, int irq); extern void sb1250_unmask_irq(int cpu, int irq); extern void sb1250_smp_finish(void); +extern void bcm1480_hpt_setup(void); extern void bcm1480_time_init(void); -extern unsigned long bcm1480_gettimeoffset(void); extern void bcm1480_mask_irq(int cpu, int irq); extern void bcm1480_unmask_irq(int cpu, int irq); extern void bcm1480_smp_finish(void); diff --git a/include/asm-mips/time.h b/include/asm-mips/time.h index 28512ba2266e..625acd337bc3 100644 --- a/include/asm-mips/time.h +++ b/include/asm-mips/time.h @@ -48,7 +48,8 @@ extern void (*mips_timer_ack)(void); * If mips_hpt_read is NULL, an R4k-compatible timer setup is attempted. */ extern unsigned int (*mips_hpt_read)(void); -extern void (*mips_hpt_init)(unsigned int); +extern void (*mips_hpt_init)(void); +extern unsigned int mips_hpt_mask; /* * to_tm() converts system time back to (year, mon, day, hour, min, sec). @@ -57,13 +58,6 @@ extern void (*mips_hpt_init)(unsigned int); */ extern void to_tm(unsigned long tim, struct rtc_time *tm); -/* - * do_gettimeoffset(). By default, this func pointer points to - * do_null_gettimeoffset(), which leads to the same resolution as HZ. - * Higher resolution versions are available, which give ~1us resolution. - */ -extern unsigned long (*do_gettimeoffset)(void); - /* * high-level timer interrupt routines. */ -- cgit v1.2.3 From 242954b5aa8e5ec84f46a84637daf08ee4247c6e Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Tue, 24 Oct 2006 02:29:01 +0100 Subject: [MIPS] 16K & 64K page size fixes Derived from Peter Watkins 's work. Signed-off-by: Ralf Baechle --- arch/mips/kernel/asm-offsets.c | 2 +- arch/mips/kernel/head.S | 3 ++- arch/mips/kernel/r4k_switch.S | 5 +++++ arch/mips/kernel/vmlinux.lds.S | 10 ++++++++++ arch/mips/lib-64/dump_tlb.c | 6 +++--- arch/mips/mips-boards/generic/memory.c | 2 +- arch/mips/mm/pg-r4k.c | 30 ++++++++++++++++++++++++++++-- arch/mips/mm/tlbex.c | 13 ++++++++++--- include/asm-mips/asm.h | 2 ++ include/asm-mips/pgalloc.h | 2 +- include/asm-mips/pgtable-64.h | 2 +- 11 files changed, 64 insertions(+), 13 deletions(-) (limited to 'arch/mips/kernel') diff --git a/arch/mips/kernel/asm-offsets.c b/arch/mips/kernel/asm-offsets.c index e9ce5b3721af..ff88b06f89df 100644 --- a/arch/mips/kernel/asm-offsets.c +++ b/arch/mips/kernel/asm-offsets.c @@ -22,7 +22,7 @@ #define offset(string, ptr, member) \ __asm__("\n@@@" string "%0" : : "i" (_offset(ptr, member))) #define constant(string, member) \ - __asm__("\n@@@" string "%x0" : : "ri" (member)) + __asm__("\n@@@" string "%X0" : : "ri" (member)) #define size(string, size) \ __asm__("\n@@@" string "%0" : : "i" (sizeof(size))) #define linefeed text("") diff --git a/arch/mips/kernel/head.S b/arch/mips/kernel/head.S index 8c6db0fc72f0..ddc1b71c9378 100644 --- a/arch/mips/kernel/head.S +++ b/arch/mips/kernel/head.S @@ -189,7 +189,8 @@ NESTED(kernel_entry, 16, sp) # kernel entry point MTC0 zero, CP0_CONTEXT # clear context register PTR_LA $28, init_thread_union - PTR_ADDIU sp, $28, _THREAD_SIZE - 32 + PTR_LI sp, _THREAD_SIZE - 32 + PTR_ADDU sp, $28 set_saved_sp sp, t0, t1 PTR_SUBU sp, 4 * SZREG # init stack pointer diff --git a/arch/mips/kernel/r4k_switch.S b/arch/mips/kernel/r4k_switch.S index d5c8b82fed72..cc566cf12246 100644 --- a/arch/mips/kernel/r4k_switch.S +++ b/arch/mips/kernel/r4k_switch.S @@ -85,7 +85,12 @@ move $28, a2 cpu_restore_nonscratch a1 +#if (_THREAD_SIZE - 32) < 0x10000 PTR_ADDIU t0, $28, _THREAD_SIZE - 32 +#else + PTR_LI t0, _THREAD_SIZE - 32 + PTR_ADDU t0, $28 +#endif set_saved_sp t0, t1, t2 #ifdef CONFIG_MIPS_MT_SMTC /* Read-modify-writes of Status must be atomic on a VPE */ diff --git a/arch/mips/kernel/vmlinux.lds.S b/arch/mips/kernel/vmlinux.lds.S index 25ed3337ce35..79f0317d84ac 100644 --- a/arch/mips/kernel/vmlinux.lds.S +++ b/arch/mips/kernel/vmlinux.lds.S @@ -50,6 +50,16 @@ SECTIONS /* writeable */ .data : { /* Data */ . = . + DATAOFFSET; /* for CONFIG_MAPPED_KERNEL */ + /* + * This ALIGN is needed as a workaround for a bug a gcc bug upto 4.1 which + * limits the maximum alignment to at most 32kB and results in the following + * warning: + * + * CC arch/mips/kernel/init_task.o + * arch/mips/kernel/init_task.c:30: warning: alignment of ‘init_thread_union’ + * is greater than maximum object file alignment. Using 32768 + */ + . = ALIGN(_PAGE_SIZE); *(.data.init_task) *(.data) diff --git a/arch/mips/lib-64/dump_tlb.c b/arch/mips/lib-64/dump_tlb.c index be8261be679b..594df1a05ecc 100644 --- a/arch/mips/lib-64/dump_tlb.c +++ b/arch/mips/lib-64/dump_tlb.c @@ -149,7 +149,7 @@ void dump_list_process(struct task_struct *t, void *address) printk("Addr == %08lx\n", addr); printk("tasks->mm.pgd == %08lx\n", (unsigned long) t->mm->pgd); - page_dir = pgd_offset(t->mm, 0); + page_dir = pgd_offset(t->mm, 0UL); printk("page_dir == %016lx\n", (unsigned long) page_dir); pgd = pgd_offset(t->mm, addr); @@ -184,13 +184,13 @@ void dump_list_current(void *address) dump_list_process(current, address); } -unsigned int vtop(void *address) +unsigned long vtop(void *address) { pgd_t *pgd; pud_t *pud; pmd_t *pmd; pte_t *pte; - unsigned int addr, paddr; + unsigned long addr, paddr; addr = (unsigned long) address; pgd = pgd_offset(current->mm, addr); diff --git a/arch/mips/mips-boards/generic/memory.c b/arch/mips/mips-boards/generic/memory.c index be80c5dd4a0c..eeed944e0f83 100644 --- a/arch/mips/mips-boards/generic/memory.c +++ b/arch/mips/mips-boards/generic/memory.c @@ -176,7 +176,7 @@ unsigned long __init prom_free_prom_memory(void) if (boot_mem_map.map[i].type != BOOT_MEM_ROM_DATA) continue; - addr = boot_mem_map.map[i].addr; + addr = PAGE_ALIGN(boot_mem_map.map[i].addr); while (addr < boot_mem_map.map[i].addr + boot_mem_map.map[i].size) { ClearPageReserved(virt_to_page(__va(addr))); diff --git a/arch/mips/mm/pg-r4k.c b/arch/mips/mm/pg-r4k.c index b7c749232ffe..d41fc5885e87 100644 --- a/arch/mips/mm/pg-r4k.c +++ b/arch/mips/mm/pg-r4k.c @@ -270,6 +270,20 @@ static inline void build_addiu_a2_a0(unsigned long offset) emit_instruction(mi); } +static inline void build_addiu_a2(unsigned long offset) +{ + union mips_instruction mi; + + BUG_ON(offset > 0x7fff); + + mi.i_format.opcode = cpu_has_64bit_gp_regs ? daddiu_op : addiu_op; + mi.i_format.rs = 6; /* $a2 */ + mi.i_format.rt = 6; /* $a2 */ + mi.i_format.simmediate = offset; + + emit_instruction(mi); +} + static inline void build_addiu_a1(unsigned long offset) { union mips_instruction mi; @@ -333,6 +347,7 @@ static inline void build_jr_ra(void) void __init build_clear_page(void) { unsigned int loop_start; + unsigned long off; epc = (unsigned int *) &clear_page_array; instruction_pending = 0; @@ -369,7 +384,12 @@ void __init build_clear_page(void) } } - build_addiu_a2_a0(PAGE_SIZE - (cpu_has_prefetch ? pref_offset_clear : 0)); + off = PAGE_SIZE - (cpu_has_prefetch ? pref_offset_clear : 0); + if (off > 0x7fff) { + build_addiu_a2_a0(off >> 1); + build_addiu_a2(off >> 1); + } else + build_addiu_a2_a0(off); if (R4600_V2_HIT_CACHEOP_WAR && cpu_is_r4600_v2_x()) build_insn_word(0x3c01a000); /* lui $at, 0xa000 */ @@ -420,12 +440,18 @@ dest = label(); void __init build_copy_page(void) { unsigned int loop_start; + unsigned long off; epc = (unsigned int *) ©_page_array; store_offset = load_offset = 0; instruction_pending = 0; - build_addiu_a2_a0(PAGE_SIZE - (cpu_has_prefetch ? pref_offset_copy : 0)); + off = PAGE_SIZE - (cpu_has_prefetch ? pref_offset_copy : 0); + if (off > 0x7fff) { + build_addiu_a2_a0(off >> 1); + build_addiu_a2(off >> 1); + } else + build_addiu_a2_a0(off); if (R4600_V2_HIT_CACHEOP_WAR && cpu_is_r4600_v2_x()) build_insn_word(0x3c01a000); /* lui $at, 0xa000 */ diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c index 6f8b25cfa6f0..fec318a1c8c5 100644 --- a/arch/mips/mm/tlbex.c +++ b/arch/mips/mm/tlbex.c @@ -102,7 +102,7 @@ enum opcode { insn_addu, insn_addiu, insn_and, insn_andi, insn_beq, insn_beql, insn_bgez, insn_bgezl, insn_bltz, insn_bltzl, insn_bne, insn_daddu, insn_daddiu, insn_dmfc0, insn_dmtc0, - insn_dsll, insn_dsll32, insn_dsra, insn_dsrl, + insn_dsll, insn_dsll32, insn_dsra, insn_dsrl, insn_dsrl32, insn_dsubu, insn_eret, insn_j, insn_jal, insn_jr, insn_ld, insn_ll, insn_lld, insn_lui, insn_lw, insn_mfc0, insn_mtc0, insn_ori, insn_rfe, insn_sc, insn_scd, insn_sd, insn_sll, @@ -145,6 +145,7 @@ static __initdata struct insn insn_table[] = { { insn_dsll32, M(spec_op,0,0,0,0,dsll32_op), RT | RD | RE }, { insn_dsra, M(spec_op,0,0,0,0,dsra_op), RT | RD | RE }, { insn_dsrl, M(spec_op,0,0,0,0,dsrl_op), RT | RD | RE }, + { insn_dsrl32, M(spec_op,0,0,0,0,dsrl32_op), RT | RD | RE }, { insn_dsubu, M(spec_op,0,0,0,0,dsubu_op), RS | RT | RD }, { insn_eret, M(cop0_op,cop_op,0,0,0,eret_op), 0 }, { insn_j, M(j_op,0,0,0,0,0), JIMM }, @@ -385,6 +386,7 @@ I_u2u1u3(_dsll); I_u2u1u3(_dsll32); I_u2u1u3(_dsra); I_u2u1u3(_dsrl); +I_u2u1u3(_dsrl32); I_u3u1u2(_dsubu); I_0(_eret); I_u1(_j); @@ -996,7 +998,12 @@ build_get_pmde64(u32 **p, struct label **l, struct reloc **r, #endif l_vmalloc_done(l, *p); - i_dsrl(p, tmp, tmp, PGDIR_SHIFT-3); /* get pgd offset in bytes */ + + if (PGDIR_SHIFT - 3 < 32) /* get pgd offset in bytes */ + i_dsrl(p, tmp, tmp, PGDIR_SHIFT-3); + else + i_dsrl32(p, tmp, tmp, PGDIR_SHIFT - 3 - 32); + i_andi(p, tmp, tmp, (PTRS_PER_PGD - 1)<<3); i_daddu(p, ptr, ptr, tmp); /* add in pgd offset */ i_dmfc0(p, tmp, C0_BADVADDR); /* get faulting address */ @@ -1073,7 +1080,7 @@ build_get_pgde32(u32 **p, unsigned int tmp, unsigned int ptr) static __init void build_adjust_context(u32 **p, unsigned int ctx) { - unsigned int shift = 4 - (PTE_T_LOG2 + 1); + unsigned int shift = 4 - (PTE_T_LOG2 + 1) + PAGE_SHIFT - 12; unsigned int mask = (PTRS_PER_PTE / 2 - 1) << (PTE_T_LOG2 + 1); switch (current_cpu_data.cputype) { diff --git a/include/asm-mips/asm.h b/include/asm-mips/asm.h index e3038a4599ee..838eb3144d81 100644 --- a/include/asm-mips/asm.h +++ b/include/asm-mips/asm.h @@ -344,6 +344,7 @@ symbol = value #define PTR_L lw #define PTR_S sw #define PTR_LA la +#define PTR_LI li #define PTR_SLL sll #define PTR_SLLV sllv #define PTR_SRL srl @@ -368,6 +369,7 @@ symbol = value #define PTR_L ld #define PTR_S sd #define PTR_LA dla +#define PTR_LI dli #define PTR_SLL dsll #define PTR_SLLV dsllv #define PTR_SRL dsrl diff --git a/include/asm-mips/pgalloc.h b/include/asm-mips/pgalloc.h index 582c1fe6cc4a..af121c67dc71 100644 --- a/include/asm-mips/pgalloc.h +++ b/include/asm-mips/pgalloc.h @@ -48,7 +48,7 @@ static inline pgd_t *pgd_alloc(struct mm_struct *mm) ret = (pgd_t *) __get_free_pages(GFP_KERNEL, PGD_ORDER); if (ret) { - init = pgd_offset(&init_mm, 0); + init = pgd_offset(&init_mm, 0UL); pgd_init((unsigned long)ret); memcpy(ret + USER_PTRS_PER_PGD, init + USER_PTRS_PER_PGD, (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t)); diff --git a/include/asm-mips/pgtable-64.h b/include/asm-mips/pgtable-64.h index d05fb6f38aa7..7e7320300aa3 100644 --- a/include/asm-mips/pgtable-64.h +++ b/include/asm-mips/pgtable-64.h @@ -174,7 +174,7 @@ static inline void pud_clear(pud_t *pudp) #define __pmd_offset(address) pmd_index(address) /* to find an entry in a kernel page-table-directory */ -#define pgd_offset_k(address) pgd_offset(&init_mm, 0) +#define pgd_offset_k(address) pgd_offset(&init_mm, 0UL) #define pgd_index(address) (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD-1)) #define pmd_index(address) (((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1)) -- cgit v1.2.3 From cb56837ea5f15fa5279fd490f292134c3a92e5de Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Tue, 31 Oct 2006 22:49:04 +0000 Subject: [MIPS] SMTC: Fix crash if # of TC's > # of VPE's after pt_regs irq cleanup. Signed-off-by: Ralf Baechle --- arch/mips/kernel/entry.S | 3 +++ arch/mips/kernel/smtc-asm.S | 7 ++++++- 2 files changed, 9 insertions(+), 1 deletion(-) (limited to 'arch/mips/kernel') diff --git a/arch/mips/kernel/entry.S b/arch/mips/kernel/entry.S index 417c08ac76eb..f10b6a19f8bf 100644 --- a/arch/mips/kernel/entry.S +++ b/arch/mips/kernel/entry.S @@ -83,7 +83,10 @@ FEXPORT(syscall_exit) FEXPORT(restore_all) # restore full frame #ifdef CONFIG_MIPS_MT_SMTC /* Detect and execute deferred IPI "interrupts" */ + LONG_L s0, TI_REGS($28) + LONG_S sp, TI_REGS($28) jal deferred_smtc_ipi + LONG_S s0, TI_REGS($28) /* Re-arm any temporarily masked interrupts not explicitly "acked" */ mfc0 v0, CP0_TCSTATUS ori v1, v0, TCSTATUS_IXMT diff --git a/arch/mips/kernel/smtc-asm.S b/arch/mips/kernel/smtc-asm.S index 1cb9441f1474..921207c4a83c 100644 --- a/arch/mips/kernel/smtc-asm.S +++ b/arch/mips/kernel/smtc-asm.S @@ -101,7 +101,9 @@ FEXPORT(__smtc_ipi_vector) lw t0,PT_PADSLOT5(sp) /* Argument from sender passed in stack pad slot 4 */ lw a0,PT_PADSLOT4(sp) - PTR_LA ra, _ret_from_irq + LONG_L s0, TI_REGS($28) + LONG_S sp, TI_REGS($28) + PTR_LA ra, ret_from_irq jr t0 /* @@ -119,7 +121,10 @@ LEAF(self_ipi) subu t1,sp,PT_SIZE sw ra,PT_EPC(t1) sw a0,PT_PADSLOT4(t1) + LONG_L s0, TI_REGS($28) + LONG_S sp, TI_REGS($28) la t2,ipi_decode + LONG_S s0, TI_REGS($28) sw t2,PT_PADSLOT5(t1) /* Save pre-disable value of TCStatus */ sw t0,PT_TCSTATUS(t1) -- cgit v1.2.3 From 64c590b7a62ae1272fe4afd7b915de314591f35e Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Wed, 1 Nov 2006 00:22:00 +0000 Subject: [MIPS] SMTC: Synchronize cp0 counters on bootup. Signed-off-by: Ralf Baechle --- arch/mips/kernel/smtc.c | 1 + 1 file changed, 1 insertion(+) (limited to 'arch/mips/kernel') diff --git a/arch/mips/kernel/smtc.c b/arch/mips/kernel/smtc.c index cc1f7474f7d7..3b78caf112f5 100644 --- a/arch/mips/kernel/smtc.c +++ b/arch/mips/kernel/smtc.c @@ -476,6 +476,7 @@ void mipsmt_prepare_cpus(void) write_vpe_c0_compare(0); /* Propagate Config7 */ write_vpe_c0_config7(read_c0_config7()); + write_vpe_c0_count(read_c0_count()); } /* enable multi-threading within VPE */ write_vpe_c0_vpecontrol(read_vpe_c0_vpecontrol() | VPECONTROL_TE); -- cgit v1.2.3 From 9ba126cfbf505f4d5b39ed294cedd241321c7a91 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Fri, 13 Oct 2006 11:22:52 +0100 Subject: [MIPS] Fix warning about init_initrd() call if !CONFIG_BLK_DEV_INITRD. Signed-off-by: Ralf Baechle --- arch/mips/kernel/setup.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'arch/mips/kernel') diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c index fdbb508661c5..8f6e89697ccf 100644 --- a/arch/mips/kernel/setup.c +++ b/arch/mips/kernel/setup.c @@ -223,7 +223,11 @@ disable: #else /* !CONFIG_BLK_DEV_INITRD */ -#define init_initrd() 0 +static unsigned long __init init_initrd(void) +{ + return 0; +} + #define finalize_initrd() do {} while (0) #endif -- cgit v1.2.3