aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips')
-rw-r--r--arch/mips/Makefile1
-rw-r--r--arch/mips/configs/ip27_defconfig13
-rw-r--r--arch/mips/kernel/binfmt_elfn32.c5
-rw-r--r--arch/mips/kernel/binfmt_elfo32.c5
-rw-r--r--arch/mips/kernel/linux32.c22
-rw-r--r--arch/mips/kernel/process.c158
-rw-r--r--arch/mips/kernel/scall32-o32.S2
-rw-r--r--arch/mips/kernel/scall64-n32.S4
-rw-r--r--arch/mips/kernel/signal-common.h2
-rw-r--r--arch/mips/kernel/signal32.c76
-rw-r--r--arch/mips/kernel/signal_n32.c35
-rw-r--r--arch/mips/kernel/smp.c20
-rw-r--r--arch/mips/kernel/smp_mt.c34
-rw-r--r--arch/mips/kernel/traps.c4
-rw-r--r--arch/mips/mm/c-r4k.c104
-rw-r--r--arch/mips/mm/c-tx39.c70
-rw-r--r--arch/mips/mm/cex-sb1.S2
-rw-r--r--arch/mips/pmc-sierra/yosemite/smp.c2
-rw-r--r--arch/mips/sibyte/Kconfig4
-rw-r--r--arch/mips/sibyte/bcm1480/irq.c5
20 files changed, 234 insertions, 334 deletions
diff --git a/arch/mips/Makefile b/arch/mips/Makefile
index 6a57407df1bc..38c0f3360d51 100644
--- a/arch/mips/Makefile
+++ b/arch/mips/Makefile
@@ -94,7 +94,6 @@ endif
94# machines may also. Since BFD is incredibly buggy with respect to 94# machines may also. Since BFD is incredibly buggy with respect to
95# crossformat linking we rely on the elf2ecoff tool for format conversion. 95# crossformat linking we rely on the elf2ecoff tool for format conversion.
96# 96#
97cflags-y += -I $(TOPDIR)/include/asm/gcc
98cflags-y += -G 0 -mno-abicalls -fno-pic -pipe 97cflags-y += -G 0 -mno-abicalls -fno-pic -pipe
99LDFLAGS_vmlinux += -G 0 -static -n -nostdlib 98LDFLAGS_vmlinux += -G 0 -static -n -nostdlib
100MODFLAGS += -mlong-calls 99MODFLAGS += -mlong-calls
diff --git a/arch/mips/configs/ip27_defconfig b/arch/mips/configs/ip27_defconfig
index e17d3adff021..58c22cd344d3 100644
--- a/arch/mips/configs/ip27_defconfig
+++ b/arch/mips/configs/ip27_defconfig
@@ -1,7 +1,7 @@
1# 1#
2# Automatically generated make config: don't edit 2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.15-rc2 3# Linux kernel version: 2.6.16-rc4
4# Thu Nov 24 01:06:21 2005 4# Tue Feb 21 13:44:31 2006
5# 5#
6CONFIG_MIPS=y 6CONFIG_MIPS=y
7 7
@@ -144,7 +144,6 @@ CONFIG_PREEMPT_BKL=y
144# Code maturity level options 144# Code maturity level options
145# 145#
146CONFIG_EXPERIMENTAL=y 146CONFIG_EXPERIMENTAL=y
147CONFIG_CLEAN_COMPILE=y
148CONFIG_LOCK_KERNEL=y 147CONFIG_LOCK_KERNEL=y
149CONFIG_INIT_ENV_ARG_LIMIT=32 148CONFIG_INIT_ENV_ARG_LIMIT=32
150 149
@@ -250,6 +249,7 @@ CONFIG_NET=y
250# 249#
251# Networking options 250# Networking options
252# 251#
252# CONFIG_NETDEBUG is not set
253CONFIG_PACKET=y 253CONFIG_PACKET=y
254CONFIG_PACKET_MMAP=y 254CONFIG_PACKET_MMAP=y
255CONFIG_UNIX=y 255CONFIG_UNIX=y
@@ -289,6 +289,7 @@ CONFIG_TCP_CONG_BIC=y
289# SCTP Configuration (EXPERIMENTAL) 289# SCTP Configuration (EXPERIMENTAL)
290# 290#
291# CONFIG_IP_SCTP is not set 291# CONFIG_IP_SCTP is not set
292
292# CONFIG_ATM is not set 293# CONFIG_ATM is not set
293# CONFIG_BRIDGE is not set 294# CONFIG_BRIDGE is not set
294# CONFIG_VLAN_8021Q is not set 295# CONFIG_VLAN_8021Q is not set
@@ -448,7 +449,7 @@ CONFIG_SCSI_SAS_ATTRS=m
448# 449#
449# SCSI low-level drivers 450# SCSI low-level drivers
450# 451#
451CONFIG_ISCSI_TCP=m 452# CONFIG_ISCSI_TCP is not set
452# CONFIG_BLK_DEV_3W_XXXX_RAID is not set 453# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
453# CONFIG_SCSI_3W_9XXX is not set 454# CONFIG_SCSI_3W_9XXX is not set
454# CONFIG_SCSI_ACARD is not set 455# CONFIG_SCSI_ACARD is not set
@@ -774,6 +775,10 @@ CONFIG_USB_ARCH_HAS_OHCI=y
774# 775#
775 776
776# 777#
778# EDAC - error detection and reporting (RAS)
779#
780
781#
777# File systems 782# File systems
778# 783#
779CONFIG_EXT2_FS=y 784CONFIG_EXT2_FS=y
diff --git a/arch/mips/kernel/binfmt_elfn32.c b/arch/mips/kernel/binfmt_elfn32.c
index d8e2674a1543..4a9f1ecefaf2 100644
--- a/arch/mips/kernel/binfmt_elfn32.c
+++ b/arch/mips/kernel/binfmt_elfn32.c
@@ -103,8 +103,9 @@ jiffies_to_compat_timeval(unsigned long jiffies, struct compat_timeval *value)
103 * one divide. 103 * one divide.
104 */ 104 */
105 u64 nsec = (u64)jiffies * TICK_NSEC; 105 u64 nsec = (u64)jiffies * TICK_NSEC;
106 value->tv_sec = div_long_long_rem(nsec, NSEC_PER_SEC, &value->tv_usec); 106 long rem;
107 value->tv_usec /= NSEC_PER_USEC; 107 value->tv_sec = div_long_long_rem(nsec, NSEC_PER_SEC, &rem);
108 value->tv_usec = rem / NSEC_PER_USEC;
108} 109}
109 110
110#define ELF_CORE_EFLAGS EF_MIPS_ABI2 111#define ELF_CORE_EFLAGS EF_MIPS_ABI2
diff --git a/arch/mips/kernel/binfmt_elfo32.c b/arch/mips/kernel/binfmt_elfo32.c
index cec5f327e360..e31813779895 100644
--- a/arch/mips/kernel/binfmt_elfo32.c
+++ b/arch/mips/kernel/binfmt_elfo32.c
@@ -105,8 +105,9 @@ jiffies_to_compat_timeval(unsigned long jiffies, struct compat_timeval *value)
105 * one divide. 105 * one divide.
106 */ 106 */
107 u64 nsec = (u64)jiffies * TICK_NSEC; 107 u64 nsec = (u64)jiffies * TICK_NSEC;
108 value->tv_sec = div_long_long_rem(nsec, NSEC_PER_SEC, &value->tv_usec); 108 long rem;
109 value->tv_usec /= NSEC_PER_USEC; 109 value->tv_sec = div_long_long_rem(nsec, NSEC_PER_SEC, &rem);
110 value->tv_usec = rem / NSEC_PER_USEC;
110} 111}
111 112
112#undef ELF_CORE_COPY_REGS 113#undef ELF_CORE_COPY_REGS
diff --git a/arch/mips/kernel/linux32.c b/arch/mips/kernel/linux32.c
index 60353f5acc48..5f68b220c26d 100644
--- a/arch/mips/kernel/linux32.c
+++ b/arch/mips/kernel/linux32.c
@@ -230,6 +230,9 @@ sysn32_waitid(int which, compat_pid_t pid,
230 long ret; 230 long ret;
231 mm_segment_t old_fs = get_fs(); 231 mm_segment_t old_fs = get_fs();
232 232
233 if (!access_ok(VERIFY_WRITE, uinfo, sizeof(*uinfo)))
234 return -EFAULT;
235
233 set_fs (KERNEL_DS); 236 set_fs (KERNEL_DS);
234 ret = sys_waitid(which, pid, uinfo, options, 237 ret = sys_waitid(which, pid, uinfo, options,
235 uru ? (struct rusage __user *) &ru : NULL); 238 uru ? (struct rusage __user *) &ru : NULL);
@@ -1450,25 +1453,6 @@ sys32_timer_create(u32 clock, struct sigevent32 __user *se32, timer_t __user *ti
1450 return sys_timer_create(clock, p, timer_id); 1453 return sys_timer_create(clock, p, timer_id);
1451} 1454}
1452 1455
1453asmlinkage long
1454sysn32_rt_sigtimedwait(const sigset_t __user *uthese,
1455 siginfo_t __user *uinfo,
1456 const struct compat_timespec __user *uts32,
1457 size_t sigsetsize)
1458{
1459 struct timespec __user *uts = NULL;
1460
1461 if (uts32) {
1462 struct timespec ts;
1463 uts = compat_alloc_user_space(sizeof(struct timespec));
1464 if (get_user(ts.tv_sec, &uts32->tv_sec) ||
1465 get_user(ts.tv_nsec, &uts32->tv_nsec) ||
1466 copy_to_user (uts, &ts, sizeof (ts)))
1467 return -EFAULT;
1468 }
1469 return sys_rt_sigtimedwait(uthese, uinfo, uts, sigsetsize);
1470}
1471
1472save_static_function(sys32_clone); 1456save_static_function(sys32_clone);
1473__attribute_used__ noinline static int 1457__attribute_used__ noinline static int
1474_sys32_clone(nabi_no_regargs struct pt_regs regs) 1458_sys32_clone(nabi_no_regargs struct pt_regs regs)
diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c
index 5232fc752935..092679c2dca9 100644
--- a/arch/mips/kernel/process.c
+++ b/arch/mips/kernel/process.c
@@ -25,6 +25,7 @@
25#include <linux/a.out.h> 25#include <linux/a.out.h>
26#include <linux/init.h> 26#include <linux/init.h>
27#include <linux/completion.h> 27#include <linux/completion.h>
28#include <linux/kallsyms.h>
28 29
29#include <asm/abi.h> 30#include <asm/abi.h>
30#include <asm/bootinfo.h> 31#include <asm/bootinfo.h>
@@ -272,46 +273,19 @@ long kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
272 273
273static struct mips_frame_info { 274static struct mips_frame_info {
274 void *func; 275 void *func;
275 int omit_fp; /* compiled without fno-omit-frame-pointer */ 276 unsigned long func_size;
276 int frame_offset; 277 int frame_size;
277 int pc_offset; 278 int pc_offset;
278} schedule_frame, mfinfo[] = { 279} *schedule_frame, mfinfo[64];
279 { schedule, 0 }, /* must be first */ 280static int mfinfo_num;
280 /* arch/mips/kernel/semaphore.c */
281 { __down, 1 },
282 { __down_interruptible, 1 },
283 /* kernel/sched.c */
284#ifdef CONFIG_PREEMPT
285 { preempt_schedule, 0 },
286#endif
287 { wait_for_completion, 0 },
288 { interruptible_sleep_on, 0 },
289 { interruptible_sleep_on_timeout, 0 },
290 { sleep_on, 0 },
291 { sleep_on_timeout, 0 },
292 { yield, 0 },
293 { io_schedule, 0 },
294 { io_schedule_timeout, 0 },
295#if defined(CONFIG_SMP) && defined(CONFIG_PREEMPT)
296 { __preempt_spin_lock, 0 },
297 { __preempt_write_lock, 0 },
298#endif
299 /* kernel/timer.c */
300 { schedule_timeout, 1 },
301/* { nanosleep_restart, 1 }, */
302 /* lib/rwsem-spinlock.c */
303 { __down_read, 1 },
304 { __down_write, 1 },
305};
306 281
307static int mips_frame_info_initialized;
308static int __init get_frame_info(struct mips_frame_info *info) 282static int __init get_frame_info(struct mips_frame_info *info)
309{ 283{
310 int i; 284 int i;
311 void *func = info->func; 285 void *func = info->func;
312 union mips_instruction *ip = (union mips_instruction *)func; 286 union mips_instruction *ip = (union mips_instruction *)func;
313 info->pc_offset = -1; 287 info->pc_offset = -1;
314 info->frame_offset = info->omit_fp ? 0 : -1; 288 info->frame_size = 0;
315 for (i = 0; i < 128; i++, ip++) { 289 for (i = 0; i < 128; i++, ip++) {
316 /* if jal, jalr, jr, stop. */ 290 /* if jal, jalr, jr, stop. */
317 if (ip->j_format.opcode == jal_op || 291 if (ip->j_format.opcode == jal_op ||
@@ -320,6 +294,23 @@ static int __init get_frame_info(struct mips_frame_info *info)
320 ip->r_format.func == jr_op))) 294 ip->r_format.func == jr_op)))
321 break; 295 break;
322 296
297 if (info->func_size && i >= info->func_size / 4)
298 break;
299 if (
300#ifdef CONFIG_32BIT
301 ip->i_format.opcode == addiu_op &&
302#endif
303#ifdef CONFIG_64BIT
304 ip->i_format.opcode == daddiu_op &&
305#endif
306 ip->i_format.rs == 29 &&
307 ip->i_format.rt == 29) {
308 /* addiu/daddiu sp,sp,-imm */
309 if (info->frame_size)
310 continue;
311 info->frame_size = - ip->i_format.simmediate;
312 }
313
323 if ( 314 if (
324#ifdef CONFIG_32BIT 315#ifdef CONFIG_32BIT
325 ip->i_format.opcode == sw_op && 316 ip->i_format.opcode == sw_op &&
@@ -327,31 +318,20 @@ static int __init get_frame_info(struct mips_frame_info *info)
327#ifdef CONFIG_64BIT 318#ifdef CONFIG_64BIT
328 ip->i_format.opcode == sd_op && 319 ip->i_format.opcode == sd_op &&
329#endif 320#endif
330 ip->i_format.rs == 29) 321 ip->i_format.rs == 29 &&
331 { 322 ip->i_format.rt == 31) {
332 /* sw / sd $ra, offset($sp) */ 323 /* sw / sd $ra, offset($sp) */
333 if (ip->i_format.rt == 31) { 324 if (info->pc_offset != -1)
334 if (info->pc_offset != -1) 325 continue;
335 continue; 326 info->pc_offset =
336 info->pc_offset = 327 ip->i_format.simmediate / sizeof(long);
337 ip->i_format.simmediate / sizeof(long);
338 }
339 /* sw / sd $s8, offset($sp) */
340 if (ip->i_format.rt == 30) {
341//#if 0 /* gcc 3.4 does aggressive optimization... */
342 if (info->frame_offset != -1)
343 continue;
344//#endif
345 info->frame_offset =
346 ip->i_format.simmediate / sizeof(long);
347 }
348 } 328 }
349 } 329 }
350 if (info->pc_offset == -1 || info->frame_offset == -1) { 330 if (info->pc_offset == -1 || info->frame_size == 0) {
351 printk("Can't analyze prologue code at %p\n", func); 331 if (func == schedule)
332 printk("Can't analyze prologue code at %p\n", func);
352 info->pc_offset = -1; 333 info->pc_offset = -1;
353 info->frame_offset = -1; 334 info->frame_size = 0;
354 return -1;
355 } 335 }
356 336
357 return 0; 337 return 0;
@@ -359,25 +339,36 @@ static int __init get_frame_info(struct mips_frame_info *info)
359 339
360static int __init frame_info_init(void) 340static int __init frame_info_init(void)
361{ 341{
362 int i, found; 342 int i;
363 for (i = 0; i < ARRAY_SIZE(mfinfo); i++) 343#ifdef CONFIG_KALLSYMS
364 if (get_frame_info(&mfinfo[i])) 344 char *modname;
365 return -1; 345 char namebuf[KSYM_NAME_LEN + 1];
366 schedule_frame = mfinfo[0]; 346 unsigned long start, size, ofs;
367 /* bubble sort */ 347 extern char __sched_text_start[], __sched_text_end[];
368 do { 348 extern char __lock_text_start[], __lock_text_end[];
369 struct mips_frame_info tmp; 349
370 found = 0; 350 start = (unsigned long)__sched_text_start;
371 for (i = 1; i < ARRAY_SIZE(mfinfo); i++) { 351 for (i = 0; i < ARRAY_SIZE(mfinfo); i++) {
372 if (mfinfo[i-1].func > mfinfo[i].func) { 352 if (start == (unsigned long)schedule)
373 tmp = mfinfo[i]; 353 schedule_frame = &mfinfo[i];
374 mfinfo[i] = mfinfo[i-1]; 354 if (!kallsyms_lookup(start, &size, &ofs, &modname, namebuf))
375 mfinfo[i-1] = tmp; 355 break;
376 found = 1; 356 mfinfo[i].func = (void *)(start + ofs);
377 } 357 mfinfo[i].func_size = size;
378 } 358 start += size - ofs;
379 } while (found); 359 if (start >= (unsigned long)__lock_text_end)
380 mips_frame_info_initialized = 1; 360 break;
361 if (start == (unsigned long)__sched_text_end)
362 start = (unsigned long)__lock_text_start;
363 }
364#else
365 mfinfo[0].func = schedule;
366 schedule_frame = &mfinfo[0];
367#endif
368 for (i = 0; i < ARRAY_SIZE(mfinfo) && mfinfo[i].func; i++)
369 get_frame_info(&mfinfo[i]);
370
371 mfinfo_num = i;
381 return 0; 372 return 0;
382} 373}
383 374
@@ -394,47 +385,52 @@ unsigned long thread_saved_pc(struct task_struct *tsk)
394 if (t->reg31 == (unsigned long) ret_from_fork) 385 if (t->reg31 == (unsigned long) ret_from_fork)
395 return t->reg31; 386 return t->reg31;
396 387
397 if (schedule_frame.pc_offset < 0) 388 if (!schedule_frame || schedule_frame->pc_offset < 0)
398 return 0; 389 return 0;
399 return ((unsigned long *)t->reg29)[schedule_frame.pc_offset]; 390 return ((unsigned long *)t->reg29)[schedule_frame->pc_offset];
400} 391}
401 392
402/* get_wchan - a maintenance nightmare^W^Wpain in the ass ... */ 393/* get_wchan - a maintenance nightmare^W^Wpain in the ass ... */
403unsigned long get_wchan(struct task_struct *p) 394unsigned long get_wchan(struct task_struct *p)
404{ 395{
405 unsigned long stack_page; 396 unsigned long stack_page;
406 unsigned long frame, pc; 397 unsigned long pc;
398#ifdef CONFIG_KALLSYMS
399 unsigned long frame;
400#endif
407 401
408 if (!p || p == current || p->state == TASK_RUNNING) 402 if (!p || p == current || p->state == TASK_RUNNING)
409 return 0; 403 return 0;
410 404
411 stack_page = (unsigned long)task_stack_page(p); 405 stack_page = (unsigned long)task_stack_page(p);
412 if (!stack_page || !mips_frame_info_initialized) 406 if (!stack_page || !mfinfo_num)
413 return 0; 407 return 0;
414 408
415 pc = thread_saved_pc(p); 409 pc = thread_saved_pc(p);
410#ifdef CONFIG_KALLSYMS
416 if (!in_sched_functions(pc)) 411 if (!in_sched_functions(pc))
417 return pc; 412 return pc;
418 413
419 frame = ((unsigned long *)p->thread.reg30)[schedule_frame.frame_offset]; 414 frame = p->thread.reg29 + schedule_frame->frame_size;
420 do { 415 do {
421 int i; 416 int i;
422 417
423 if (frame < stack_page || frame > stack_page + THREAD_SIZE - 32) 418 if (frame < stack_page || frame > stack_page + THREAD_SIZE - 32)
424 return 0; 419 return 0;
425 420
426 for (i = ARRAY_SIZE(mfinfo) - 1; i >= 0; i--) { 421 for (i = mfinfo_num - 1; i >= 0; i--) {
427 if (pc >= (unsigned long) mfinfo[i].func) 422 if (pc >= (unsigned long) mfinfo[i].func)
428 break; 423 break;
429 } 424 }
430 if (i < 0) 425 if (i < 0)
431 break; 426 break;
432 427
433 if (mfinfo[i].omit_fp)
434 break;
435 pc = ((unsigned long *)frame)[mfinfo[i].pc_offset]; 428 pc = ((unsigned long *)frame)[mfinfo[i].pc_offset];
436 frame = ((unsigned long *)frame)[mfinfo[i].frame_offset]; 429 if (!mfinfo[i].frame_size)
430 break;
431 frame += mfinfo[i].frame_size;
437 } while (in_sched_functions(pc)); 432 } while (in_sched_functions(pc));
433#endif
438 434
439 return pc; 435 return pc;
440} 436}
diff --git a/arch/mips/kernel/scall32-o32.S b/arch/mips/kernel/scall32-o32.S
index d7c4a38ed5ae..d83e033dbc87 100644
--- a/arch/mips/kernel/scall32-o32.S
+++ b/arch/mips/kernel/scall32-o32.S
@@ -623,7 +623,7 @@ einval: li v0, -EINVAL
623 sys sys_mknodat 4 /* 4290 */ 623 sys sys_mknodat 4 /* 4290 */
624 sys sys_fchownat 5 624 sys sys_fchownat 5
625 sys sys_futimesat 3 625 sys sys_futimesat 3
626 sys sys_newfstatat 4 626 sys sys_fstatat64 4
627 sys sys_unlinkat 3 627 sys sys_unlinkat 3
628 sys sys_renameat 4 /* 4295 */ 628 sys sys_renameat 4 /* 4295 */
629 sys sys_linkat 4 629 sys sys_linkat 4
diff --git a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S
index bc4980cefc8b..d87b5446fa13 100644
--- a/arch/mips/kernel/scall64-n32.S
+++ b/arch/mips/kernel/scall64-n32.S
@@ -245,9 +245,9 @@ EXPORT(sysn32_call_table)
245 PTR sys_capget 245 PTR sys_capget
246 PTR sys_capset 246 PTR sys_capset
247 PTR sys32_rt_sigpending /* 6125 */ 247 PTR sys32_rt_sigpending /* 6125 */
248 PTR sysn32_rt_sigtimedwait 248 PTR compat_sys_rt_sigtimedwait
249 PTR sys_rt_sigqueueinfo 249 PTR sys_rt_sigqueueinfo
250 PTR sys32_rt_sigsuspend 250 PTR sysn32_rt_sigsuspend
251 PTR sys32_sigaltstack 251 PTR sys32_sigaltstack
252 PTR compat_sys_utime /* 6130 */ 252 PTR compat_sys_utime /* 6130 */
253 PTR sys_mknod 253 PTR sys_mknod
diff --git a/arch/mips/kernel/signal-common.h b/arch/mips/kernel/signal-common.h
index 0fbc492d24b4..36bfc2588aa3 100644
--- a/arch/mips/kernel/signal-common.h
+++ b/arch/mips/kernel/signal-common.h
@@ -176,7 +176,7 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size)
176 if ((ka->sa.sa_flags & SA_ONSTACK) && (sas_ss_flags (sp) == 0)) 176 if ((ka->sa.sa_flags & SA_ONSTACK) && (sas_ss_flags (sp) == 0))
177 sp = current->sas_ss_sp + current->sas_ss_size; 177 sp = current->sas_ss_sp + current->sas_ss_size;
178 178
179 return (void __user *)((sp - frame_size) & (ICACHE_REFILLS_WORKAROUND_WAR ? 32 : ALMASK)); 179 return (void __user *)((sp - frame_size) & (ICACHE_REFILLS_WORKAROUND_WAR ? ~(cpu_icache_line_size()-1) : ALMASK));
180} 180}
181 181
182static inline int install_sigtramp(unsigned int __user *tramp, 182static inline int install_sigtramp(unsigned int __user *tramp,
diff --git a/arch/mips/kernel/signal32.c b/arch/mips/kernel/signal32.c
index da3271e1fdac..237cd8a2cd32 100644
--- a/arch/mips/kernel/signal32.c
+++ b/arch/mips/kernel/signal32.c
@@ -4,7 +4,7 @@
4 * for more details. 4 * for more details.
5 * 5 *
6 * Copyright (C) 1991, 1992 Linus Torvalds 6 * Copyright (C) 1991, 1992 Linus Torvalds
7 * Copyright (C) 1994 - 2000 Ralf Baechle 7 * Copyright (C) 1994 - 2000, 2006 Ralf Baechle
8 * Copyright (C) 1999, 2000 Silicon Graphics, Inc. 8 * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
9 */ 9 */
10#include <linux/cache.h> 10#include <linux/cache.h>
@@ -106,8 +106,6 @@ typedef struct compat_siginfo {
106 106
107#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) 107#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
108 108
109extern int do_signal32(sigset_t *oldset, struct pt_regs *regs);
110
111/* 32-bit compatibility types */ 109/* 32-bit compatibility types */
112 110
113#define _NSIG_BPW32 32 111#define _NSIG_BPW32 32
@@ -198,7 +196,7 @@ __attribute_used__ noinline static int
198_sys32_sigsuspend(nabi_no_regargs struct pt_regs regs) 196_sys32_sigsuspend(nabi_no_regargs struct pt_regs regs)
199{ 197{
200 compat_sigset_t *uset; 198 compat_sigset_t *uset;
201 sigset_t newset, saveset; 199 sigset_t newset;
202 200
203 uset = (compat_sigset_t *) regs.regs[4]; 201 uset = (compat_sigset_t *) regs.regs[4];
204 if (get_sigset(&newset, uset)) 202 if (get_sigset(&newset, uset))
@@ -206,19 +204,15 @@ _sys32_sigsuspend(nabi_no_regargs struct pt_regs regs)
206 sigdelsetmask(&newset, ~_BLOCKABLE); 204 sigdelsetmask(&newset, ~_BLOCKABLE);
207 205
208 spin_lock_irq(&current->sighand->siglock); 206 spin_lock_irq(&current->sighand->siglock);
209 saveset = current->blocked; 207 current->saved_sigmask = current->blocked;
210 current->blocked = newset; 208 current->blocked = newset;
211 recalc_sigpending(); 209 recalc_sigpending();
212 spin_unlock_irq(&current->sighand->siglock); 210 spin_unlock_irq(&current->sighand->siglock);
213 211
214 regs.regs[2] = EINTR; 212 current->state = TASK_INTERRUPTIBLE;
215 regs.regs[7] = 1; 213 schedule();
216 while (1) { 214 set_thread_flag(TIF_RESTORE_SIGMASK);
217 current->state = TASK_INTERRUPTIBLE; 215 return -ERESTARTNOHAND;
218 schedule();
219 if (do_signal32(&saveset, &regs))
220 return -EINTR;
221 }
222} 216}
223 217
224save_static_function(sys32_rt_sigsuspend); 218save_static_function(sys32_rt_sigsuspend);
@@ -226,8 +220,8 @@ __attribute_used__ noinline static int
226_sys32_rt_sigsuspend(nabi_no_regargs struct pt_regs regs) 220_sys32_rt_sigsuspend(nabi_no_regargs struct pt_regs regs)
227{ 221{
228 compat_sigset_t *uset; 222 compat_sigset_t *uset;
229 sigset_t newset, saveset; 223 sigset_t newset;
230 size_t sigsetsize; 224 size_t sigsetsize;
231 225
232 /* XXX Don't preclude handling different sized sigset_t's. */ 226 /* XXX Don't preclude handling different sized sigset_t's. */
233 sigsetsize = regs.regs[5]; 227 sigsetsize = regs.regs[5];
@@ -240,19 +234,15 @@ _sys32_rt_sigsuspend(nabi_no_regargs struct pt_regs regs)
240 sigdelsetmask(&newset, ~_BLOCKABLE); 234 sigdelsetmask(&newset, ~_BLOCKABLE);
241 235
242 spin_lock_irq(&current->sighand->siglock); 236 spin_lock_irq(&current->sighand->siglock);
243 saveset = current->blocked; 237 current->saved_sigmask = current->blocked;
244 current->blocked = newset; 238 current->blocked = newset;
245 recalc_sigpending(); 239 recalc_sigpending();
246 spin_unlock_irq(&current->sighand->siglock); 240 spin_unlock_irq(&current->sighand->siglock);
247 241
248 regs.regs[2] = EINTR; 242 current->state = TASK_INTERRUPTIBLE;
249 regs.regs[7] = 1; 243 schedule();
250 while (1) { 244 set_thread_flag(TIF_RESTORE_SIGMASK);
251 current->state = TASK_INTERRUPTIBLE; 245 return -ERESTARTNOHAND;
252 schedule();
253 if (do_signal32(&saveset, &regs))
254 return -EINTR;
255 }
256} 246}
257 247
258asmlinkage int sys32_sigaction(int sig, const struct sigaction32 *act, 248asmlinkage int sys32_sigaction(int sig, const struct sigaction32 *act,
@@ -537,7 +527,7 @@ _sys32_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
537 /* The ucontext contains a stack32_t, so we must convert! */ 527 /* The ucontext contains a stack32_t, so we must convert! */
538 if (__get_user(sp, &frame->rs_uc.uc_stack.ss_sp)) 528 if (__get_user(sp, &frame->rs_uc.uc_stack.ss_sp))
539 goto badframe; 529 goto badframe;
540 st.ss_size = (long) sp; 530 st.ss_sp = (void *)(long) sp;
541 if (__get_user(st.ss_size, &frame->rs_uc.uc_stack.ss_size)) 531 if (__get_user(st.ss_size, &frame->rs_uc.uc_stack.ss_size))
542 goto badframe; 532 goto badframe;
543 if (__get_user(st.ss_flags, &frame->rs_uc.uc_stack.ss_flags)) 533 if (__get_user(st.ss_flags, &frame->rs_uc.uc_stack.ss_flags))
@@ -783,7 +773,7 @@ static inline int handle_signal(unsigned long sig, siginfo_t *info,
783 regs->regs[2] = EINTR; 773 regs->regs[2] = EINTR;
784 break; 774 break;
785 case ERESTARTSYS: 775 case ERESTARTSYS:
786 if(!(ka->sa.sa_flags & SA_RESTART)) { 776 if (!(ka->sa.sa_flags & SA_RESTART)) {
787 regs->regs[2] = EINTR; 777 regs->regs[2] = EINTR;
788 break; 778 break;
789 } 779 }
@@ -810,9 +800,10 @@ static inline int handle_signal(unsigned long sig, siginfo_t *info,
810 return ret; 800 return ret;
811} 801}
812 802
813int do_signal32(sigset_t *oldset, struct pt_regs *regs) 803void do_signal32(struct pt_regs *regs)
814{ 804{
815 struct k_sigaction ka; 805 struct k_sigaction ka;
806 sigset_t *oldset;
816 siginfo_t info; 807 siginfo_t info;
817 int signr; 808 int signr;
818 809
@@ -822,17 +813,30 @@ int do_signal32(sigset_t *oldset, struct pt_regs *regs)
822 * if so. 813 * if so.
823 */ 814 */
824 if (!user_mode(regs)) 815 if (!user_mode(regs))
825 return 1; 816 return;
826 817
827 if (try_to_freeze()) 818 if (try_to_freeze())
828 goto no_signal; 819 goto no_signal;
829 820
830 if (!oldset) 821 if (test_thread_flag(TIF_RESTORE_SIGMASK))
822 oldset = &current->saved_sigmask;
823 else
831 oldset = &current->blocked; 824 oldset = &current->blocked;
832 825
833 signr = get_signal_to_deliver(&info, &ka, regs, NULL); 826 signr = get_signal_to_deliver(&info, &ka, regs, NULL);
834 if (signr > 0) 827 if (signr > 0) {
835 return handle_signal(signr, &info, &ka, oldset, regs); 828 /* Whee! Actually deliver the signal. */
829 if (handle_signal(signr, &info, &ka, oldset, regs) == 0) {
830 /*
831 * A signal was successfully delivered; the saved
832 * sigmask will have been stored in the signal frame,
833 * and will be restored by sigreturn, so we can simply
834 * clear the TIF_RESTORE_SIGMASK flag.
835 */
836 if (test_thread_flag(TIF_RESTORE_SIGMASK))
837 clear_thread_flag(TIF_RESTORE_SIGMASK);
838 }
839 }
836 840
837no_signal: 841no_signal:
838 /* 842 /*
@@ -853,7 +857,15 @@ no_signal:
853 regs->cp0_epc -= 4; 857 regs->cp0_epc -= 4;
854 } 858 }
855 } 859 }
856 return 0; 860
861 /*
862 * If there's no signal to deliver, we just put the saved sigmask
863 * back
864 */
865 if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
866 clear_thread_flag(TIF_RESTORE_SIGMASK);
867 sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
868 }
857} 869}
858 870
859asmlinkage int sys32_rt_sigaction(int sig, const struct sigaction32 *act, 871asmlinkage int sys32_rt_sigaction(int sig, const struct sigaction32 *act,
diff --git a/arch/mips/kernel/signal_n32.c b/arch/mips/kernel/signal_n32.c
index 384fc4a639a4..3e168c08a3a8 100644
--- a/arch/mips/kernel/signal_n32.c
+++ b/arch/mips/kernel/signal_n32.c
@@ -81,6 +81,39 @@ struct rt_sigframe_n32 {
81#endif 81#endif
82}; 82};
83 83
84extern void sigset_from_compat (sigset_t *set, compat_sigset_t *compat);
85
86save_static_function(sysn32_rt_sigsuspend);
87__attribute_used__ noinline static int
88_sysn32_rt_sigsuspend(nabi_no_regargs struct pt_regs regs)
89{
90 compat_sigset_t __user *unewset, uset;
91 size_t sigsetsize;
92 sigset_t newset;
93
94 /* XXX Don't preclude handling different sized sigset_t's. */
95 sigsetsize = regs.regs[5];
96 if (sigsetsize != sizeof(sigset_t))
97 return -EINVAL;
98
99 unewset = (compat_sigset_t __user *) regs.regs[4];
100 if (copy_from_user(&uset, unewset, sizeof(uset)))
101 return -EFAULT;
102 sigset_from_compat (&newset, &uset);
103 sigdelsetmask(&newset, ~_BLOCKABLE);
104
105 spin_lock_irq(&current->sighand->siglock);
106 current->saved_sigmask = current->blocked;
107 current->blocked = newset;
108 recalc_sigpending();
109 spin_unlock_irq(&current->sighand->siglock);
110
111 current->state = TASK_INTERRUPTIBLE;
112 schedule();
113 set_thread_flag(TIF_RESTORE_SIGMASK);
114 return -ERESTARTNOHAND;
115}
116
84save_static_function(sysn32_rt_sigreturn); 117save_static_function(sysn32_rt_sigreturn);
85__attribute_used__ noinline static void 118__attribute_used__ noinline static void
86_sysn32_rt_sigreturn(nabi_no_regargs struct pt_regs regs) 119_sysn32_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
@@ -108,7 +141,7 @@ _sysn32_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
108 /* The ucontext contains a stack32_t, so we must convert! */ 141 /* The ucontext contains a stack32_t, so we must convert! */
109 if (__get_user(sp, &frame->rs_uc.uc_stack.ss_sp)) 142 if (__get_user(sp, &frame->rs_uc.uc_stack.ss_sp))
110 goto badframe; 143 goto badframe;
111 st.ss_size = (long) sp; 144 st.ss_sp = (void *)(long) sp;
112 if (__get_user(st.ss_size, &frame->rs_uc.uc_stack.ss_size)) 145 if (__get_user(st.ss_size, &frame->rs_uc.uc_stack.ss_size))
113 goto badframe; 146 goto badframe;
114 if (__get_user(st.ss_flags, &frame->rs_uc.uc_stack.ss_flags)) 147 if (__get_user(st.ss_flags, &frame->rs_uc.uc_stack.ss_flags))
diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c
index 25472fcaf715..5e189862e523 100644
--- a/arch/mips/kernel/smp.c
+++ b/arch/mips/kernel/smp.c
@@ -29,6 +29,7 @@
29#include <linux/timex.h> 29#include <linux/timex.h>
30#include <linux/sched.h> 30#include <linux/sched.h>
31#include <linux/cpumask.h> 31#include <linux/cpumask.h>
32#include <linux/cpu.h>
32 33
33#include <asm/atomic.h> 34#include <asm/atomic.h>
34#include <asm/cpu.h> 35#include <asm/cpu.h>
@@ -424,6 +425,25 @@ void flush_tlb_one(unsigned long vaddr)
424 local_flush_tlb_one(vaddr); 425 local_flush_tlb_one(vaddr);
425} 426}
426 427
428static DEFINE_PER_CPU(struct cpu, cpu_devices);
429
430static int __init topology_init(void)
431{
432 int cpu;
433 int ret;
434
435 for_each_cpu(cpu) {
436 ret = register_cpu(&per_cpu(cpu_devices, cpu), cpu, NULL);
437 if (ret)
438 printk(KERN_WARNING "topology_init: register_cpu %d "
439 "failed (%d)\n", cpu, ret);
440 }
441
442 return 0;
443}
444
445subsys_initcall(topology_init);
446
427EXPORT_SYMBOL(flush_tlb_page); 447EXPORT_SYMBOL(flush_tlb_page);
428EXPORT_SYMBOL(flush_tlb_one); 448EXPORT_SYMBOL(flush_tlb_one);
429EXPORT_SYMBOL(cpu_data); 449EXPORT_SYMBOL(cpu_data);
diff --git a/arch/mips/kernel/smp_mt.c b/arch/mips/kernel/smp_mt.c
index 794a1c3de2a4..c930364830d0 100644
--- a/arch/mips/kernel/smp_mt.c
+++ b/arch/mips/kernel/smp_mt.c
@@ -68,6 +68,8 @@ void __init sanitize_tlb_entries(void)
68 68
69 set_c0_mvpcontrol(MVPCONTROL_VPC); 69 set_c0_mvpcontrol(MVPCONTROL_VPC);
70 70
71 back_to_back_c0_hazard();
72
71 /* Disable TLB sharing */ 73 /* Disable TLB sharing */
72 clear_c0_mvpcontrol(MVPCONTROL_STLB); 74 clear_c0_mvpcontrol(MVPCONTROL_STLB);
73 75
@@ -102,35 +104,6 @@ void __init sanitize_tlb_entries(void)
102 clear_c0_mvpcontrol(MVPCONTROL_VPC); 104 clear_c0_mvpcontrol(MVPCONTROL_VPC);
103} 105}
104 106
105#if 0
106/*
107 * Use c0_MVPConf0 to find out how many CPUs are available, setting up
108 * phys_cpu_present_map and the logical/physical mappings.
109 */
110void __init prom_build_cpu_map(void)
111{
112 int i, num, ncpus;
113
114 cpus_clear(phys_cpu_present_map);
115
116 /* assume we boot on cpu 0.... */
117 cpu_set(0, phys_cpu_present_map);
118 __cpu_number_map[0] = 0;
119 __cpu_logical_map[0] = 0;
120
121 if (cpu_has_mipsmt) {
122 ncpus = ((read_c0_mvpconf0() & (MVPCONF0_PVPE)) >> MVPCONF0_PVPE_SHIFT) + 1;
123 for (i=1, num=0; i< NR_CPUS && i<ncpus; i++) {
124 cpu_set(i, phys_cpu_present_map);
125 __cpu_number_map[i] = ++num;
126 __cpu_logical_map[num] = i;
127 }
128
129 printk(KERN_INFO "%i available secondary CPU(s)\n", num);
130 }
131}
132#endif
133
134static void ipi_resched_dispatch (struct pt_regs *regs) 107static void ipi_resched_dispatch (struct pt_regs *regs)
135{ 108{
136 do_IRQ(MIPS_CPU_IPI_RESCHED_IRQ, regs); 109 do_IRQ(MIPS_CPU_IPI_RESCHED_IRQ, regs);
@@ -222,6 +195,9 @@ void prom_prepare_cpus(unsigned int max_cpus)
222 195
223 /* set config to be the same as vpe0, particularly kseg0 coherency alg */ 196 /* set config to be the same as vpe0, particularly kseg0 coherency alg */
224 write_vpe_c0_config( read_c0_config()); 197 write_vpe_c0_config( read_c0_config());
198
199 /* Propagate Config7 */
200 write_vpe_c0_config7(read_c0_config7());
225 } 201 }
226 202
227 } 203 }
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index c9d2b5147ca3..005debbfbe84 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -3,7 +3,7 @@
3 * License. See the file "COPYING" in the main directory of this archive 3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details. 4 * for more details.
5 * 5 *
6 * Copyright (C) 1994 - 1999, 2000, 01 Ralf Baechle 6 * Copyright (C) 1994 - 1999, 2000, 01, 06 Ralf Baechle
7 * Copyright (C) 1995, 1996 Paul M. Antoine 7 * Copyright (C) 1995, 1996 Paul M. Antoine
8 * Copyright (C) 1998 Ulf Carlsson 8 * Copyright (C) 1998 Ulf Carlsson
9 * Copyright (C) 1999 Silicon Graphics, Inc. 9 * Copyright (C) 1999 Silicon Graphics, Inc.
@@ -548,6 +548,8 @@ asmlinkage void do_ov(struct pt_regs *regs)
548{ 548{
549 siginfo_t info; 549 siginfo_t info;
550 550
551 die_if_kernel("Integer overflow", regs);
552
551 info.si_code = FPE_INTOVF; 553 info.si_code = FPE_INTOVF;
552 info.si_signo = SIGFPE; 554 info.si_signo = SIGFPE;
553 info.si_errno = 0; 555 info.si_errno = 0;
diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c
index e51c38cef88e..1b71d91e8268 100644
--- a/arch/mips/mm/c-r4k.c
+++ b/arch/mips/mm/c-r4k.c
@@ -471,61 +471,29 @@ struct flush_icache_range_args {
471static inline void local_r4k_flush_icache_range(void *args) 471static inline void local_r4k_flush_icache_range(void *args)
472{ 472{
473 struct flush_icache_range_args *fir_args = args; 473 struct flush_icache_range_args *fir_args = args;
474 unsigned long dc_lsize = cpu_dcache_line_size();
475 unsigned long ic_lsize = cpu_icache_line_size();
476 unsigned long sc_lsize = cpu_scache_line_size();
477 unsigned long start = fir_args->start; 474 unsigned long start = fir_args->start;
478 unsigned long end = fir_args->end; 475 unsigned long end = fir_args->end;
479 unsigned long addr, aend;
480 476
481 if (!cpu_has_ic_fills_f_dc) { 477 if (!cpu_has_ic_fills_f_dc) {
482 if (end - start > dcache_size) { 478 if (end - start > dcache_size) {
483 r4k_blast_dcache(); 479 r4k_blast_dcache();
484 } else { 480 } else {
485 R4600_HIT_CACHEOP_WAR_IMPL; 481 R4600_HIT_CACHEOP_WAR_IMPL;
486 addr = start & ~(dc_lsize - 1); 482 protected_blast_dcache_range(start, end);
487 aend = (end - 1) & ~(dc_lsize - 1);
488
489 while (1) {
490 /* Hit_Writeback_Inv_D */
491 protected_writeback_dcache_line(addr);
492 if (addr == aend)
493 break;
494 addr += dc_lsize;
495 }
496 } 483 }
497 484
498 if (!cpu_icache_snoops_remote_store) { 485 if (!cpu_icache_snoops_remote_store) {
499 if (end - start > scache_size) { 486 if (end - start > scache_size)
500 r4k_blast_scache(); 487 r4k_blast_scache();
501 } else { 488 else
502 addr = start & ~(sc_lsize - 1); 489 protected_blast_scache_range(start, end);
503 aend = (end - 1) & ~(sc_lsize - 1);
504
505 while (1) {
506 /* Hit_Writeback_Inv_SD */
507 protected_writeback_scache_line(addr);
508 if (addr == aend)
509 break;
510 addr += sc_lsize;
511 }
512 }
513 } 490 }
514 } 491 }
515 492
516 if (end - start > icache_size) 493 if (end - start > icache_size)
517 r4k_blast_icache(); 494 r4k_blast_icache();
518 else { 495 else
519 addr = start & ~(ic_lsize - 1); 496 protected_blast_icache_range(start, end);
520 aend = (end - 1) & ~(ic_lsize - 1);
521 while (1) {
522 /* Hit_Invalidate_I */
523 protected_flush_icache_line(addr);
524 if (addr == aend)
525 break;
526 addr += ic_lsize;
527 }
528 }
529} 497}
530 498
531static void r4k_flush_icache_range(unsigned long start, unsigned long end) 499static void r4k_flush_icache_range(unsigned long start, unsigned long end)
@@ -619,27 +587,14 @@ static void r4k_flush_icache_page(struct vm_area_struct *vma,
619 587
620static void r4k_dma_cache_wback_inv(unsigned long addr, unsigned long size) 588static void r4k_dma_cache_wback_inv(unsigned long addr, unsigned long size)
621{ 589{
622 unsigned long end, a;
623
624 /* Catch bad driver code */ 590 /* Catch bad driver code */
625 BUG_ON(size == 0); 591 BUG_ON(size == 0);
626 592
627 if (cpu_has_subset_pcaches) { 593 if (cpu_has_subset_pcaches) {
628 unsigned long sc_lsize = cpu_scache_line_size(); 594 if (size >= scache_size)
629
630 if (size >= scache_size) {
631 r4k_blast_scache(); 595 r4k_blast_scache();
632 return; 596 else
633 } 597 blast_scache_range(addr, addr + size);
634
635 a = addr & ~(sc_lsize - 1);
636 end = (addr + size - 1) & ~(sc_lsize - 1);
637 while (1) {
638 flush_scache_line(a); /* Hit_Writeback_Inv_SD */
639 if (a == end)
640 break;
641 a += sc_lsize;
642 }
643 return; 598 return;
644 } 599 }
645 600
@@ -651,17 +606,8 @@ static void r4k_dma_cache_wback_inv(unsigned long addr, unsigned long size)
651 if (size >= dcache_size) { 606 if (size >= dcache_size) {
652 r4k_blast_dcache(); 607 r4k_blast_dcache();
653 } else { 608 } else {
654 unsigned long dc_lsize = cpu_dcache_line_size();
655
656 R4600_HIT_CACHEOP_WAR_IMPL; 609 R4600_HIT_CACHEOP_WAR_IMPL;
657 a = addr & ~(dc_lsize - 1); 610 blast_dcache_range(addr, addr + size);
658 end = (addr + size - 1) & ~(dc_lsize - 1);
659 while (1) {
660 flush_dcache_line(a); /* Hit_Writeback_Inv_D */
661 if (a == end)
662 break;
663 a += dc_lsize;
664 }
665 } 611 }
666 612
667 bc_wback_inv(addr, size); 613 bc_wback_inv(addr, size);
@@ -669,44 +615,22 @@ static void r4k_dma_cache_wback_inv(unsigned long addr, unsigned long size)
669 615
670static void r4k_dma_cache_inv(unsigned long addr, unsigned long size) 616static void r4k_dma_cache_inv(unsigned long addr, unsigned long size)
671{ 617{
672 unsigned long end, a;
673
674 /* Catch bad driver code */ 618 /* Catch bad driver code */
675 BUG_ON(size == 0); 619 BUG_ON(size == 0);
676 620
677 if (cpu_has_subset_pcaches) { 621 if (cpu_has_subset_pcaches) {
678 unsigned long sc_lsize = cpu_scache_line_size(); 622 if (size >= scache_size)
679
680 if (size >= scache_size) {
681 r4k_blast_scache(); 623 r4k_blast_scache();
682 return; 624 else
683 } 625 blast_scache_range(addr, addr + size);
684
685 a = addr & ~(sc_lsize - 1);
686 end = (addr + size - 1) & ~(sc_lsize - 1);
687 while (1) {
688 flush_scache_line(a); /* Hit_Writeback_Inv_SD */
689 if (a == end)
690 break;
691 a += sc_lsize;
692 }
693 return; 626 return;
694 } 627 }
695 628
696 if (size >= dcache_size) { 629 if (size >= dcache_size) {
697 r4k_blast_dcache(); 630 r4k_blast_dcache();
698 } else { 631 } else {
699 unsigned long dc_lsize = cpu_dcache_line_size();
700
701 R4600_HIT_CACHEOP_WAR_IMPL; 632 R4600_HIT_CACHEOP_WAR_IMPL;
702 a = addr & ~(dc_lsize - 1); 633 blast_dcache_range(addr, addr + size);
703 end = (addr + size - 1) & ~(dc_lsize - 1);
704 while (1) {
705 flush_dcache_line(a); /* Hit_Writeback_Inv_D */
706 if (a == end)
707 break;
708 a += dc_lsize;
709 }
710 } 634 }
711 635
712 bc_inv(addr, size); 636 bc_inv(addr, size);
diff --git a/arch/mips/mm/c-tx39.c b/arch/mips/mm/c-tx39.c
index 0a97a9434eba..7c572bea4a98 100644
--- a/arch/mips/mm/c-tx39.c
+++ b/arch/mips/mm/c-tx39.c
@@ -44,8 +44,6 @@ __asm__ __volatile__( \
44/* TX39H-style cache flush routines. */ 44/* TX39H-style cache flush routines. */
45static void tx39h_flush_icache_all(void) 45static void tx39h_flush_icache_all(void)
46{ 46{
47 unsigned long start = KSEG0;
48 unsigned long end = (start + icache_size);
49 unsigned long flags, config; 47 unsigned long flags, config;
50 48
51 /* disable icache (set ICE#) */ 49 /* disable icache (set ICE#) */
@@ -53,33 +51,18 @@ static void tx39h_flush_icache_all(void)
53 config = read_c0_conf(); 51 config = read_c0_conf();
54 write_c0_conf(config & ~TX39_CONF_ICE); 52 write_c0_conf(config & ~TX39_CONF_ICE);
55 TX39_STOP_STREAMING(); 53 TX39_STOP_STREAMING();
56 54 blast_icache16();
57 /* invalidate icache */
58 while (start < end) {
59 cache16_unroll32(start, Index_Invalidate_I);
60 start += 0x200;
61 }
62
63 write_c0_conf(config); 55 write_c0_conf(config);
64 local_irq_restore(flags); 56 local_irq_restore(flags);
65} 57}
66 58
67static void tx39h_dma_cache_wback_inv(unsigned long addr, unsigned long size) 59static void tx39h_dma_cache_wback_inv(unsigned long addr, unsigned long size)
68{ 60{
69 unsigned long end, a;
70 unsigned long dc_lsize = current_cpu_data.dcache.linesz;
71
72 /* Catch bad driver code */ 61 /* Catch bad driver code */
73 BUG_ON(size == 0); 62 BUG_ON(size == 0);
74 63
75 iob(); 64 iob();
76 a = addr & ~(dc_lsize - 1); 65 blast_inv_dcache_range(addr, addr + size);
77 end = (addr + size - 1) & ~(dc_lsize - 1);
78 while (1) {
79 invalidate_dcache_line(a); /* Hit_Invalidate_D */
80 if (a == end) break;
81 a += dc_lsize;
82 }
83} 66}
84 67
85 68
@@ -241,42 +224,21 @@ static void tx39_flush_data_cache_page(unsigned long addr)
241 224
242static void tx39_flush_icache_range(unsigned long start, unsigned long end) 225static void tx39_flush_icache_range(unsigned long start, unsigned long end)
243{ 226{
244 unsigned long dc_lsize = current_cpu_data.dcache.linesz;
245 unsigned long addr, aend;
246
247 if (end - start > dcache_size) 227 if (end - start > dcache_size)
248 tx39_blast_dcache(); 228 tx39_blast_dcache();
249 else { 229 else
250 addr = start & ~(dc_lsize - 1); 230 protected_blast_dcache_range(start, end);
251 aend = (end - 1) & ~(dc_lsize - 1);
252
253 while (1) {
254 /* Hit_Writeback_Inv_D */
255 protected_writeback_dcache_line(addr);
256 if (addr == aend)
257 break;
258 addr += dc_lsize;
259 }
260 }
261 231
262 if (end - start > icache_size) 232 if (end - start > icache_size)
263 tx39_blast_icache(); 233 tx39_blast_icache();
264 else { 234 else {
265 unsigned long flags, config; 235 unsigned long flags, config;
266 addr = start & ~(dc_lsize - 1);
267 aend = (end - 1) & ~(dc_lsize - 1);
268 /* disable icache (set ICE#) */ 236 /* disable icache (set ICE#) */
269 local_irq_save(flags); 237 local_irq_save(flags);
270 config = read_c0_conf(); 238 config = read_c0_conf();
271 write_c0_conf(config & ~TX39_CONF_ICE); 239 write_c0_conf(config & ~TX39_CONF_ICE);
272 TX39_STOP_STREAMING(); 240 TX39_STOP_STREAMING();
273 while (1) { 241 protected_blast_icache_range(start, end);
274 /* Hit_Invalidate_I */
275 protected_flush_icache_line(addr);
276 if (addr == aend)
277 break;
278 addr += dc_lsize;
279 }
280 write_c0_conf(config); 242 write_c0_conf(config);
281 local_irq_restore(flags); 243 local_irq_restore(flags);
282 } 244 }
@@ -311,7 +273,7 @@ static void tx39_flush_icache_page(struct vm_area_struct *vma, struct page *page
311 273
312static void tx39_dma_cache_wback_inv(unsigned long addr, unsigned long size) 274static void tx39_dma_cache_wback_inv(unsigned long addr, unsigned long size)
313{ 275{
314 unsigned long end, a; 276 unsigned long end;
315 277
316 if (((size | addr) & (PAGE_SIZE - 1)) == 0) { 278 if (((size | addr) & (PAGE_SIZE - 1)) == 0) {
317 end = addr + size; 279 end = addr + size;
@@ -322,20 +284,13 @@ static void tx39_dma_cache_wback_inv(unsigned long addr, unsigned long size)
322 } else if (size > dcache_size) { 284 } else if (size > dcache_size) {
323 tx39_blast_dcache(); 285 tx39_blast_dcache();
324 } else { 286 } else {
325 unsigned long dc_lsize = current_cpu_data.dcache.linesz; 287 blast_dcache_range(addr, addr + size);
326 a = addr & ~(dc_lsize - 1);
327 end = (addr + size - 1) & ~(dc_lsize - 1);
328 while (1) {
329 flush_dcache_line(a); /* Hit_Writeback_Inv_D */
330 if (a == end) break;
331 a += dc_lsize;
332 }
333 } 288 }
334} 289}
335 290
336static void tx39_dma_cache_inv(unsigned long addr, unsigned long size) 291static void tx39_dma_cache_inv(unsigned long addr, unsigned long size)
337{ 292{
338 unsigned long end, a; 293 unsigned long end;
339 294
340 if (((size | addr) & (PAGE_SIZE - 1)) == 0) { 295 if (((size | addr) & (PAGE_SIZE - 1)) == 0) {
341 end = addr + size; 296 end = addr + size;
@@ -346,14 +301,7 @@ static void tx39_dma_cache_inv(unsigned long addr, unsigned long size)
346 } else if (size > dcache_size) { 301 } else if (size > dcache_size) {
347 tx39_blast_dcache(); 302 tx39_blast_dcache();
348 } else { 303 } else {
349 unsigned long dc_lsize = current_cpu_data.dcache.linesz; 304 blast_inv_dcache_range(addr, addr + size);
350 a = addr & ~(dc_lsize - 1);
351 end = (addr + size - 1) & ~(dc_lsize - 1);
352 while (1) {
353 invalidate_dcache_line(a); /* Hit_Invalidate_D */
354 if (a == end) break;
355 a += dc_lsize;
356 }
357 } 305 }
358} 306}
359 307
diff --git a/arch/mips/mm/cex-sb1.S b/arch/mips/mm/cex-sb1.S
index 0e71580774ff..e54a62f2807c 100644
--- a/arch/mips/mm/cex-sb1.S
+++ b/arch/mips/mm/cex-sb1.S
@@ -64,7 +64,7 @@ LEAF(except_vec2_sb1)
64 sd k0,0x170($0) 64 sd k0,0x170($0)
65 sd k1,0x178($0) 65 sd k1,0x178($0)
66 66
67#if CONFIG_SB1_CEX_ALWAYS_FATAL 67#ifdef CONFIG_SB1_CEX_ALWAYS_FATAL
68 j handle_vec2_sb1 68 j handle_vec2_sb1
69 nop 69 nop
70#else 70#else
diff --git a/arch/mips/pmc-sierra/yosemite/smp.c b/arch/mips/pmc-sierra/yosemite/smp.c
index f17f575f58f0..7f8fda962190 100644
--- a/arch/mips/pmc-sierra/yosemite/smp.c
+++ b/arch/mips/pmc-sierra/yosemite/smp.c
@@ -94,7 +94,7 @@ void __init prom_prepare_cpus(unsigned int max_cpus)
94void prom_boot_secondary(int cpu, struct task_struct *idle) 94void prom_boot_secondary(int cpu, struct task_struct *idle)
95{ 95{
96 unsigned long gp = (unsigned long) task_thread_info(idle); 96 unsigned long gp = (unsigned long) task_thread_info(idle);
97 unsigned long sp = __KSTK_TOP(idle); 97 unsigned long sp = __KSTK_TOS(idle);
98 98
99 secondary_sp = sp; 99 secondary_sp = sp;
100 secondary_gp = gp; 100 secondary_gp = gp;
diff --git a/arch/mips/sibyte/Kconfig b/arch/mips/sibyte/Kconfig
index de46f62ac462..816aee7fcd25 100644
--- a/arch/mips/sibyte/Kconfig
+++ b/arch/mips/sibyte/Kconfig
@@ -102,11 +102,11 @@ config SIMULATION
102 Build a kernel suitable for running under the GDB simulator. 102 Build a kernel suitable for running under the GDB simulator.
103 Primarily adjusts the kernel's notion of time. 103 Primarily adjusts the kernel's notion of time.
104 104
105config CONFIG_SB1_CEX_ALWAYS_FATAL 105config SB1_CEX_ALWAYS_FATAL
106 bool "All cache exceptions considered fatal (no recovery attempted)" 106 bool "All cache exceptions considered fatal (no recovery attempted)"
107 depends on SIBYTE_SB1xxx_SOC 107 depends on SIBYTE_SB1xxx_SOC
108 108
109config CONFIG_SB1_CERR_STALL 109config SB1_CERR_STALL
110 bool "Stall (rather than panic) on fatal cache error" 110 bool "Stall (rather than panic) on fatal cache error"
111 depends on SIBYTE_SB1xxx_SOC 111 depends on SIBYTE_SB1xxx_SOC
112 112
diff --git a/arch/mips/sibyte/bcm1480/irq.c b/arch/mips/sibyte/bcm1480/irq.c
index b2a1ba5d23df..9cf7d713b13c 100644
--- a/arch/mips/sibyte/bcm1480/irq.c
+++ b/arch/mips/sibyte/bcm1480/irq.c
@@ -139,7 +139,7 @@ void bcm1480_unmask_irq(int cpu, int irq)
139#ifdef CONFIG_SMP 139#ifdef CONFIG_SMP
140static void bcm1480_set_affinity(unsigned int irq, cpumask_t mask) 140static void bcm1480_set_affinity(unsigned int irq, cpumask_t mask)
141{ 141{
142 int i = 0, old_cpu, cpu, int_on; 142 int i = 0, old_cpu, cpu, int_on, k;
143 u64 cur_ints; 143 u64 cur_ints;
144 irq_desc_t *desc = irq_desc + irq; 144 irq_desc_t *desc = irq_desc + irq;
145 unsigned long flags; 145 unsigned long flags;
@@ -165,7 +165,6 @@ static void bcm1480_set_affinity(unsigned int irq, cpumask_t mask)
165 irq_dirty -= BCM1480_NR_IRQS_HALF; 165 irq_dirty -= BCM1480_NR_IRQS_HALF;
166 } 166 }
167 167
168 int k;
169 for (k=0; k<2; k++) { /* Loop through high and low interrupt mask register */ 168 for (k=0; k<2; k++) { /* Loop through high and low interrupt mask register */
170 cur_ints = ____raw_readq(IOADDR(A_BCM1480_IMR_MAPPER(old_cpu) + R_BCM1480_IMR_INTERRUPT_MASK_H + (k*BCM1480_IMR_HL_SPACING))); 169 cur_ints = ____raw_readq(IOADDR(A_BCM1480_IMR_MAPPER(old_cpu) + R_BCM1480_IMR_INTERRUPT_MASK_H + (k*BCM1480_IMR_HL_SPACING)));
171 int_on = !(cur_ints & (((u64) 1) << irq_dirty)); 170 int_on = !(cur_ints & (((u64) 1) << irq_dirty));
@@ -216,6 +215,7 @@ static void ack_bcm1480_irq(unsigned int irq)
216{ 215{
217 u64 pending; 216 u64 pending;
218 unsigned int irq_dirty; 217 unsigned int irq_dirty;
218 int k;
219 219
220 /* 220 /*
221 * If the interrupt was an HT interrupt, now is the time to 221 * If the interrupt was an HT interrupt, now is the time to
@@ -227,7 +227,6 @@ static void ack_bcm1480_irq(unsigned int irq)
227 if ((irq_dirty >= BCM1480_NR_IRQS_HALF) && (irq_dirty <= BCM1480_NR_IRQS)) { 227 if ((irq_dirty >= BCM1480_NR_IRQS_HALF) && (irq_dirty <= BCM1480_NR_IRQS)) {
228 irq_dirty -= BCM1480_NR_IRQS_HALF; 228 irq_dirty -= BCM1480_NR_IRQS_HALF;
229 } 229 }
230 int k;
231 for (k=0; k<2; k++) { /* Loop through high and low LDT interrupts */ 230 for (k=0; k<2; k++) { /* Loop through high and low LDT interrupts */
232 pending = __raw_readq(IOADDR(A_BCM1480_IMR_REGISTER(bcm1480_irq_owner[irq], 231 pending = __raw_readq(IOADDR(A_BCM1480_IMR_REGISTER(bcm1480_irq_owner[irq],
233 R_BCM1480_IMR_LDT_INTERRUPT_H + (k*BCM1480_IMR_HL_SPACING)))); 232 R_BCM1480_IMR_LDT_INTERRUPT_H + (k*BCM1480_IMR_HL_SPACING))));