aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/avr32/kernel/ptrace.c4
-rw-r--r--arch/avr32/kernel/traps.c52
-rw-r--r--arch/avr32/mach-at32ap/at32ap7000.c2
-rw-r--r--arch/avr32/mm/cache.c3
-rw-r--r--arch/i386/kernel/acpi/earlyquirk.c7
-rw-r--r--arch/i386/kernel/smpboot.c16
-rw-r--r--arch/ia64/kernel/asm-offsets.c1
-rw-r--r--arch/ia64/kernel/efi.c10
-rw-r--r--arch/ia64/kernel/fsys.S105
-rw-r--r--arch/ia64/kernel/iosapic.c8
-rw-r--r--arch/ia64/kernel/setup.c2
-rw-r--r--arch/ia64/sn/kernel/io_acpi_init.c44
-rw-r--r--arch/ia64/sn/kernel/irq.c14
-rw-r--r--arch/ia64/sn/kernel/setup.c2
-rw-r--r--arch/mips/arc/init.c6
-rw-r--r--arch/mips/dec/prom/init.c3
-rw-r--r--arch/mips/kernel/linux32.c46
-rw-r--r--arch/mips/sibyte/Kconfig22
-rw-r--r--arch/mips/sibyte/sb1250/bcm1250_tbprof.c377
-rw-r--r--arch/mips/sibyte/sb1250/setup.c2
-rw-r--r--arch/powerpc/kernel/cputable.c16
-rw-r--r--arch/powerpc/kernel/prom_parse.c2
-rw-r--r--arch/powerpc/platforms/83xx/mpc834x_mds.c8
-rw-r--r--arch/powerpc/platforms/85xx/Kconfig1
-rw-r--r--arch/powerpc/platforms/celleb/scc_epci.c82
-rw-r--r--arch/powerpc/platforms/embedded6xx/Kconfig1
-rw-r--r--arch/powerpc/platforms/powermac/feature.c5
-rw-r--r--arch/powerpc/platforms/powermac/pci.c7
-rw-r--r--arch/powerpc/xmon/xmon.c2
-rw-r--r--arch/sh/boards/renesas/r7780rp/Makefile2
-rw-r--r--arch/sh/boards/renesas/r7780rp/io.c233
-rw-r--r--arch/sh/boards/renesas/r7780rp/setup.c24
-rw-r--r--arch/sh/boards/renesas/rts7751r2d/setup.c26
-rw-r--r--arch/sh/configs/rts7751r2d_defconfig110
-rw-r--r--arch/sh/kernel/entry-common.S2
-rw-r--r--arch/sh/kernel/io_generic.c3
-rw-r--r--arch/sh/kernel/process.c5
-rw-r--r--arch/sh/kernel/ptrace.c45
-rw-r--r--arch/sh/kernel/signal.c4
-rw-r--r--arch/sh/kernel/vmlinux.lds.S3
-rw-r--r--arch/sh/mm/cache-sh4.c12
-rw-r--r--arch/sh/mm/cache-sh7705.c9
-rw-r--r--arch/sh/mm/pg-sh4.c22
-rw-r--r--arch/sh/mm/pg-sh7705.c31
-rw-r--r--arch/sh/mm/tlb-flush.c55
-rw-r--r--arch/sh/mm/tlb-sh3.c63
-rw-r--r--arch/sh/mm/tlb-sh4.c68
-rw-r--r--arch/um/drivers/daemon_user.c17
-rw-r--r--arch/um/drivers/line.c6
-rw-r--r--arch/um/drivers/mcast_user.c10
-rw-r--r--arch/um/drivers/ssl.c2
-rw-r--r--arch/um/drivers/stdio_console.c2
-rw-r--r--arch/um/include/os.h3
-rw-r--r--arch/um/kernel/irq.c1
-rw-r--r--arch/um/os-Linux/process.c3
-rw-r--r--arch/um/os-Linux/signal.c5
-rw-r--r--arch/um/sys-x86_64/syscalls.c6
-rw-r--r--arch/x86_64/ia32/ptrace32.c1
-rw-r--r--arch/x86_64/kernel/early-quirks.c9
-rw-r--r--arch/x86_64/kernel/smpboot.c5
60 files changed, 976 insertions, 661 deletions
diff --git a/arch/avr32/kernel/ptrace.c b/arch/avr32/kernel/ptrace.c
index f2e81cd79002..6f4388f7c20b 100644
--- a/arch/avr32/kernel/ptrace.c
+++ b/arch/avr32/kernel/ptrace.c
@@ -313,7 +313,7 @@ asmlinkage void do_debug_priv(struct pt_regs *regs)
313 __mtdr(DBGREG_DC, dc); 313 __mtdr(DBGREG_DC, dc);
314 314
315 ti = current_thread_info(); 315 ti = current_thread_info();
316 ti->flags |= _TIF_BREAKPOINT; 316 set_ti_thread_flag(ti, TIF_BREAKPOINT);
317 317
318 /* The TLB miss handlers don't check thread flags */ 318 /* The TLB miss handlers don't check thread flags */
319 if ((regs->pc >= (unsigned long)&itlb_miss) 319 if ((regs->pc >= (unsigned long)&itlb_miss)
@@ -328,7 +328,7 @@ asmlinkage void do_debug_priv(struct pt_regs *regs)
328 * single step. 328 * single step.
329 */ 329 */
330 if ((regs->sr & MODE_MASK) != MODE_SUPERVISOR) 330 if ((regs->sr & MODE_MASK) != MODE_SUPERVISOR)
331 ti->flags |= TIF_SINGLE_STEP; 331 set_ti_thread_flag(ti, TIF_SINGLE_STEP);
332 } else { 332 } else {
333 panic("Unable to handle debug trap at pc = %08lx\n", 333 panic("Unable to handle debug trap at pc = %08lx\n",
334 regs->pc); 334 regs->pc);
diff --git a/arch/avr32/kernel/traps.c b/arch/avr32/kernel/traps.c
index 7e803f4d7a12..adc01a12d154 100644
--- a/arch/avr32/kernel/traps.c
+++ b/arch/avr32/kernel/traps.c
@@ -49,39 +49,45 @@ out:
49 return; 49 return;
50} 50}
51 51
52static inline int valid_stack_ptr(struct thread_info *tinfo, unsigned long p)
53{
54 return (p > (unsigned long)tinfo)
55 && (p < (unsigned long)tinfo + THREAD_SIZE - 3);
56}
57
52#ifdef CONFIG_FRAME_POINTER 58#ifdef CONFIG_FRAME_POINTER
53static inline void __show_trace(struct task_struct *tsk, unsigned long *sp, 59static inline void __show_trace(struct task_struct *tsk, unsigned long *sp,
54 struct pt_regs *regs) 60 struct pt_regs *regs)
55{ 61{
56 unsigned long __user *fp; 62 unsigned long lr, fp;
57 unsigned long __user *last_fp = NULL; 63 struct thread_info *tinfo;
58 64
59 if (regs) { 65 tinfo = (struct thread_info *)
60 fp = (unsigned long __user *)regs->r7; 66 ((unsigned long)sp & ~(THREAD_SIZE - 1));
61 } else if (tsk == current) { 67
62 register unsigned long __user *real_fp __asm__("r7"); 68 if (regs)
63 fp = real_fp; 69 fp = regs->r7;
64 } else { 70 else if (tsk == current)
65 fp = (unsigned long __user *)tsk->thread.cpu_context.r7; 71 asm("mov %0, r7" : "=r"(fp));
66 } 72 else
73 fp = tsk->thread.cpu_context.r7;
67 74
68 /* 75 /*
69 * Walk the stack until (a) we get an exception, (b) the frame 76 * Walk the stack as long as the frame pointer (a) is within
70 * pointer becomes zero, or (c) the frame pointer gets stuck 77 * the kernel stack of the task, and (b) it doesn't move
71 * at the same value. 78 * downwards.
72 */ 79 */
73 while (fp && fp != last_fp) { 80 while (valid_stack_ptr(tinfo, fp)) {
74 unsigned long lr, new_fp = 0; 81 unsigned long new_fp;
75
76 last_fp = fp;
77 if (__get_user(lr, fp))
78 break;
79 if (fp && __get_user(new_fp, fp + 1))
80 break;
81 fp = (unsigned long __user *)new_fp;
82 82
83 lr = *(unsigned long *)fp;
83 printk(" [<%08lx>] ", lr); 84 printk(" [<%08lx>] ", lr);
84 print_symbol("%s\n", lr); 85 print_symbol("%s\n", lr);
86
87 new_fp = *(unsigned long *)(fp + 4);
88 if (new_fp <= fp)
89 break;
90 fp = new_fp;
85 } 91 }
86 printk("\n"); 92 printk("\n");
87} 93}
diff --git a/arch/avr32/mach-at32ap/at32ap7000.c b/arch/avr32/mach-at32ap/at32ap7000.c
index bc235507c5c7..472703f90c22 100644
--- a/arch/avr32/mach-at32ap/at32ap7000.c
+++ b/arch/avr32/mach-at32ap/at32ap7000.c
@@ -752,7 +752,7 @@ static struct resource atmel_spi1_resource[] = {
752DEFINE_DEV(atmel_spi, 1); 752DEFINE_DEV(atmel_spi, 1);
753DEV_CLK(spi_clk, atmel_spi1, pba, 1); 753DEV_CLK(spi_clk, atmel_spi1, pba, 1);
754 754
755static void 755static void __init
756at32_spi_setup_slaves(unsigned int bus_num, struct spi_board_info *b, 756at32_spi_setup_slaves(unsigned int bus_num, struct spi_board_info *b,
757 unsigned int n, const u8 *pins) 757 unsigned int n, const u8 *pins)
758{ 758{
diff --git a/arch/avr32/mm/cache.c b/arch/avr32/mm/cache.c
index fb13f72e9a02..8f7b1c3cd0f9 100644
--- a/arch/avr32/mm/cache.c
+++ b/arch/avr32/mm/cache.c
@@ -121,9 +121,8 @@ void flush_icache_range(unsigned long start, unsigned long end)
121void flush_icache_page(struct vm_area_struct *vma, struct page *page) 121void flush_icache_page(struct vm_area_struct *vma, struct page *page)
122{ 122{
123 if (vma->vm_flags & VM_EXEC) { 123 if (vma->vm_flags & VM_EXEC) {
124 void *v = kmap(page); 124 void *v = page_address(page);
125 __flush_icache_range((unsigned long)v, (unsigned long)v + PAGE_SIZE); 125 __flush_icache_range((unsigned long)v, (unsigned long)v + PAGE_SIZE);
126 kunmap(v);
127 } 126 }
128} 127}
129 128
diff --git a/arch/i386/kernel/acpi/earlyquirk.c b/arch/i386/kernel/acpi/earlyquirk.c
index bf86f7662d8b..a7d22d9f3d7e 100644
--- a/arch/i386/kernel/acpi/earlyquirk.c
+++ b/arch/i386/kernel/acpi/earlyquirk.c
@@ -14,11 +14,8 @@
14 14
15#ifdef CONFIG_ACPI 15#ifdef CONFIG_ACPI
16 16
17static int nvidia_hpet_detected __initdata;
18
19static int __init nvidia_hpet_check(struct acpi_table_header *header) 17static int __init nvidia_hpet_check(struct acpi_table_header *header)
20{ 18{
21 nvidia_hpet_detected = 1;
22 return 0; 19 return 0;
23} 20}
24#endif 21#endif
@@ -29,9 +26,7 @@ static int __init check_bridge(int vendor, int device)
29 /* According to Nvidia all timer overrides are bogus unless HPET 26 /* According to Nvidia all timer overrides are bogus unless HPET
30 is enabled. */ 27 is enabled. */
31 if (!acpi_use_timer_override && vendor == PCI_VENDOR_ID_NVIDIA) { 28 if (!acpi_use_timer_override && vendor == PCI_VENDOR_ID_NVIDIA) {
32 nvidia_hpet_detected = 0; 29 if (acpi_table_parse(ACPI_SIG_HPET, nvidia_hpet_check)) {
33 acpi_table_parse(ACPI_SIG_HPET, nvidia_hpet_check);
34 if (nvidia_hpet_detected == 0) {
35 acpi_skip_timer_override = 1; 30 acpi_skip_timer_override = 1;
36 printk(KERN_INFO "Nvidia board " 31 printk(KERN_INFO "Nvidia board "
37 "detected. Ignoring ACPI " 32 "detected. Ignoring ACPI "
diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c
index 9b0dd2744c82..4ff55e675576 100644
--- a/arch/i386/kernel/smpboot.c
+++ b/arch/i386/kernel/smpboot.c
@@ -45,6 +45,7 @@
45#include <linux/notifier.h> 45#include <linux/notifier.h>
46#include <linux/cpu.h> 46#include <linux/cpu.h>
47#include <linux/percpu.h> 47#include <linux/percpu.h>
48#include <linux/nmi.h>
48 49
49#include <linux/delay.h> 50#include <linux/delay.h>
50#include <linux/mc146818rtc.h> 51#include <linux/mc146818rtc.h>
@@ -1278,8 +1279,9 @@ void __cpu_die(unsigned int cpu)
1278 1279
1279int __cpuinit __cpu_up(unsigned int cpu) 1280int __cpuinit __cpu_up(unsigned int cpu)
1280{ 1281{
1282 unsigned long flags;
1281#ifdef CONFIG_HOTPLUG_CPU 1283#ifdef CONFIG_HOTPLUG_CPU
1282 int ret=0; 1284 int ret = 0;
1283 1285
1284 /* 1286 /*
1285 * We do warm boot only on cpus that had booted earlier 1287 * We do warm boot only on cpus that had booted earlier
@@ -1297,23 +1299,25 @@ int __cpuinit __cpu_up(unsigned int cpu)
1297 /* In case one didn't come up */ 1299 /* In case one didn't come up */
1298 if (!cpu_isset(cpu, cpu_callin_map)) { 1300 if (!cpu_isset(cpu, cpu_callin_map)) {
1299 printk(KERN_DEBUG "skipping cpu%d, didn't come online\n", cpu); 1301 printk(KERN_DEBUG "skipping cpu%d, didn't come online\n", cpu);
1300 local_irq_enable();
1301 return -EIO; 1302 return -EIO;
1302 } 1303 }
1303 1304
1304 local_irq_enable();
1305
1306 per_cpu(cpu_state, cpu) = CPU_UP_PREPARE; 1305 per_cpu(cpu_state, cpu) = CPU_UP_PREPARE;
1307 /* Unleash the CPU! */ 1306 /* Unleash the CPU! */
1308 cpu_set(cpu, smp_commenced_mask); 1307 cpu_set(cpu, smp_commenced_mask);
1309 1308
1310 /* 1309 /*
1311 * Check TSC synchronization with the AP: 1310 * Check TSC synchronization with the AP (keep irqs disabled
1311 * while doing so):
1312 */ 1312 */
1313 local_irq_save(flags);
1313 check_tsc_sync_source(cpu); 1314 check_tsc_sync_source(cpu);
1315 local_irq_restore(flags);
1314 1316
1315 while (!cpu_isset(cpu, cpu_online_map)) 1317 while (!cpu_isset(cpu, cpu_online_map)) {
1316 cpu_relax(); 1318 cpu_relax();
1319 touch_nmi_watchdog();
1320 }
1317 1321
1318#ifdef CONFIG_X86_GENERICARCH 1322#ifdef CONFIG_X86_GENERICARCH
1319 if (num_online_cpus() > 8 && genapic == &apic_default) 1323 if (num_online_cpus() > 8 && genapic == &apic_default)
diff --git a/arch/ia64/kernel/asm-offsets.c b/arch/ia64/kernel/asm-offsets.c
index 75a2a2c12258..2236fabbb3c6 100644
--- a/arch/ia64/kernel/asm-offsets.c
+++ b/arch/ia64/kernel/asm-offsets.c
@@ -35,6 +35,7 @@ void foo(void)
35 BLANK(); 35 BLANK();
36 36
37 DEFINE(TI_FLAGS, offsetof(struct thread_info, flags)); 37 DEFINE(TI_FLAGS, offsetof(struct thread_info, flags));
38 DEFINE(TI_CPU, offsetof(struct thread_info, cpu));
38 DEFINE(TI_PRE_COUNT, offsetof(struct thread_info, preempt_count)); 39 DEFINE(TI_PRE_COUNT, offsetof(struct thread_info, preempt_count));
39 40
40 BLANK(); 41 BLANK();
diff --git a/arch/ia64/kernel/efi.c b/arch/ia64/kernel/efi.c
index 4061593e5b17..49b93682c752 100644
--- a/arch/ia64/kernel/efi.c
+++ b/arch/ia64/kernel/efi.c
@@ -971,6 +971,11 @@ efi_memmap_init(unsigned long *s, unsigned long *e)
971 if (!is_memory_available(md)) 971 if (!is_memory_available(md))
972 continue; 972 continue;
973 973
974#ifdef CONFIG_CRASH_DUMP
975 /* saved_max_pfn should ignore max_addr= command line arg */
976 if (saved_max_pfn < (efi_md_end(md) >> PAGE_SHIFT))
977 saved_max_pfn = (efi_md_end(md) >> PAGE_SHIFT);
978#endif
974 /* 979 /*
975 * Round ends inward to granule boundaries 980 * Round ends inward to granule boundaries
976 * Give trimmings to uncached allocator 981 * Give trimmings to uncached allocator
@@ -1010,11 +1015,6 @@ efi_memmap_init(unsigned long *s, unsigned long *e)
1010 } else 1015 } else
1011 ae = efi_md_end(md); 1016 ae = efi_md_end(md);
1012 1017
1013#ifdef CONFIG_CRASH_DUMP
1014 /* saved_max_pfn should ignore max_addr= command line arg */
1015 if (saved_max_pfn < (ae >> PAGE_SHIFT))
1016 saved_max_pfn = (ae >> PAGE_SHIFT);
1017#endif
1018 /* keep within max_addr= and min_addr= command line arg */ 1018 /* keep within max_addr= and min_addr= command line arg */
1019 as = max(as, min_addr); 1019 as = max(as, min_addr);
1020 ae = min(ae, max_addr); 1020 ae = min(ae, max_addr);
diff --git a/arch/ia64/kernel/fsys.S b/arch/ia64/kernel/fsys.S
index 7a05b1cb2ad5..8589e84a27c6 100644
--- a/arch/ia64/kernel/fsys.S
+++ b/arch/ia64/kernel/fsys.S
@@ -10,6 +10,8 @@
10 * probably broke it along the way... ;-) 10 * probably broke it along the way... ;-)
11 * 13-Jul-04 clameter Implement fsys_clock_gettime and revise fsys_gettimeofday to make 11 * 13-Jul-04 clameter Implement fsys_clock_gettime and revise fsys_gettimeofday to make
12 * it capable of using memory based clocks without falling back to C code. 12 * it capable of using memory based clocks without falling back to C code.
13 * 08-Feb-07 Fenghua Yu Implement fsys_getcpu.
14 *
13 */ 15 */
14 16
15#include <asm/asmmacro.h> 17#include <asm/asmmacro.h>
@@ -505,6 +507,59 @@ EX(.fail_efault, (p15) st8 [r34]=r3)
505#endif 507#endif
506END(fsys_rt_sigprocmask) 508END(fsys_rt_sigprocmask)
507 509
510/*
511 * fsys_getcpu doesn't use the third parameter in this implementation. It reads
512 * current_thread_info()->cpu and corresponding node in cpu_to_node_map.
513 */
514ENTRY(fsys_getcpu)
515 .prologue
516 .altrp b6
517 .body
518 ;;
519 add r2=TI_FLAGS+IA64_TASK_SIZE,r16
520 tnat.nz p6,p0 = r32 // guard against NaT argument
521 add r3=TI_CPU+IA64_TASK_SIZE,r16
522 ;;
523 ld4 r3=[r3] // M r3 = thread_info->cpu
524 ld4 r2=[r2] // M r2 = thread_info->flags
525(p6) br.cond.spnt.few .fail_einval // B
526 ;;
527 tnat.nz p7,p0 = r33 // I guard against NaT argument
528(p7) br.cond.spnt.few .fail_einval // B
529#ifdef CONFIG_NUMA
530 movl r17=cpu_to_node_map
531 ;;
532EX(.fail_efault, probe.w.fault r32, 3) // M This takes 5 cycles
533EX(.fail_efault, probe.w.fault r33, 3) // M This takes 5 cycles
534 shladd r18=r3,1,r17
535 ;;
536 ld2 r20=[r18] // r20 = cpu_to_node_map[cpu]
537 and r2 = TIF_ALLWORK_MASK,r2
538 ;;
539 cmp.ne p8,p0=0,r2
540(p8) br.spnt.many fsys_fallback_syscall
541 ;;
542 ;;
543EX(.fail_efault, st4 [r32] = r3)
544EX(.fail_efault, st2 [r33] = r20)
545 mov r8=0
546 ;;
547#else
548EX(.fail_efault, probe.w.fault r32, 3) // M This takes 5 cycles
549EX(.fail_efault, probe.w.fault r33, 3) // M This takes 5 cycles
550 and r2 = TIF_ALLWORK_MASK,r2
551 ;;
552 cmp.ne p8,p0=0,r2
553(p8) br.spnt.many fsys_fallback_syscall
554 ;;
555EX(.fail_efault, st4 [r32] = r3)
556EX(.fail_efault, st2 [r33] = r0)
557 mov r8=0
558 ;;
559#endif
560 FSYS_RETURN
561END(fsys_getcpu)
562
508ENTRY(fsys_fallback_syscall) 563ENTRY(fsys_fallback_syscall)
509 .prologue 564 .prologue
510 .altrp b6 565 .altrp b6
@@ -878,6 +933,56 @@ fsyscall_table:
878 data8 0 // timer_delete 933 data8 0 // timer_delete
879 data8 0 // clock_settime 934 data8 0 // clock_settime
880 data8 fsys_clock_gettime // clock_gettime 935 data8 fsys_clock_gettime // clock_gettime
936 data8 0 // clock_getres // 1255
937 data8 0 // clock_nanosleep
938 data8 0 // fstatfs64
939 data8 0 // statfs64
940 data8 0 // mbind
941 data8 0 // get_mempolicy // 1260
942 data8 0 // set_mempolicy
943 data8 0 // mq_open
944 data8 0 // mq_unlink
945 data8 0 // mq_timedsend
946 data8 0 // mq_timedreceive // 1265
947 data8 0 // mq_notify
948 data8 0 // mq_getsetattr
949 data8 0 // kexec_load
950 data8 0 // vserver
951 data8 0 // waitid // 1270
952 data8 0 // add_key
953 data8 0 // request_key
954 data8 0 // keyctl
955 data8 0 // ioprio_set
956 data8 0 // ioprio_get // 1275
957 data8 0 // move_pages
958 data8 0 // inotify_init
959 data8 0 // inotify_add_watch
960 data8 0 // inotify_rm_watch
961 data8 0 // migrate_pages // 1280
962 data8 0 // openat
963 data8 0 // mkdirat
964 data8 0 // mknodat
965 data8 0 // fchownat
966 data8 0 // futimesat // 1285
967 data8 0 // newfstatat
968 data8 0 // unlinkat
969 data8 0 // renameat
970 data8 0 // linkat
971 data8 0 // symlinkat // 1290
972 data8 0 // readlinkat
973 data8 0 // fchmodat
974 data8 0 // faccessat
975 data8 0
976 data8 0 // 1295
977 data8 0 // unshare
978 data8 0 // splice
979 data8 0 // set_robust_list
980 data8 0 // get_robust_list
981 data8 0 // sync_file_range // 1300
982 data8 0 // tee
983 data8 0 // vmsplice
984 data8 0
985 data8 fsys_getcpu // getcpu // 1304
881 986
882 // fill in zeros for the remaining entries 987 // fill in zeros for the remaining entries
883 .zero: 988 .zero:
diff --git a/arch/ia64/kernel/iosapic.c b/arch/ia64/kernel/iosapic.c
index d6aab40c6416..dcfbf3e7a9ef 100644
--- a/arch/ia64/kernel/iosapic.c
+++ b/arch/ia64/kernel/iosapic.c
@@ -446,7 +446,7 @@ iosapic_end_level_irq (unsigned int irq)
446#define iosapic_disable_level_irq mask_irq 446#define iosapic_disable_level_irq mask_irq
447#define iosapic_ack_level_irq nop 447#define iosapic_ack_level_irq nop
448 448
449struct hw_interrupt_type irq_type_iosapic_level = { 449struct irq_chip irq_type_iosapic_level = {
450 .name = "IO-SAPIC-level", 450 .name = "IO-SAPIC-level",
451 .startup = iosapic_startup_level_irq, 451 .startup = iosapic_startup_level_irq,
452 .shutdown = iosapic_shutdown_level_irq, 452 .shutdown = iosapic_shutdown_level_irq,
@@ -454,6 +454,8 @@ struct hw_interrupt_type irq_type_iosapic_level = {
454 .disable = iosapic_disable_level_irq, 454 .disable = iosapic_disable_level_irq,
455 .ack = iosapic_ack_level_irq, 455 .ack = iosapic_ack_level_irq,
456 .end = iosapic_end_level_irq, 456 .end = iosapic_end_level_irq,
457 .mask = mask_irq,
458 .unmask = unmask_irq,
457 .set_affinity = iosapic_set_affinity 459 .set_affinity = iosapic_set_affinity
458}; 460};
459 461
@@ -493,7 +495,7 @@ iosapic_ack_edge_irq (unsigned int irq)
493#define iosapic_disable_edge_irq nop 495#define iosapic_disable_edge_irq nop
494#define iosapic_end_edge_irq nop 496#define iosapic_end_edge_irq nop
495 497
496struct hw_interrupt_type irq_type_iosapic_edge = { 498struct irq_chip irq_type_iosapic_edge = {
497 .name = "IO-SAPIC-edge", 499 .name = "IO-SAPIC-edge",
498 .startup = iosapic_startup_edge_irq, 500 .startup = iosapic_startup_edge_irq,
499 .shutdown = iosapic_disable_edge_irq, 501 .shutdown = iosapic_disable_edge_irq,
@@ -501,6 +503,8 @@ struct hw_interrupt_type irq_type_iosapic_edge = {
501 .disable = iosapic_disable_edge_irq, 503 .disable = iosapic_disable_edge_irq,
502 .ack = iosapic_ack_edge_irq, 504 .ack = iosapic_ack_edge_irq,
503 .end = iosapic_end_edge_irq, 505 .end = iosapic_end_edge_irq,
506 .mask = mask_irq,
507 .unmask = unmask_irq,
504 .set_affinity = iosapic_set_affinity 508 .set_affinity = iosapic_set_affinity
505}; 509};
506 510
diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c
index 7d6fe65c93f4..339e8a54c2f1 100644
--- a/arch/ia64/kernel/setup.c
+++ b/arch/ia64/kernel/setup.c
@@ -91,8 +91,6 @@ static struct resource code_resource = {
91 .name = "Kernel code", 91 .name = "Kernel code",
92 .flags = IORESOURCE_BUSY | IORESOURCE_MEM 92 .flags = IORESOURCE_BUSY | IORESOURCE_MEM
93}; 93};
94extern void efi_initialize_iomem_resources(struct resource *,
95 struct resource *);
96extern char _text[], _end[], _etext[]; 94extern char _text[], _end[], _etext[];
97 95
98unsigned long ia64_max_cacheline_size; 96unsigned long ia64_max_cacheline_size;
diff --git a/arch/ia64/sn/kernel/io_acpi_init.c b/arch/ia64/sn/kernel/io_acpi_init.c
index 8c331ca6e5c9..c6216f454ffb 100644
--- a/arch/ia64/sn/kernel/io_acpi_init.c
+++ b/arch/ia64/sn/kernel/io_acpi_init.c
@@ -53,12 +53,15 @@ sal_ioif_init(u64 *result)
53} 53}
54 54
55/* 55/*
56 * sn_hubdev_add - The 'add' function of the acpi_sn_hubdev_driver. 56 * sn_acpi_hubdev_init() - This function is called by acpi_ns_get_device_callback()
57 * Called for every "SGIHUB" or "SGITIO" device defined 57 * for all SGIHUB and SGITIO acpi devices defined in the
58 * in the ACPI namespace. 58 * DSDT. It obtains the hubdev_info pointer from the
59 * ACPI vendor resource, which the PROM setup, and sets up the
60 * hubdev_info in the pda.
59 */ 61 */
60static int __init 62
61sn_hubdev_add(struct acpi_device *device) 63static acpi_status __init
64sn_acpi_hubdev_init(acpi_handle handle, u32 depth, void *context, void **ret)
62{ 65{
63 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; 66 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
64 u64 addr; 67 u64 addr;
@@ -67,18 +70,19 @@ sn_hubdev_add(struct acpi_device *device)
67 int i; 70 int i;
68 u64 nasid; 71 u64 nasid;
69 struct acpi_resource *resource; 72 struct acpi_resource *resource;
70 int ret = 0;
71 acpi_status status; 73 acpi_status status;
72 struct acpi_resource_vendor_typed *vendor; 74 struct acpi_resource_vendor_typed *vendor;
73 extern void sn_common_hubdev_init(struct hubdev_info *); 75 extern void sn_common_hubdev_init(struct hubdev_info *);
74 76
75 status = acpi_get_vendor_resource(device->handle, METHOD_NAME__CRS, 77 status = acpi_get_vendor_resource(handle, METHOD_NAME__CRS,
76 &sn_uuid, &buffer); 78 &sn_uuid, &buffer);
77 if (ACPI_FAILURE(status)) { 79 if (ACPI_FAILURE(status)) {
78 printk(KERN_ERR 80 printk(KERN_ERR
79 "sn_hubdev_add: acpi_get_vendor_resource() failed: %d\n", 81 "sn_acpi_hubdev_init: acpi_get_vendor_resource() "
80 status); 82 "(0x%x) failed for: ", status);
81 return 1; 83 acpi_ns_print_node_pathname(handle, NULL);
84 printk("\n");
85 return AE_OK; /* Continue walking namespace */
82 } 86 }
83 87
84 resource = buffer.pointer; 88 resource = buffer.pointer;
@@ -86,9 +90,10 @@ sn_hubdev_add(struct acpi_device *device)
86 if ((vendor->byte_length - sizeof(struct acpi_vendor_uuid)) != 90 if ((vendor->byte_length - sizeof(struct acpi_vendor_uuid)) !=
87 sizeof(struct hubdev_info *)) { 91 sizeof(struct hubdev_info *)) {
88 printk(KERN_ERR 92 printk(KERN_ERR
89 "sn_hubdev_add: Invalid vendor data length: %d\n", 93 "sn_acpi_hubdev_init: Invalid vendor data length: %d for: ",
90 vendor->byte_length); 94 vendor->byte_length);
91 ret = 1; 95 acpi_ns_print_node_pathname(handle, NULL);
96 printk("\n");
92 goto exit; 97 goto exit;
93 } 98 }
94 99
@@ -103,7 +108,7 @@ sn_hubdev_add(struct acpi_device *device)
103 108
104exit: 109exit:
105 kfree(buffer.pointer); 110 kfree(buffer.pointer);
106 return ret; 111 return AE_OK; /* Continue walking namespace */
107} 112}
108 113
109/* 114/*
@@ -441,14 +446,6 @@ sn_acpi_slot_fixup(struct pci_dev *dev)
441 446
442EXPORT_SYMBOL(sn_acpi_slot_fixup); 447EXPORT_SYMBOL(sn_acpi_slot_fixup);
443 448
444static struct acpi_driver acpi_sn_hubdev_driver = {
445 .name = "SGI HUBDEV Driver",
446 .ids = "SGIHUB,SGITIO",
447 .ops = {
448 .add = sn_hubdev_add,
449 },
450};
451
452 449
453/* 450/*
454 * sn_acpi_bus_fixup - Perform SN specific setup of software structs 451 * sn_acpi_bus_fixup - Perform SN specific setup of software structs
@@ -492,7 +489,10 @@ sn_io_acpi_init(void)
492 /* SN Altix does not follow the IOSAPIC IRQ routing model */ 489 /* SN Altix does not follow the IOSAPIC IRQ routing model */
493 acpi_irq_model = ACPI_IRQ_MODEL_PLATFORM; 490 acpi_irq_model = ACPI_IRQ_MODEL_PLATFORM;
494 491
495 acpi_bus_register_driver(&acpi_sn_hubdev_driver); 492 /* Setup hubdev_info for all SGIHUB/SGITIO devices */
493 acpi_get_devices("SGIHUB", sn_acpi_hubdev_init, NULL, NULL);
494 acpi_get_devices("SGITIO", sn_acpi_hubdev_init, NULL, NULL);
495
496 status = sal_ioif_init(&result); 496 status = sal_ioif_init(&result);
497 if (status || result) 497 if (status || result)
498 panic("sal_ioif_init failed: [%lx] %s\n", 498 panic("sal_ioif_init failed: [%lx] %s\n",
diff --git a/arch/ia64/sn/kernel/irq.c b/arch/ia64/sn/kernel/irq.c
index 8c5bee01eaa2..8d2a1bfbfe7c 100644
--- a/arch/ia64/sn/kernel/irq.c
+++ b/arch/ia64/sn/kernel/irq.c
@@ -205,7 +205,17 @@ static void sn_set_affinity_irq(unsigned int irq, cpumask_t mask)
205 (void)sn_retarget_vector(sn_irq_info, nasid, slice); 205 (void)sn_retarget_vector(sn_irq_info, nasid, slice);
206} 206}
207 207
208struct hw_interrupt_type irq_type_sn = { 208static void
209sn_mask_irq(unsigned int irq)
210{
211}
212
213static void
214sn_unmask_irq(unsigned int irq)
215{
216}
217
218struct irq_chip irq_type_sn = {
209 .name = "SN hub", 219 .name = "SN hub",
210 .startup = sn_startup_irq, 220 .startup = sn_startup_irq,
211 .shutdown = sn_shutdown_irq, 221 .shutdown = sn_shutdown_irq,
@@ -213,6 +223,8 @@ struct hw_interrupt_type irq_type_sn = {
213 .disable = sn_disable_irq, 223 .disable = sn_disable_irq,
214 .ack = sn_ack_irq, 224 .ack = sn_ack_irq,
215 .end = sn_end_irq, 225 .end = sn_end_irq,
226 .mask = sn_mask_irq,
227 .unmask = sn_unmask_irq,
216 .set_affinity = sn_set_affinity_irq 228 .set_affinity = sn_set_affinity_irq
217}; 229};
218 230
diff --git a/arch/ia64/sn/kernel/setup.c b/arch/ia64/sn/kernel/setup.c
index 8571e52c2efd..bd5373d593e1 100644
--- a/arch/ia64/sn/kernel/setup.c
+++ b/arch/ia64/sn/kernel/setup.c
@@ -397,6 +397,8 @@ void __init sn_setup(char **cmdline_p)
397 ia64_sn_set_os_feature(OSF_PCISEGMENT_ENABLE); 397 ia64_sn_set_os_feature(OSF_PCISEGMENT_ENABLE);
398 ia64_sn_set_os_feature(OSF_ACPI_ENABLE); 398 ia64_sn_set_os_feature(OSF_ACPI_ENABLE);
399 399
400 /* Load the new DSDT and SSDT tables into the global table list. */
401 acpi_table_init();
400 402
401#if defined(CONFIG_VT) && defined(CONFIG_VGA_CONSOLE) 403#if defined(CONFIG_VT) && defined(CONFIG_VGA_CONSOLE)
402 /* 404 /*
diff --git a/arch/mips/arc/init.c b/arch/mips/arc/init.c
index 0ac8f42d3752..e2f75b13312f 100644
--- a/arch/mips/arc/init.c
+++ b/arch/mips/arc/init.c
@@ -23,16 +23,16 @@ LONG *_prom_argv, *_prom_envp;
23void __init prom_init(void) 23void __init prom_init(void)
24{ 24{
25 PSYSTEM_PARAMETER_BLOCK pb = PROMBLOCK; 25 PSYSTEM_PARAMETER_BLOCK pb = PROMBLOCK;
26
26 romvec = ROMVECTOR; 27 romvec = ROMVECTOR;
27 ULONG cnt;
28 CHAR c;
29 28
30 prom_argc = fw_arg0; 29 prom_argc = fw_arg0;
31 _prom_argv = (LONG *) fw_arg1; 30 _prom_argv = (LONG *) fw_arg1;
32 _prom_envp = (LONG *) fw_arg2; 31 _prom_envp = (LONG *) fw_arg2;
33 32
34 if (pb->magic != 0x53435241) { 33 if (pb->magic != 0x53435241) {
35 printk(KERN_CRIT "Aieee, bad prom vector magic %08lx\n", pb->magic); 34 printk(KERN_CRIT "Aieee, bad prom vector magic %08lx\n",
35 (unsigned long) pb->magic);
36 while(1) 36 while(1)
37 ; 37 ;
38 } 38 }
diff --git a/arch/mips/dec/prom/init.c b/arch/mips/dec/prom/init.c
index bf2858071f1f..a217aafe59f6 100644
--- a/arch/mips/dec/prom/init.c
+++ b/arch/mips/dec/prom/init.c
@@ -103,9 +103,6 @@ void __init prom_init(void)
103 if (prom_is_rex(magic)) 103 if (prom_is_rex(magic))
104 rex_clear_cache(); 104 rex_clear_cache();
105 105
106 /* Register the early console. */
107 register_prom_console();
108
109 /* Were we compiled with the right CPU option? */ 106 /* Were we compiled with the right CPU option? */
110#if defined(CONFIG_CPU_R3000) 107#if defined(CONFIG_CPU_R3000)
111 if ((current_cpu_data.cputype == CPU_R4000SC) || 108 if ((current_cpu_data.cputype == CPU_R4000SC) ||
diff --git a/arch/mips/kernel/linux32.c b/arch/mips/kernel/linux32.c
index 30d433f14f93..1df544c1f966 100644
--- a/arch/mips/kernel/linux32.c
+++ b/arch/mips/kernel/linux32.c
@@ -564,49 +564,3 @@ _sys32_clone(nabi_no_regargs struct pt_regs regs)
564 return do_fork(clone_flags, newsp, &regs, 0, 564 return do_fork(clone_flags, newsp, &regs, 0,
565 parent_tidptr, child_tidptr); 565 parent_tidptr, child_tidptr);
566} 566}
567
568/*
569 * Implement the event wait interface for the eventpoll file. It is the kernel
570 * part of the user space epoll_pwait(2).
571 */
572asmlinkage long compat_sys_epoll_pwait(int epfd,
573 struct epoll_event __user *events, int maxevents, int timeout,
574 const compat_sigset_t __user *sigmask, size_t sigsetsize)
575{
576 int error;
577 sigset_t ksigmask, sigsaved;
578
579 /*
580 * If the caller wants a certain signal mask to be set during the wait,
581 * we apply it here.
582 */
583 if (sigmask) {
584 if (sigsetsize != sizeof(sigset_t))
585 return -EINVAL;
586 if (!access_ok(VERIFY_READ, sigmask, sizeof(ksigmask)))
587 return -EFAULT;
588 if (__copy_conv_sigset_from_user(&ksigmask, sigmask))
589 return -EFAULT;
590 sigdelsetmask(&ksigmask, sigmask(SIGKILL) | sigmask(SIGSTOP));
591 sigprocmask(SIG_SETMASK, &ksigmask, &sigsaved);
592 }
593
594 error = sys_epoll_wait(epfd, events, maxevents, timeout);
595
596 /*
597 * If we changed the signal mask, we need to restore the original one.
598 * In case we've got a signal while waiting, we do not restore the
599 * signal mask yet, and we allow do_signal() to deliver the signal on
600 * the way back to userspace, before the signal mask is restored.
601 */
602 if (sigmask) {
603 if (error == -EINTR) {
604 memcpy(&current->saved_sigmask, &sigsaved,
605 sizeof(sigsaved));
606 set_thread_flag(TIF_RESTORE_SIGMASK);
607 } else
608 sigprocmask(SIG_SETMASK, &sigsaved, NULL);
609 }
610
611 return error;
612}
diff --git a/arch/mips/sibyte/Kconfig b/arch/mips/sibyte/Kconfig
index 67dac6204b6d..bdf24a7b5494 100644
--- a/arch/mips/sibyte/Kconfig
+++ b/arch/mips/sibyte/Kconfig
@@ -1,31 +1,35 @@
1config SIBYTE_SB1250 1config SIBYTE_SB1250
2 bool 2 bool
3 select HW_HAS_PCI 3 select HW_HAS_PCI
4 select SIBYTE_HAS_LDT 4 select SIBYTE_ENABLE_LDT_IF_PCI
5 select SIBYTE_SB1xxx_SOC 5 select SIBYTE_SB1xxx_SOC
6 select SYS_SUPPORTS_SMP 6 select SYS_SUPPORTS_SMP
7 7
8config SIBYTE_BCM1120 8config SIBYTE_BCM1120
9 bool 9 bool
10 select SIBYTE_BCM112X 10 select SIBYTE_BCM112X
11 select SIBYTE_HAS_ZBUS_PROFILING
11 select SIBYTE_SB1xxx_SOC 12 select SIBYTE_SB1xxx_SOC
12 13
13config SIBYTE_BCM1125 14config SIBYTE_BCM1125
14 bool 15 bool
15 select HW_HAS_PCI 16 select HW_HAS_PCI
16 select SIBYTE_BCM112X 17 select SIBYTE_BCM112X
18 select SIBYTE_HAS_ZBUS_PROFILING
17 select SIBYTE_SB1xxx_SOC 19 select SIBYTE_SB1xxx_SOC
18 20
19config SIBYTE_BCM1125H 21config SIBYTE_BCM1125H
20 bool 22 bool
21 select HW_HAS_PCI 23 select HW_HAS_PCI
22 select SIBYTE_BCM112X 24 select SIBYTE_BCM112X
23 select SIBYTE_HAS_LDT 25 select SIBYTE_ENABLE_LDT_IF_PCI
26 select SIBYTE_HAS_ZBUS_PROFILING
24 select SIBYTE_SB1xxx_SOC 27 select SIBYTE_SB1xxx_SOC
25 28
26config SIBYTE_BCM112X 29config SIBYTE_BCM112X
27 bool 30 bool
28 select SIBYTE_SB1xxx_SOC 31 select SIBYTE_SB1xxx_SOC
32 select SIBYTE_HAS_ZBUS_PROFILING
29 33
30config SIBYTE_BCM1x80 34config SIBYTE_BCM1x80
31 bool 35 bool
@@ -37,6 +41,7 @@ config SIBYTE_BCM1x55
37 bool 41 bool
38 select HW_HAS_PCI 42 select HW_HAS_PCI
39 select SIBYTE_SB1xxx_SOC 43 select SIBYTE_SB1xxx_SOC
44 select SIBYTE_HAS_ZBUS_PROFILING
40 select SYS_SUPPORTS_SMP 45 select SYS_SUPPORTS_SMP
41 46
42config SIBYTE_SB1xxx_SOC 47config SIBYTE_SB1xxx_SOC
@@ -95,8 +100,10 @@ config CPU_SB1_PASS_2
95 100
96config SIBYTE_HAS_LDT 101config SIBYTE_HAS_LDT
97 bool 102 bool
98 depends on PCI && (SIBYTE_SB1250 || SIBYTE_BCM1125H) 103
99 default y 104config SIBYTE_ENABLE_LDT_IF_PCI
105 bool
106 select SIBYTE_HAS_LDT if PCI
100 107
101config SIMULATION 108config SIMULATION
102 bool "Running under simulation" 109 bool "Running under simulation"
@@ -162,5 +169,8 @@ config SIBYTE_SB1250_PROF
162 depends on SIBYTE_SB1xxx_SOC 169 depends on SIBYTE_SB1xxx_SOC
163 170
164config SIBYTE_TBPROF 171config SIBYTE_TBPROF
165 bool "Support for ZBbus profiling" 172 tristate "Support for ZBbus profiling"
166 depends on SIBYTE_SB1xxx_SOC 173 depends on SIBYTE_HAS_ZBUS_PROFILING
174
175config SIBYTE_HAS_ZBUS_PROFILING
176 bool
diff --git a/arch/mips/sibyte/sb1250/bcm1250_tbprof.c b/arch/mips/sibyte/sb1250/bcm1250_tbprof.c
index 212547c57310..ea0ca131a3cf 100644
--- a/arch/mips/sibyte/sb1250/bcm1250_tbprof.c
+++ b/arch/mips/sibyte/sb1250/bcm1250_tbprof.c
@@ -1,6 +1,4 @@
1/* 1/*
2 * Copyright (C) 2001, 2002, 2003 Broadcom Corporation
3 *
4 * This program is free software; you can redistribute it and/or 2 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License 3 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2 4 * as published by the Free Software Foundation; either version 2
@@ -14,10 +12,16 @@
14 * You should have received a copy of the GNU General Public License 12 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software 13 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 14 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
15 *
16 * Copyright (C) 2001, 2002, 2003 Broadcom Corporation
17 * Copyright (C) 2007 Ralf Baechle <ralf@linux-mips.org>
18 * Copyright (C) 2007 MIPS Technologies, Inc.
19 * written by Ralf Baechle <ralf@linux-mips.org>
17 */ 20 */
18 21
19#define SBPROF_TB_DEBUG 0 22#undef DEBUG
20 23
24#include <linux/device.h>
21#include <linux/module.h> 25#include <linux/module.h>
22#include <linux/kernel.h> 26#include <linux/kernel.h>
23#include <linux/types.h> 27#include <linux/types.h>
@@ -27,24 +31,98 @@
27#include <linux/vmalloc.h> 31#include <linux/vmalloc.h>
28#include <linux/fs.h> 32#include <linux/fs.h>
29#include <linux/errno.h> 33#include <linux/errno.h>
30#include <linux/reboot.h> 34#include <linux/types.h>
31#include <linux/smp_lock.h>
32#include <linux/wait.h> 35#include <linux/wait.h>
33#include <asm/uaccess.h> 36
34#include <asm/io.h> 37#include <asm/io.h>
35#include <asm/sibyte/sb1250.h> 38#include <asm/sibyte/sb1250.h>
36#include <asm/sibyte/sb1250_regs.h> 39#include <asm/sibyte/sb1250_regs.h>
37#include <asm/sibyte/sb1250_scd.h> 40#include <asm/sibyte/sb1250_scd.h>
38#include <asm/sibyte/sb1250_int.h> 41#include <asm/sibyte/sb1250_int.h>
39#include <asm/sibyte/trace_prof.h> 42#include <asm/system.h>
43#include <asm/uaccess.h>
40 44
41#define DEVNAME "bcm1250_tbprof" 45#define SBPROF_TB_MAJOR 240
46
47typedef u64 tb_sample_t[6*256];
48
49enum open_status {
50 SB_CLOSED,
51 SB_OPENING,
52 SB_OPEN
53};
54
55struct sbprof_tb {
56 wait_queue_head_t tb_sync;
57 wait_queue_head_t tb_read;
58 struct mutex lock;
59 enum open_status open;
60 tb_sample_t *sbprof_tbbuf;
61 int next_tb_sample;
62
63 volatile int tb_enable;
64 volatile int tb_armed;
65
66};
42 67
43static struct sbprof_tb sbp; 68static struct sbprof_tb sbp;
44 69
70#define MAX_SAMPLE_BYTES (24*1024*1024)
71#define MAX_TBSAMPLE_BYTES (12*1024*1024)
72
73#define MAX_SAMPLES (MAX_SAMPLE_BYTES/sizeof(u_int32_t))
74#define TB_SAMPLE_SIZE (sizeof(tb_sample_t))
75#define MAX_TB_SAMPLES (MAX_TBSAMPLE_BYTES/TB_SAMPLE_SIZE)
76
77/* ioctls */
78#define SBPROF_ZBSTART _IOW('s', 0, int)
79#define SBPROF_ZBSTOP _IOW('s', 1, int)
80#define SBPROF_ZBWAITFULL _IOW('s', 2, int)
81
82/*
83 * Routines for using 40-bit SCD cycle counter
84 *
85 * Client responsible for either handling interrupts or making sure
86 * the cycles counter never saturates, e.g., by doing
87 * zclk_timer_init(0) at least every 2^40 - 1 ZCLKs.
88 */
89
90/*
91 * Configures SCD counter 0 to count ZCLKs starting from val;
92 * Configures SCD counters1,2,3 to count nothing.
93 * Must not be called while gathering ZBbus profiles.
94 */
95
96#define zclk_timer_init(val) \
97 __asm__ __volatile__ (".set push;" \
98 ".set mips64;" \
99 "la $8, 0xb00204c0;" /* SCD perf_cnt_cfg */ \
100 "sd %0, 0x10($8);" /* write val to counter0 */ \
101 "sd %1, 0($8);" /* config counter0 for zclks*/ \
102 ".set pop" \
103 : /* no outputs */ \
104 /* enable, counter0 */ \
105 : /* inputs */ "r"(val), "r" ((1ULL << 33) | 1ULL) \
106 : /* modifies */ "$8" )
107
108
109/* Reads SCD counter 0 and puts result in value
110 unsigned long long val; */
111#define zclk_get(val) \
112 __asm__ __volatile__ (".set push;" \
113 ".set mips64;" \
114 "la $8, 0xb00204c0;" /* SCD perf_cnt_cfg */ \
115 "ld %0, 0x10($8);" /* write val to counter0 */ \
116 ".set pop" \
117 : /* outputs */ "=r"(val) \
118 : /* inputs */ \
119 : /* modifies */ "$8" )
120
121#define DEVNAME "bcm1250_tbprof"
122
45#define TB_FULL (sbp.next_tb_sample == MAX_TB_SAMPLES) 123#define TB_FULL (sbp.next_tb_sample == MAX_TB_SAMPLES)
46 124
47/************************************************************************ 125/*
48 * Support for ZBbus sampling using the trace buffer 126 * Support for ZBbus sampling using the trace buffer
49 * 127 *
50 * We use the SCD performance counter interrupt, caused by a Zclk counter 128 * We use the SCD performance counter interrupt, caused by a Zclk counter
@@ -54,30 +132,36 @@ static struct sbprof_tb sbp;
54 * overflow. 132 * overflow.
55 * 133 *
56 * We map the interrupt for trace_buffer_freeze to handle it on CPU 0. 134 * We map the interrupt for trace_buffer_freeze to handle it on CPU 0.
57 * 135 */
58 ************************************************************************/
59 136
60static u_int64_t tb_period; 137static u64 tb_period;
61 138
62static void arm_tb(void) 139static void arm_tb(void)
63{ 140{
64 u_int64_t scdperfcnt; 141 u64 scdperfcnt;
65 u_int64_t next = (1ULL << 40) - tb_period; 142 u64 next = (1ULL << 40) - tb_period;
66 u_int64_t tb_options = M_SCD_TRACE_CFG_FREEZE_FULL; 143 u64 tb_options = M_SCD_TRACE_CFG_FREEZE_FULL;
67 /* Generate an SCD_PERFCNT interrupt in TB_PERIOD Zclks to 144
68 trigger start of trace. XXX vary sampling period */ 145 /*
146 * Generate an SCD_PERFCNT interrupt in TB_PERIOD Zclks to trigger
147 *start of trace. XXX vary sampling period
148 */
69 __raw_writeq(0, IOADDR(A_SCD_PERF_CNT_1)); 149 __raw_writeq(0, IOADDR(A_SCD_PERF_CNT_1));
70 scdperfcnt = __raw_readq(IOADDR(A_SCD_PERF_CNT_CFG)); 150 scdperfcnt = __raw_readq(IOADDR(A_SCD_PERF_CNT_CFG));
71 /* Unfortunately, in Pass 2 we must clear all counters to knock down 151
72 a previous interrupt request. This means that bus profiling 152 /*
73 requires ALL of the SCD perf counters. */ 153 * Unfortunately, in Pass 2 we must clear all counters to knock down a
154 * previous interrupt request. This means that bus profiling requires
155 * ALL of the SCD perf counters.
156 */
74 __raw_writeq((scdperfcnt & ~M_SPC_CFG_SRC1) | 157 __raw_writeq((scdperfcnt & ~M_SPC_CFG_SRC1) |
75 // keep counters 0,2,3 as is 158 /* keep counters 0,2,3 as is */
76 M_SPC_CFG_ENABLE | // enable counting 159 M_SPC_CFG_ENABLE | /* enable counting */
77 M_SPC_CFG_CLEAR | // clear all counters 160 M_SPC_CFG_CLEAR | /* clear all counters */
78 V_SPC_CFG_SRC1(1), // counter 1 counts cycles 161 V_SPC_CFG_SRC1(1), /* counter 1 counts cycles */
79 IOADDR(A_SCD_PERF_CNT_CFG)); 162 IOADDR(A_SCD_PERF_CNT_CFG));
80 __raw_writeq(next, IOADDR(A_SCD_PERF_CNT_1)); 163 __raw_writeq(next, IOADDR(A_SCD_PERF_CNT_1));
164
81 /* Reset the trace buffer */ 165 /* Reset the trace buffer */
82 __raw_writeq(M_SCD_TRACE_CFG_RESET, IOADDR(A_SCD_TRACE_CFG)); 166 __raw_writeq(M_SCD_TRACE_CFG_RESET, IOADDR(A_SCD_TRACE_CFG));
83#if 0 && defined(M_SCD_TRACE_CFG_FORCECNT) 167#if 0 && defined(M_SCD_TRACE_CFG_FORCECNT)
@@ -91,43 +175,45 @@ static void arm_tb(void)
91static irqreturn_t sbprof_tb_intr(int irq, void *dev_id) 175static irqreturn_t sbprof_tb_intr(int irq, void *dev_id)
92{ 176{
93 int i; 177 int i;
94 DBG(printk(DEVNAME ": tb_intr\n")); 178
179 pr_debug(DEVNAME ": tb_intr\n");
180
95 if (sbp.next_tb_sample < MAX_TB_SAMPLES) { 181 if (sbp.next_tb_sample < MAX_TB_SAMPLES) {
96 /* XXX should use XKPHYS to make writes bypass L2 */ 182 /* XXX should use XKPHYS to make writes bypass L2 */
97 u_int64_t *p = sbp.sbprof_tbbuf[sbp.next_tb_sample++]; 183 u64 *p = sbp.sbprof_tbbuf[sbp.next_tb_sample++];
98 /* Read out trace */ 184 /* Read out trace */
99 __raw_writeq(M_SCD_TRACE_CFG_START_READ, 185 __raw_writeq(M_SCD_TRACE_CFG_START_READ,
100 IOADDR(A_SCD_TRACE_CFG)); 186 IOADDR(A_SCD_TRACE_CFG));
101 __asm__ __volatile__ ("sync" : : : "memory"); 187 __asm__ __volatile__ ("sync" : : : "memory");
102 /* Loop runs backwards because bundles are read out in reverse order */ 188 /* Loop runs backwards because bundles are read out in reverse order */
103 for (i = 256 * 6; i > 0; i -= 6) { 189 for (i = 256 * 6; i > 0; i -= 6) {
104 // Subscripts decrease to put bundle in the order 190 /* Subscripts decrease to put bundle in the order */
105 // t0 lo, t0 hi, t1 lo, t1 hi, t2 lo, t2 hi 191 /* t0 lo, t0 hi, t1 lo, t1 hi, t2 lo, t2 hi */
106 p[i - 1] = __raw_readq(IOADDR(A_SCD_TRACE_READ)); 192 p[i - 1] = __raw_readq(IOADDR(A_SCD_TRACE_READ));
107 // read t2 hi 193 /* read t2 hi */
108 p[i - 2] = __raw_readq(IOADDR(A_SCD_TRACE_READ)); 194 p[i - 2] = __raw_readq(IOADDR(A_SCD_TRACE_READ));
109 // read t2 lo 195 /* read t2 lo */
110 p[i - 3] = __raw_readq(IOADDR(A_SCD_TRACE_READ)); 196 p[i - 3] = __raw_readq(IOADDR(A_SCD_TRACE_READ));
111 // read t1 hi 197 /* read t1 hi */
112 p[i - 4] = __raw_readq(IOADDR(A_SCD_TRACE_READ)); 198 p[i - 4] = __raw_readq(IOADDR(A_SCD_TRACE_READ));
113 // read t1 lo 199 /* read t1 lo */
114 p[i - 5] = __raw_readq(IOADDR(A_SCD_TRACE_READ)); 200 p[i - 5] = __raw_readq(IOADDR(A_SCD_TRACE_READ));
115 // read t0 hi 201 /* read t0 hi */
116 p[i - 6] = __raw_readq(IOADDR(A_SCD_TRACE_READ)); 202 p[i - 6] = __raw_readq(IOADDR(A_SCD_TRACE_READ));
117 // read t0 lo 203 /* read t0 lo */
118 } 204 }
119 if (!sbp.tb_enable) { 205 if (!sbp.tb_enable) {
120 DBG(printk(DEVNAME ": tb_intr shutdown\n")); 206 pr_debug(DEVNAME ": tb_intr shutdown\n");
121 __raw_writeq(M_SCD_TRACE_CFG_RESET, 207 __raw_writeq(M_SCD_TRACE_CFG_RESET,
122 IOADDR(A_SCD_TRACE_CFG)); 208 IOADDR(A_SCD_TRACE_CFG));
123 sbp.tb_armed = 0; 209 sbp.tb_armed = 0;
124 wake_up(&sbp.tb_sync); 210 wake_up(&sbp.tb_sync);
125 } else { 211 } else {
126 arm_tb(); // knock down current interrupt and get another one later 212 arm_tb(); /* knock down current interrupt and get another one later */
127 } 213 }
128 } else { 214 } else {
129 /* No more trace buffer samples */ 215 /* No more trace buffer samples */
130 DBG(printk(DEVNAME ": tb_intr full\n")); 216 pr_debug(DEVNAME ": tb_intr full\n");
131 __raw_writeq(M_SCD_TRACE_CFG_RESET, IOADDR(A_SCD_TRACE_CFG)); 217 __raw_writeq(M_SCD_TRACE_CFG_RESET, IOADDR(A_SCD_TRACE_CFG));
132 sbp.tb_armed = 0; 218 sbp.tb_armed = 0;
133 if (!sbp.tb_enable) { 219 if (!sbp.tb_enable) {
@@ -135,6 +221,7 @@ static irqreturn_t sbprof_tb_intr(int irq, void *dev_id)
135 } 221 }
136 wake_up(&sbp.tb_read); 222 wake_up(&sbp.tb_read);
137 } 223 }
224
138 return IRQ_HANDLED; 225 return IRQ_HANDLED;
139} 226}
140 227
@@ -144,23 +231,30 @@ static irqreturn_t sbprof_pc_intr(int irq, void *dev_id)
144 return IRQ_NONE; 231 return IRQ_NONE;
145} 232}
146 233
147int sbprof_zbprof_start(struct file *filp) 234/*
235 * Requires: Already called zclk_timer_init with a value that won't
236 * saturate 40 bits. No subsequent use of SCD performance counters
237 * or trace buffer.
238 */
239
240static int sbprof_zbprof_start(struct file *filp)
148{ 241{
149 u_int64_t scdperfcnt; 242 u64 scdperfcnt;
243 int err;
150 244
151 if (sbp.tb_enable) 245 if (xchg(&sbp.tb_enable, 1))
152 return -EBUSY; 246 return -EBUSY;
153 247
154 DBG(printk(DEVNAME ": starting\n")); 248 pr_debug(DEVNAME ": starting\n");
155 249
156 sbp.tb_enable = 1;
157 sbp.next_tb_sample = 0; 250 sbp.next_tb_sample = 0;
158 filp->f_pos = 0; 251 filp->f_pos = 0;
159 252
160 if (request_irq 253 err = request_irq(K_INT_TRACE_FREEZE, sbprof_tb_intr, 0,
161 (K_INT_TRACE_FREEZE, sbprof_tb_intr, 0, DEVNAME " trace freeze", &sbp)) { 254 DEVNAME " trace freeze", &sbp);
255 if (err)
162 return -EBUSY; 256 return -EBUSY;
163 } 257
164 /* Make sure there isn't a perf-cnt interrupt waiting */ 258 /* Make sure there isn't a perf-cnt interrupt waiting */
165 scdperfcnt = __raw_readq(IOADDR(A_SCD_PERF_CNT_CFG)); 259 scdperfcnt = __raw_readq(IOADDR(A_SCD_PERF_CNT_CFG));
166 /* Disable and clear counters, override SRC_1 */ 260 /* Disable and clear counters, override SRC_1 */
@@ -168,18 +262,21 @@ int sbprof_zbprof_start(struct file *filp)
168 M_SPC_CFG_ENABLE | M_SPC_CFG_CLEAR | V_SPC_CFG_SRC1(1), 262 M_SPC_CFG_ENABLE | M_SPC_CFG_CLEAR | V_SPC_CFG_SRC1(1),
169 IOADDR(A_SCD_PERF_CNT_CFG)); 263 IOADDR(A_SCD_PERF_CNT_CFG));
170 264
171 /* We grab this interrupt to prevent others from trying to use 265 /*
172 it, even though we don't want to service the interrupts 266 * We grab this interrupt to prevent others from trying to use it, even
173 (they only feed into the trace-on-interrupt mechanism) */ 267 * though we don't want to service the interrupts (they only feed into
174 if (request_irq 268 * the trace-on-interrupt mechanism)
175 (K_INT_PERF_CNT, sbprof_pc_intr, 0, DEVNAME " scd perfcnt", &sbp)) { 269 */
176 free_irq(K_INT_TRACE_FREEZE, &sbp); 270 err = request_irq(K_INT_PERF_CNT, sbprof_pc_intr, 0,
177 return -EBUSY; 271 DEVNAME " scd perfcnt", &sbp);
178 } 272 if (err)
179 273 goto out_free_irq;
180 /* I need the core to mask these, but the interrupt mapper to 274
181 pass them through. I am exploiting my knowledge that 275 /*
182 cp0_status masks out IP[5]. krw */ 276 * I need the core to mask these, but the interrupt mapper to pass them
277 * through. I am exploiting my knowledge that cp0_status masks out
278 * IP[5]. krw
279 */
183 __raw_writeq(K_INT_MAP_I3, 280 __raw_writeq(K_INT_MAP_I3,
184 IOADDR(A_IMR_REGISTER(0, R_IMR_INTERRUPT_MAP_BASE) + 281 IOADDR(A_IMR_REGISTER(0, R_IMR_INTERRUPT_MAP_BASE) +
185 (K_INT_PERF_CNT << 3))); 282 (K_INT_PERF_CNT << 3)));
@@ -201,7 +298,7 @@ int sbprof_zbprof_start(struct file *filp)
201 __raw_writeq(0, IOADDR(A_ADDR_TRAP_CFG_3)); 298 __raw_writeq(0, IOADDR(A_ADDR_TRAP_CFG_3));
202 299
203 /* Initialize Trace Event 0-7 */ 300 /* Initialize Trace Event 0-7 */
204 // when interrupt 301 /* when interrupt */
205 __raw_writeq(M_SCD_TREVT_INTERRUPT, IOADDR(A_SCD_TRACE_EVENT_0)); 302 __raw_writeq(M_SCD_TREVT_INTERRUPT, IOADDR(A_SCD_TRACE_EVENT_0));
206 __raw_writeq(0, IOADDR(A_SCD_TRACE_EVENT_1)); 303 __raw_writeq(0, IOADDR(A_SCD_TRACE_EVENT_1));
207 __raw_writeq(0, IOADDR(A_SCD_TRACE_EVENT_2)); 304 __raw_writeq(0, IOADDR(A_SCD_TRACE_EVENT_2));
@@ -212,10 +309,10 @@ int sbprof_zbprof_start(struct file *filp)
212 __raw_writeq(0, IOADDR(A_SCD_TRACE_EVENT_7)); 309 __raw_writeq(0, IOADDR(A_SCD_TRACE_EVENT_7));
213 310
214 /* Initialize Trace Sequence 0-7 */ 311 /* Initialize Trace Sequence 0-7 */
215 // Start on event 0 (interrupt) 312 /* Start on event 0 (interrupt) */
216 __raw_writeq(V_SCD_TRSEQ_FUNC_START | 0x0fff, 313 __raw_writeq(V_SCD_TRSEQ_FUNC_START | 0x0fff,
217 IOADDR(A_SCD_TRACE_SEQUENCE_0)); 314 IOADDR(A_SCD_TRACE_SEQUENCE_0));
218 // dsamp when d used | asamp when a used 315 /* dsamp when d used | asamp when a used */
219 __raw_writeq(M_SCD_TRSEQ_ASAMPLE | M_SCD_TRSEQ_DSAMPLE | 316 __raw_writeq(M_SCD_TRSEQ_ASAMPLE | M_SCD_TRSEQ_DSAMPLE |
220 K_SCD_TRSEQ_TRIGGER_ALL, 317 K_SCD_TRSEQ_TRIGGER_ALL,
221 IOADDR(A_SCD_TRACE_SEQUENCE_1)); 318 IOADDR(A_SCD_TRACE_SEQUENCE_1));
@@ -232,33 +329,41 @@ int sbprof_zbprof_start(struct file *filp)
232 329
233 arm_tb(); 330 arm_tb();
234 331
235 DBG(printk(DEVNAME ": done starting\n")); 332 pr_debug(DEVNAME ": done starting\n");
236 333
237 return 0; 334 return 0;
335
336out_free_irq:
337 free_irq(K_INT_TRACE_FREEZE, &sbp);
338
339 return err;
238} 340}
239 341
240int sbprof_zbprof_stop(void) 342static int sbprof_zbprof_stop(void)
241{ 343{
242 DEFINE_WAIT(wait); 344 int err;
243 DBG(printk(DEVNAME ": stopping\n")); 345
346 pr_debug(DEVNAME ": stopping\n");
244 347
245 if (sbp.tb_enable) { 348 if (sbp.tb_enable) {
349 /*
350 * XXXKW there is a window here where the intr handler may run,
351 * see the disable, and do the wake_up before this sleep
352 * happens.
353 */
354 pr_debug(DEVNAME ": wait for disarm\n");
355 err = wait_event_interruptible(sbp.tb_sync, !sbp.tb_armed);
356 pr_debug(DEVNAME ": disarm complete, stat %d\n", err);
357
358 if (err)
359 return err;
360
246 sbp.tb_enable = 0; 361 sbp.tb_enable = 0;
247 /* XXXKW there is a window here where the intr handler
248 may run, see the disable, and do the wake_up before
249 this sleep happens. */
250 if (sbp.tb_armed) {
251 DBG(printk(DEVNAME ": wait for disarm\n"));
252 prepare_to_wait(&sbp.tb_sync, &wait, TASK_INTERRUPTIBLE);
253 schedule();
254 finish_wait(&sbp.tb_sync, &wait);
255 DBG(printk(DEVNAME ": disarm complete\n"));
256 }
257 free_irq(K_INT_TRACE_FREEZE, &sbp); 362 free_irq(K_INT_TRACE_FREEZE, &sbp);
258 free_irq(K_INT_PERF_CNT, &sbp); 363 free_irq(K_INT_PERF_CNT, &sbp);
259 } 364 }
260 365
261 DBG(printk(DEVNAME ": done stopping\n")); 366 pr_debug(DEVNAME ": done stopping\n");
262 367
263 return 0; 368 return 0;
264} 369}
@@ -268,42 +373,45 @@ static int sbprof_tb_open(struct inode *inode, struct file *filp)
268 int minor; 373 int minor;
269 374
270 minor = iminor(inode); 375 minor = iminor(inode);
271 if (minor != 0) { 376 if (minor != 0)
272 return -ENODEV; 377 return -ENODEV;
273 } 378
274 if (sbp.open) { 379 if (xchg(&sbp.open, SB_OPENING) != SB_CLOSED)
275 return -EBUSY; 380 return -EBUSY;
276 }
277 381
278 memset(&sbp, 0, sizeof(struct sbprof_tb)); 382 memset(&sbp, 0, sizeof(struct sbprof_tb));
383
279 sbp.sbprof_tbbuf = vmalloc(MAX_TBSAMPLE_BYTES); 384 sbp.sbprof_tbbuf = vmalloc(MAX_TBSAMPLE_BYTES);
280 if (!sbp.sbprof_tbbuf) { 385 if (!sbp.sbprof_tbbuf)
281 return -ENOMEM; 386 return -ENOMEM;
282 } 387
283 memset(sbp.sbprof_tbbuf, 0, MAX_TBSAMPLE_BYTES); 388 memset(sbp.sbprof_tbbuf, 0, MAX_TBSAMPLE_BYTES);
284 init_waitqueue_head(&sbp.tb_sync); 389 init_waitqueue_head(&sbp.tb_sync);
285 init_waitqueue_head(&sbp.tb_read); 390 init_waitqueue_head(&sbp.tb_read);
286 sbp.open = 1; 391 mutex_init(&sbp.lock);
392
393 sbp.open = SB_OPEN;
287 394
288 return 0; 395 return 0;
289} 396}
290 397
291static int sbprof_tb_release(struct inode *inode, struct file *filp) 398static int sbprof_tb_release(struct inode *inode, struct file *filp)
292{ 399{
293 int minor; 400 int minor = iminor(inode);
294 401
295 minor = iminor(inode); 402 if (minor != 0 || !sbp.open)
296 if (minor != 0 || !sbp.open) {
297 return -ENODEV; 403 return -ENODEV;
298 }
299 404
300 if (sbp.tb_armed || sbp.tb_enable) { 405 mutex_lock(&sbp.lock);
406
407 if (sbp.tb_armed || sbp.tb_enable)
301 sbprof_zbprof_stop(); 408 sbprof_zbprof_stop();
302 }
303 409
304 vfree(sbp.sbprof_tbbuf); 410 vfree(sbp.sbprof_tbbuf);
305 sbp.open = 0; 411 sbp.open = 0;
306 412
413 mutex_unlock(&sbp.lock);
414
307 return 0; 415 return 0;
308} 416}
309 417
@@ -311,21 +419,35 @@ static ssize_t sbprof_tb_read(struct file *filp, char *buf,
311 size_t size, loff_t *offp) 419 size_t size, loff_t *offp)
312{ 420{
313 int cur_sample, sample_off, cur_count, sample_left; 421 int cur_sample, sample_off, cur_count, sample_left;
314 char *src;
315 int count = 0;
316 char *dest = buf;
317 long cur_off = *offp; 422 long cur_off = *offp;
423 char *dest = buf;
424 int count = 0;
425 char *src;
426
427 if (!access_ok(VERIFY_WRITE, buf, size))
428 return -EFAULT;
429
430 mutex_lock(&sbp.lock);
318 431
319 count = 0; 432 count = 0;
320 cur_sample = cur_off / TB_SAMPLE_SIZE; 433 cur_sample = cur_off / TB_SAMPLE_SIZE;
321 sample_off = cur_off % TB_SAMPLE_SIZE; 434 sample_off = cur_off % TB_SAMPLE_SIZE;
322 sample_left = TB_SAMPLE_SIZE - sample_off; 435 sample_left = TB_SAMPLE_SIZE - sample_off;
436
323 while (size && (cur_sample < sbp.next_tb_sample)) { 437 while (size && (cur_sample < sbp.next_tb_sample)) {
438 int err;
439
324 cur_count = size < sample_left ? size : sample_left; 440 cur_count = size < sample_left ? size : sample_left;
325 src = (char *)(((long)sbp.sbprof_tbbuf[cur_sample])+sample_off); 441 src = (char *)(((long)sbp.sbprof_tbbuf[cur_sample])+sample_off);
326 copy_to_user(dest, src, cur_count); 442 err = __copy_to_user(dest, src, cur_count);
327 DBG(printk(DEVNAME ": read from sample %d, %d bytes\n", 443 if (err) {
328 cur_sample, cur_count)); 444 *offp = cur_off + cur_count - err;
445 mutex_unlock(&sbp.lock);
446 return err;
447 }
448
449 pr_debug(DEVNAME ": read from sample %d, %d bytes\n",
450 cur_sample, cur_count);
329 size -= cur_count; 451 size -= cur_count;
330 sample_left -= cur_count; 452 sample_left -= cur_count;
331 if (!sample_left) { 453 if (!sample_left) {
@@ -339,37 +461,43 @@ static ssize_t sbprof_tb_read(struct file *filp, char *buf,
339 dest += cur_count; 461 dest += cur_count;
340 count += cur_count; 462 count += cur_count;
341 } 463 }
464
342 *offp = cur_off; 465 *offp = cur_off;
466 mutex_unlock(&sbp.lock);
343 467
344 return count; 468 return count;
345} 469}
346 470
347static long sbprof_tb_ioctl(struct file *filp, 471static long sbprof_tb_ioctl(struct file *filp, unsigned int command,
348 unsigned int command, 472 unsigned long arg)
349 unsigned long arg)
350{ 473{
351 int error = 0; 474 int error = 0;
352 475
353 lock_kernel();
354 switch (command) { 476 switch (command) {
355 case SBPROF_ZBSTART: 477 case SBPROF_ZBSTART:
478 mutex_lock(&sbp.lock);
356 error = sbprof_zbprof_start(filp); 479 error = sbprof_zbprof_start(filp);
480 mutex_unlock(&sbp.lock);
357 break; 481 break;
482
358 case SBPROF_ZBSTOP: 483 case SBPROF_ZBSTOP:
484 mutex_lock(&sbp.lock);
359 error = sbprof_zbprof_stop(); 485 error = sbprof_zbprof_stop();
486 mutex_unlock(&sbp.lock);
360 break; 487 break;
488
361 case SBPROF_ZBWAITFULL: 489 case SBPROF_ZBWAITFULL:
362 DEFINE_WAIT(wait); 490 error = wait_event_interruptible(sbp.tb_read, TB_FULL);
363 prepare_to_wait(&sbp.tb_read, &wait, TASK_INTERRUPTIBLE); 491 if (error)
364 schedule(); 492 break;
365 finish_wait(&sbp.tb_read, &wait); 493
366 /* XXXKW check if interrupted? */ 494 error = put_user(TB_FULL, (int *) arg);
367 return put_user(TB_FULL, (int *) arg); 495 break;
496
368 default: 497 default:
369 error = -EINVAL; 498 error = -EINVAL;
370 break; 499 break;
371 } 500 }
372 unlock_kernel();
373 501
374 return error; 502 return error;
375} 503}
@@ -384,23 +512,60 @@ static const struct file_operations sbprof_tb_fops = {
384 .mmap = NULL, 512 .mmap = NULL,
385}; 513};
386 514
515static struct class *tb_class;
516static struct device *tb_dev;
517
387static int __init sbprof_tb_init(void) 518static int __init sbprof_tb_init(void)
388{ 519{
520 struct device *dev;
521 struct class *tbc;
522 int err;
523
389 if (register_chrdev(SBPROF_TB_MAJOR, DEVNAME, &sbprof_tb_fops)) { 524 if (register_chrdev(SBPROF_TB_MAJOR, DEVNAME, &sbprof_tb_fops)) {
390 printk(KERN_WARNING DEVNAME ": initialization failed (dev %d)\n", 525 printk(KERN_WARNING DEVNAME ": initialization failed (dev %d)\n",
391 SBPROF_TB_MAJOR); 526 SBPROF_TB_MAJOR);
392 return -EIO; 527 return -EIO;
393 } 528 }
529
530 tbc = class_create(THIS_MODULE, "sb_tracebuffer");
531 if (IS_ERR(tbc)) {
532 err = PTR_ERR(tbc);
533 goto out_chrdev;
534 }
535
536 tb_class = tbc;
537
538 dev = device_create(tbc, NULL, MKDEV(SBPROF_TB_MAJOR, 0), "tb");
539 if (IS_ERR(dev)) {
540 err = PTR_ERR(dev);
541 goto out_class;
542 }
543 tb_dev = dev;
544
394 sbp.open = 0; 545 sbp.open = 0;
395 tb_period = zbbus_mhz * 10000LL; 546 tb_period = zbbus_mhz * 10000LL;
396 printk(KERN_INFO DEVNAME ": initialized - tb_period = %lld\n", tb_period); 547 pr_info(DEVNAME ": initialized - tb_period = %lld\n", tb_period);
548
397 return 0; 549 return 0;
550
551out_class:
552 class_destroy(tb_class);
553out_chrdev:
554 unregister_chrdev(SBPROF_TB_MAJOR, DEVNAME);
555
556 return err;
398} 557}
399 558
400static void __exit sbprof_tb_cleanup(void) 559static void __exit sbprof_tb_cleanup(void)
401{ 560{
561 device_destroy(tb_class, MKDEV(SBPROF_TB_MAJOR, 0));
402 unregister_chrdev(SBPROF_TB_MAJOR, DEVNAME); 562 unregister_chrdev(SBPROF_TB_MAJOR, DEVNAME);
563 class_destroy(tb_class);
403} 564}
404 565
405module_init(sbprof_tb_init); 566module_init(sbprof_tb_init);
406module_exit(sbprof_tb_cleanup); 567module_exit(sbprof_tb_cleanup);
568
569MODULE_ALIAS_CHARDEV_MAJOR(SBPROF_TB_MAJOR);
570MODULE_AUTHOR("Ralf Baechle <ralf@linux-mips.org>");
571MODULE_LICENSE("GPL");
diff --git a/arch/mips/sibyte/sb1250/setup.c b/arch/mips/sibyte/sb1250/setup.c
index 1cb042eab720..87188f0f6fbe 100644
--- a/arch/mips/sibyte/sb1250/setup.c
+++ b/arch/mips/sibyte/sb1250/setup.c
@@ -16,6 +16,7 @@
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 */ 17 */
18#include <linux/init.h> 18#include <linux/init.h>
19#include <linux/module.h>
19#include <linux/kernel.h> 20#include <linux/kernel.h>
20#include <linux/reboot.h> 21#include <linux/reboot.h>
21#include <linux/string.h> 22#include <linux/string.h>
@@ -32,6 +33,7 @@ unsigned int soc_pass;
32unsigned int soc_type; 33unsigned int soc_type;
33unsigned int periph_rev; 34unsigned int periph_rev;
34unsigned int zbbus_mhz; 35unsigned int zbbus_mhz;
36EXPORT_SYMBOL(zbbus_mhz);
35 37
36static char *soc_str; 38static char *soc_str;
37static char *pass_str; 39static char *pass_str;
diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c
index 7ec4ac77c0fa..e4006dc087ca 100644
--- a/arch/powerpc/kernel/cputable.c
+++ b/arch/powerpc/kernel/cputable.c
@@ -225,6 +225,22 @@ static struct cpu_spec cpu_specs[] = {
225 .oprofile_type = PPC_OPROFILE_POWER4, 225 .oprofile_type = PPC_OPROFILE_POWER4,
226 .platform = "ppc970", 226 .platform = "ppc970",
227 }, 227 },
228 { /* PPC970MP DD1.0 - no DEEPNAP, use regular 970 init */
229 .pvr_mask = 0xffffffff,
230 .pvr_value = 0x00440100,
231 .cpu_name = "PPC970MP",
232 .cpu_features = CPU_FTRS_PPC970,
233 .cpu_user_features = COMMON_USER_POWER4 |
234 PPC_FEATURE_HAS_ALTIVEC_COMP,
235 .icache_bsize = 128,
236 .dcache_bsize = 128,
237 .num_pmcs = 8,
238 .cpu_setup = __setup_cpu_ppc970,
239 .cpu_restore = __restore_cpu_ppc970,
240 .oprofile_cpu_type = "ppc64/970MP",
241 .oprofile_type = PPC_OPROFILE_POWER4,
242 .platform = "ppc970",
243 },
228 { /* PPC970MP */ 244 { /* PPC970MP */
229 .pvr_mask = 0xffff0000, 245 .pvr_mask = 0xffff0000,
230 .pvr_value = 0x00440000, 246 .pvr_value = 0x00440000,
diff --git a/arch/powerpc/kernel/prom_parse.c b/arch/powerpc/kernel/prom_parse.c
index ea6fd552c7ea..91b443c9a488 100644
--- a/arch/powerpc/kernel/prom_parse.c
+++ b/arch/powerpc/kernel/prom_parse.c
@@ -916,7 +916,7 @@ EXPORT_SYMBOL_GPL(of_irq_map_raw);
916static int of_irq_map_oldworld(struct device_node *device, int index, 916static int of_irq_map_oldworld(struct device_node *device, int index,
917 struct of_irq *out_irq) 917 struct of_irq *out_irq)
918{ 918{
919 const u32 *ints; 919 const u32 *ints = NULL;
920 int intlen; 920 int intlen;
921 921
922 /* 922 /*
diff --git a/arch/powerpc/platforms/83xx/mpc834x_mds.c b/arch/powerpc/platforms/83xx/mpc834x_mds.c
index e5d819166874..8aa9a93e2aa2 100644
--- a/arch/powerpc/platforms/83xx/mpc834x_mds.c
+++ b/arch/powerpc/platforms/83xx/mpc834x_mds.c
@@ -55,9 +55,9 @@ static int mpc834x_usb_cfg(void)
55 struct device_node *np = NULL; 55 struct device_node *np = NULL;
56 int port0_is_dr = 0; 56 int port0_is_dr = 0;
57 57
58 if ((np = of_find_compatible_node(np, "usb", "fsl-usb2-dr")) != NULL) 58 if ((np = of_find_compatible_node(NULL, "usb", "fsl-usb2-dr")) != NULL)
59 port0_is_dr = 1; 59 port0_is_dr = 1;
60 if ((np = of_find_compatible_node(np, "usb", "fsl-usb2-mph")) != NULL){ 60 if ((np = of_find_compatible_node(NULL, "usb", "fsl-usb2-mph")) != NULL){
61 if (port0_is_dr) { 61 if (port0_is_dr) {
62 printk(KERN_WARNING 62 printk(KERN_WARNING
63 "There is only one USB port on PB board! \n"); 63 "There is only one USB port on PB board! \n");
@@ -103,8 +103,8 @@ static int mpc834x_usb_cfg(void)
103 return -1; 103 return -1;
104 104
105 /* 105 /*
106 * if MDS board is plug into PIB board, 106 * if Processor Board is plugged into PIB board,
107 * force to use the PHY on MDS board 107 * force to use the PHY on Processor Board
108 */ 108 */
109 bcsr5 = in_8(bcsr_regs + 5); 109 bcsr5 = in_8(bcsr_regs + 5);
110 if (!(bcsr5 & BCSR5_INT_USB)) 110 if (!(bcsr5 & BCSR5_INT_USB))
diff --git a/arch/powerpc/platforms/85xx/Kconfig b/arch/powerpc/platforms/85xx/Kconfig
index eb661ccf2dab..e764c0aced88 100644
--- a/arch/powerpc/platforms/85xx/Kconfig
+++ b/arch/powerpc/platforms/85xx/Kconfig
@@ -47,6 +47,7 @@ config MPC85xx
47 bool 47 bool
48 select PPC_UDBG_16550 48 select PPC_UDBG_16550
49 select PPC_INDIRECT_PCI 49 select PPC_INDIRECT_PCI
50 select SERIAL_8250_SHARE_IRQ if SERIAL_8250
50 default y if MPC8540_ADS || MPC85xx_CDS || MPC8560_ADS || MPC85xx_MDS 51 default y if MPC8540_ADS || MPC85xx_CDS || MPC8560_ADS || MPC85xx_MDS
51 52
52config PPC_INDIRECT_PCI_BE 53config PPC_INDIRECT_PCI_BE
diff --git a/arch/powerpc/platforms/celleb/scc_epci.c b/arch/powerpc/platforms/celleb/scc_epci.c
index c11b39c3776a..fb23d53eb09c 100644
--- a/arch/powerpc/platforms/celleb/scc_epci.c
+++ b/arch/powerpc/platforms/celleb/scc_epci.c
@@ -43,11 +43,34 @@
43 43
44#define iob() __asm__ __volatile__("eieio; sync":::"memory") 44#define iob() __asm__ __volatile__("eieio; sync":::"memory")
45 45
46static inline volatile void __iomem *celleb_epci_get_epci_base(
47 struct pci_controller *hose)
48{
49 /*
50 * Note:
51 * Celleb epci uses cfg_addr as a base address for
52 * epci control registers.
53 */
54
55 return hose->cfg_addr;
56}
57
58static inline volatile void __iomem *celleb_epci_get_epci_cfg(
59 struct pci_controller *hose)
60{
61 /*
62 * Note:
63 * Celleb epci uses cfg_data as a base address for
64 * configuration area for epci devices.
65 */
66
67 return hose->cfg_data;
68}
46 69
47#if 0 /* test code for epci dummy read */ 70#if 0 /* test code for epci dummy read */
48static void celleb_epci_dummy_read(struct pci_dev *dev) 71static void celleb_epci_dummy_read(struct pci_dev *dev)
49{ 72{
50 void __iomem *epci_base; 73 volatile void __iomem *epci_base;
51 struct device_node *node; 74 struct device_node *node;
52 struct pci_controller *hose; 75 struct pci_controller *hose;
53 u32 val; 76 u32 val;
@@ -58,7 +81,7 @@ static void celleb_epci_dummy_read(struct pci_dev *dev)
58 if (!hose) 81 if (!hose)
59 return; 82 return;
60 83
61 epci_base = hose->cfg_addr; 84 epci_base = celleb_epci_get_epci_base(hose);
62 85
63 val = in_be32(epci_base + SCC_EPCI_WATRP); 86 val = in_be32(epci_base + SCC_EPCI_WATRP);
64 iosync(); 87 iosync();
@@ -70,19 +93,20 @@ static void celleb_epci_dummy_read(struct pci_dev *dev)
70static inline void clear_and_disable_master_abort_interrupt( 93static inline void clear_and_disable_master_abort_interrupt(
71 struct pci_controller *hose) 94 struct pci_controller *hose)
72{ 95{
73 void __iomem *addr; 96 volatile void __iomem *epci_base, *reg;
74 addr = hose->cfg_addr + PCI_COMMAND; 97 epci_base = celleb_epci_get_epci_base(hose);
75 out_be32(addr, in_be32(addr) | (PCI_STATUS_REC_MASTER_ABORT << 16)); 98 reg = epci_base + PCI_COMMAND;
99 out_be32(reg, in_be32(reg) | (PCI_STATUS_REC_MASTER_ABORT << 16));
76} 100}
77 101
78static int celleb_epci_check_abort(struct pci_controller *hose, 102static int celleb_epci_check_abort(struct pci_controller *hose,
79 void __iomem *addr) 103 volatile void __iomem *addr)
80{ 104{
81 void __iomem *reg, *epci_base; 105 volatile void __iomem *reg, *epci_base;
82 u32 val; 106 u32 val;
83 107
84 iob(); 108 iob();
85 epci_base = hose->cfg_addr; 109 epci_base = celleb_epci_get_epci_base(hose);
86 110
87 reg = epci_base + PCI_COMMAND; 111 reg = epci_base + PCI_COMMAND;
88 val = in_be32(reg); 112 val = in_be32(reg);
@@ -108,20 +132,21 @@ static int celleb_epci_check_abort(struct pci_controller *hose,
108 return PCIBIOS_SUCCESSFUL; 132 return PCIBIOS_SUCCESSFUL;
109} 133}
110 134
111static void __iomem *celleb_epci_make_config_addr(struct pci_controller *hose, 135static volatile void __iomem *celleb_epci_make_config_addr(
136 struct pci_controller *hose,
112 unsigned int devfn, int where) 137 unsigned int devfn, int where)
113{ 138{
114 void __iomem *addr; 139 volatile void __iomem *addr;
115 struct pci_bus *bus = hose->bus; 140 struct pci_bus *bus = hose->bus;
116 141
117 if (bus->self) 142 if (bus->self)
118 addr = hose->cfg_data + 143 addr = celleb_epci_get_epci_cfg(hose) +
119 (((bus->number & 0xff) << 16) 144 (((bus->number & 0xff) << 16)
120 | ((devfn & 0xff) << 8) 145 | ((devfn & 0xff) << 8)
121 | (where & 0xff) 146 | (where & 0xff)
122 | 0x01000000); 147 | 0x01000000);
123 else 148 else
124 addr = hose->cfg_data + 149 addr = celleb_epci_get_epci_cfg(hose) +
125 (((devfn & 0xff) << 8) | (where & 0xff)); 150 (((devfn & 0xff) << 8) | (where & 0xff));
126 151
127 pr_debug("EPCI: config_addr = 0x%p\n", addr); 152 pr_debug("EPCI: config_addr = 0x%p\n", addr);
@@ -132,7 +157,7 @@ static void __iomem *celleb_epci_make_config_addr(struct pci_controller *hose,
132static int celleb_epci_read_config(struct pci_bus *bus, 157static int celleb_epci_read_config(struct pci_bus *bus,
133 unsigned int devfn, int where, int size, u32 * val) 158 unsigned int devfn, int where, int size, u32 * val)
134{ 159{
135 void __iomem *addr; 160 volatile void __iomem *epci_base, *addr;
136 struct device_node *node; 161 struct device_node *node;
137 struct pci_controller *hose; 162 struct pci_controller *hose;
138 163
@@ -142,13 +167,14 @@ static int celleb_epci_read_config(struct pci_bus *bus,
142 node = (struct device_node *)bus->sysdata; 167 node = (struct device_node *)bus->sysdata;
143 hose = pci_find_hose_for_OF_device(node); 168 hose = pci_find_hose_for_OF_device(node);
144 169
145 if (!hose->cfg_data) 170 if (!celleb_epci_get_epci_cfg(hose))
146 return PCIBIOS_DEVICE_NOT_FOUND; 171 return PCIBIOS_DEVICE_NOT_FOUND;
147 172
148 if (bus->number == hose->first_busno && devfn == 0) { 173 if (bus->number == hose->first_busno && devfn == 0) {
149 /* EPCI controller self */ 174 /* EPCI controller self */
150 175
151 addr = hose->cfg_addr + where; 176 epci_base = celleb_epci_get_epci_base(hose);
177 addr = epci_base + where;
152 178
153 switch (size) { 179 switch (size) {
154 case 1: 180 case 1:
@@ -185,7 +211,7 @@ static int celleb_epci_read_config(struct pci_bus *bus,
185 } 211 }
186 212
187 pr_debug("EPCI: " 213 pr_debug("EPCI: "
188 "addr=0x%lx, devfn=0x%x, where=0x%x, size=0x%x, val=0x%x\n", 214 "addr=0x%p, devfn=0x%x, where=0x%x, size=0x%x, val=0x%x\n",
189 addr, devfn, where, size, *val); 215 addr, devfn, where, size, *val);
190 216
191 return celleb_epci_check_abort(hose, NULL); 217 return celleb_epci_check_abort(hose, NULL);
@@ -194,7 +220,7 @@ static int celleb_epci_read_config(struct pci_bus *bus,
194static int celleb_epci_write_config(struct pci_bus *bus, 220static int celleb_epci_write_config(struct pci_bus *bus,
195 unsigned int devfn, int where, int size, u32 val) 221 unsigned int devfn, int where, int size, u32 val)
196{ 222{
197 void __iomem *addr; 223 volatile void __iomem *epci_base, *addr;
198 struct device_node *node; 224 struct device_node *node;
199 struct pci_controller *hose; 225 struct pci_controller *hose;
200 226
@@ -204,13 +230,15 @@ static int celleb_epci_write_config(struct pci_bus *bus,
204 node = (struct device_node *)bus->sysdata; 230 node = (struct device_node *)bus->sysdata;
205 hose = pci_find_hose_for_OF_device(node); 231 hose = pci_find_hose_for_OF_device(node);
206 232
207 if (!hose->cfg_data) 233
234 if (!celleb_epci_get_epci_cfg(hose))
208 return PCIBIOS_DEVICE_NOT_FOUND; 235 return PCIBIOS_DEVICE_NOT_FOUND;
209 236
210 if (bus->number == hose->first_busno && devfn == 0) { 237 if (bus->number == hose->first_busno && devfn == 0) {
211 /* EPCI controller self */ 238 /* EPCI controller self */
212 239
213 addr = hose->cfg_addr + where; 240 epci_base = celleb_epci_get_epci_base(hose);
241 addr = epci_base + where;
214 242
215 switch (size) { 243 switch (size) {
216 case 1: 244 case 1:
@@ -258,10 +286,10 @@ struct pci_ops celleb_epci_ops = {
258static int __devinit celleb_epci_init(struct pci_controller *hose) 286static int __devinit celleb_epci_init(struct pci_controller *hose)
259{ 287{
260 u32 val; 288 u32 val;
261 void __iomem *reg, *epci_base; 289 volatile void __iomem *reg, *epci_base;
262 int hwres = 0; 290 int hwres = 0;
263 291
264 epci_base = hose->cfg_addr; 292 epci_base = celleb_epci_get_epci_base(hose);
265 293
266 /* PCI core reset(Internal bus and PCI clock) */ 294 /* PCI core reset(Internal bus and PCI clock) */
267 reg = epci_base + SCC_EPCI_CKCTRL; 295 reg = epci_base + SCC_EPCI_CKCTRL;
@@ -382,6 +410,18 @@ int __devinit celleb_setup_epci(struct device_node *node,
382 410
383 pr_debug("PCI: celleb_setup_epci()\n"); 411 pr_debug("PCI: celleb_setup_epci()\n");
384 412
413 /*
414 * Note:
415 * Celleb epci uses cfg_addr and cfg_data member of
416 * pci_controller structure in irregular way.
417 *
418 * cfg_addr is used to map for control registers of
419 * celleb epci.
420 *
421 * cfg_data is used for configuration area of devices
422 * on Celleb epci buses.
423 */
424
385 if (of_address_to_resource(node, 0, &r)) 425 if (of_address_to_resource(node, 0, &r))
386 goto error; 426 goto error;
387 hose->cfg_addr = ioremap(r.start, (r.end - r.start + 1)); 427 hose->cfg_addr = ioremap(r.start, (r.end - r.start + 1));
diff --git a/arch/powerpc/platforms/embedded6xx/Kconfig b/arch/powerpc/platforms/embedded6xx/Kconfig
index 886c522d78e9..3410bcbc9dbe 100644
--- a/arch/powerpc/platforms/embedded6xx/Kconfig
+++ b/arch/powerpc/platforms/embedded6xx/Kconfig
@@ -79,6 +79,7 @@ config LINKSTATION
79 select MPIC 79 select MPIC
80 select FSL_SOC 80 select FSL_SOC
81 select PPC_UDBG_16550 if SERIAL_8250 81 select PPC_UDBG_16550 if SERIAL_8250
82 select DEFAULT_UIMAGE
82 help 83 help
83 Select LINKSTATION if configuring for one of PPC- (MPC8241) 84 Select LINKSTATION if configuring for one of PPC- (MPC8241)
84 based NAS systems from Buffalo Technology. So far only 85 based NAS systems from Buffalo Technology. So far only
diff --git a/arch/powerpc/platforms/powermac/feature.c b/arch/powerpc/platforms/powermac/feature.c
index c29a6a064d22..24cc50c1774a 100644
--- a/arch/powerpc/platforms/powermac/feature.c
+++ b/arch/powerpc/platforms/powermac/feature.c
@@ -810,6 +810,7 @@ core99_ata100_enable(struct device_node *node, long value)
810 unsigned long flags; 810 unsigned long flags;
811 struct pci_dev *pdev = NULL; 811 struct pci_dev *pdev = NULL;
812 u8 pbus, pid; 812 u8 pbus, pid;
813 int rc;
813 814
814 if (uninorth_rev < 0x24) 815 if (uninorth_rev < 0x24)
815 return -ENODEV; 816 return -ENODEV;
@@ -828,7 +829,9 @@ core99_ata100_enable(struct device_node *node, long value)
828 pdev = pci_find_slot(pbus, pid); 829 pdev = pci_find_slot(pbus, pid);
829 if (pdev == NULL) 830 if (pdev == NULL)
830 return 0; 831 return 0;
831 pci_enable_device(pdev); 832 rc = pci_enable_device(pdev);
833 if (rc)
834 return rc;
832 pci_set_master(pdev); 835 pci_set_master(pdev);
833 } 836 }
834 return 0; 837 return 0;
diff --git a/arch/powerpc/platforms/powermac/pci.c b/arch/powerpc/platforms/powermac/pci.c
index f42475b27c15..6fbac308ded6 100644
--- a/arch/powerpc/platforms/powermac/pci.c
+++ b/arch/powerpc/platforms/powermac/pci.c
@@ -1191,8 +1191,11 @@ void __init pmac_pcibios_after_init(void)
1191 * -- BenH 1191 * -- BenH
1192 */ 1192 */
1193 for_each_pci_dev(dev) { 1193 for_each_pci_dev(dev) {
1194 if ((dev->class >> 16) == PCI_BASE_CLASS_STORAGE) 1194 if ((dev->class >> 16) != PCI_BASE_CLASS_STORAGE)
1195 pci_enable_device(dev); 1195 continue;
1196 if (pci_enable_device(dev))
1197 printk(KERN_WARNING
1198 "pci: Failed to enable %s\n", pci_name(dev));
1196 } 1199 }
1197#endif /* CONFIG_BLK_DEV_IDE */ 1200#endif /* CONFIG_BLK_DEV_IDE */
1198 1201
diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
index 0183e5fbaf46..bf299b66f3fc 100644
--- a/arch/powerpc/xmon/xmon.c
+++ b/arch/powerpc/xmon/xmon.c
@@ -218,7 +218,7 @@ Commands:\n\
218" ss stop execution on all spus\n\ 218" ss stop execution on all spus\n\
219 sr restore execution on stopped spus\n\ 219 sr restore execution on stopped spus\n\
220 sf # dump spu fields for spu # (in hex)\n\ 220 sf # dump spu fields for spu # (in hex)\n\
221 sd # dump spu local store for spu # (in hex)\ 221 sd # dump spu local store for spu # (in hex)\n\
222 sdi # disassemble spu local store for spu # (in hex)\n" 222 sdi # disassemble spu local store for spu # (in hex)\n"
223#endif 223#endif
224" S print special registers\n\ 224" S print special registers\n\
diff --git a/arch/sh/boards/renesas/r7780rp/Makefile b/arch/sh/boards/renesas/r7780rp/Makefile
index 3c93012e91a3..ed5f5a9a3b3e 100644
--- a/arch/sh/boards/renesas/r7780rp/Makefile
+++ b/arch/sh/boards/renesas/r7780rp/Makefile
@@ -2,6 +2,6 @@
2# Makefile for the R7780RP-1 specific parts of the kernel 2# Makefile for the R7780RP-1 specific parts of the kernel
3# 3#
4 4
5obj-y := setup.o io.o irq.o 5obj-y := setup.o irq.o
6 6
7obj-$(CONFIG_PUSH_SWITCH) += psw.o 7obj-$(CONFIG_PUSH_SWITCH) += psw.o
diff --git a/arch/sh/boards/renesas/r7780rp/io.c b/arch/sh/boards/renesas/r7780rp/io.c
deleted file mode 100644
index f74d2ffb3851..000000000000
--- a/arch/sh/boards/renesas/r7780rp/io.c
+++ /dev/null
@@ -1,233 +0,0 @@
1/*
2 * Copyright (C) 2001 Ian da Silva, Jeremy Siegel
3 * Based largely on io_se.c.
4 *
5 * I/O routine for Renesas Solutions Highlander R7780RP-1
6 *
7 * Initial version only to support LAN access; some
8 * placeholder code from io_r7780rp.c left in with the
9 * expectation of later SuperIO and PCMCIA access.
10 */
11#include <linux/pci.h>
12#include <linux/kernel.h>
13#include <linux/types.h>
14#include <linux/io.h>
15#include <asm/r7780rp.h>
16#include <asm/addrspace.h>
17
18static inline unsigned long port88796l(unsigned int port, int flag)
19{
20 unsigned long addr;
21
22 if (flag)
23 addr = PA_AX88796L + ((port - AX88796L_IO_BASE) << 1);
24 else
25 addr = PA_AX88796L + ((port - AX88796L_IO_BASE) << 1) + 0x1000;
26
27 return addr;
28}
29
30#if defined(CONFIG_NE2000) || defined(CONFIG_NE2000_MODULE)
31#define CHECK_AX88796L_PORT(port) \
32 ((port >= AX88796L_IO_BASE) && (port < (AX88796L_IO_BASE+0x20)))
33#else
34#define CHECK_AX88796L_PORT(port) (0)
35#endif
36
37/*
38 * General outline: remap really low stuff [eventually] to SuperIO,
39 * stuff in PCI IO space (at or above window at pci.h:PCIBIOS_MIN_IO)
40 * is mapped through the PCI IO window. Stuff with high bits (PXSEG)
41 * should be way beyond the window, and is used w/o translation for
42 * compatibility.
43 */
44u8 r7780rp_inb(unsigned long port)
45{
46 if (CHECK_AX88796L_PORT(port))
47 return ctrl_inw(port88796l(port, 0)) & 0xff;
48 else if (is_pci_ioaddr(port))
49 return ctrl_inb(pci_ioaddr(port));
50
51 return ctrl_inw(port) & 0xff;
52}
53
54u8 r7780rp_inb_p(unsigned long port)
55{
56 u8 v;
57
58 if (CHECK_AX88796L_PORT(port))
59 v = ctrl_inw(port88796l(port, 0)) & 0xff;
60 else if (is_pci_ioaddr(port))
61 v = ctrl_inb(pci_ioaddr(port));
62 else
63 v = ctrl_inw(port) & 0xff;
64
65 ctrl_delay();
66
67 return v;
68}
69
70u16 r7780rp_inw(unsigned long port)
71{
72 if (is_pci_ioaddr(port))
73 return ctrl_inw(pci_ioaddr(port));
74
75 return ctrl_inw(port);
76}
77
78u32 r7780rp_inl(unsigned long port)
79{
80 if (is_pci_ioaddr(port))
81 return ctrl_inl(pci_ioaddr(port));
82
83 return ctrl_inl(port);
84}
85
86void r7780rp_outb(u8 value, unsigned long port)
87{
88 if (CHECK_AX88796L_PORT(port))
89 ctrl_outw(value, port88796l(port, 0));
90 else if (is_pci_ioaddr(port))
91 ctrl_outb(value, pci_ioaddr(port));
92 else
93 ctrl_outb(value, port);
94}
95
96void r7780rp_outb_p(u8 value, unsigned long port)
97{
98 if (CHECK_AX88796L_PORT(port))
99 ctrl_outw(value, port88796l(port, 0));
100 else if (is_pci_ioaddr(port))
101 ctrl_outb(value, pci_ioaddr(port));
102 else
103 ctrl_outb(value, port);
104
105 ctrl_delay();
106}
107
108void r7780rp_outw(u16 value, unsigned long port)
109{
110 if (is_pci_ioaddr(port))
111 ctrl_outw(value, pci_ioaddr(port));
112 else
113 ctrl_outw(value, port);
114}
115
116void r7780rp_outl(u32 value, unsigned long port)
117{
118 if (is_pci_ioaddr(port))
119 ctrl_outl(value, pci_ioaddr(port));
120 else
121 ctrl_outl(value, port);
122}
123
124void r7780rp_insb(unsigned long port, void *dst, unsigned long count)
125{
126 volatile u16 *p;
127 u8 *buf = dst;
128
129 if (CHECK_AX88796L_PORT(port)) {
130 p = (volatile u16 *)port88796l(port, 0);
131 while (count--)
132 *buf++ = *p & 0xff;
133 } else if (is_pci_ioaddr(port)) {
134 volatile u8 *bp = (volatile u8 *)pci_ioaddr(port);
135
136 while (count--)
137 *buf++ = *bp;
138 } else {
139 p = (volatile u16 *)port;
140 while (count--)
141 *buf++ = *p & 0xff;
142 }
143}
144
145void r7780rp_insw(unsigned long port, void *dst, unsigned long count)
146{
147 volatile u16 *p;
148 u16 *buf = dst;
149
150 if (CHECK_AX88796L_PORT(port))
151 p = (volatile u16 *)port88796l(port, 1);
152 else if (is_pci_ioaddr(port))
153 p = (volatile u16 *)pci_ioaddr(port);
154 else
155 p = (volatile u16 *)port;
156
157 while (count--)
158 *buf++ = *p;
159
160 flush_dcache_all();
161}
162
163void r7780rp_insl(unsigned long port, void *dst, unsigned long count)
164{
165 if (is_pci_ioaddr(port)) {
166 volatile u32 *p = (volatile u32 *)pci_ioaddr(port);
167 u32 *buf = dst;
168
169 while (count--)
170 *buf++ = *p;
171 }
172}
173
174void r7780rp_outsb(unsigned long port, const void *src, unsigned long count)
175{
176 volatile u16 *p;
177 const u8 *buf = src;
178
179 if (CHECK_AX88796L_PORT(port)) {
180 p = (volatile u16 *)port88796l(port, 0);
181 while (count--)
182 *p = *buf++;
183 } else if (is_pci_ioaddr(port)) {
184 volatile u8 *bp = (volatile u8 *)pci_ioaddr(port);
185
186 while (count--)
187 *bp = *buf++;
188 } else
189 while (count--)
190 ctrl_outb(*buf++, port);
191}
192
193void r7780rp_outsw(unsigned long port, const void *src, unsigned long count)
194{
195 volatile u16 *p;
196 const u16 *buf = src;
197
198 if (CHECK_AX88796L_PORT(port))
199 p = (volatile u16 *)port88796l(port, 1);
200 else if (is_pci_ioaddr(port))
201 p = (volatile u16 *)pci_ioaddr(port);
202 else
203 p = (volatile u16 *)port;
204
205 while (count--)
206 *p = *buf++;
207
208 flush_dcache_all();
209}
210
211void r7780rp_outsl(unsigned long port, const void *src, unsigned long count)
212{
213 const u32 *buf = src;
214 u32 *p;
215
216 if (is_pci_ioaddr(port))
217 p = (u32 *)pci_ioaddr(port);
218 else
219 p = (u32 *)port;
220
221 while (count--)
222 ctrl_outl(*buf++, (unsigned long)p);
223}
224
225void __iomem *r7780rp_ioport_map(unsigned long port, unsigned int size)
226{
227 if (CHECK_AX88796L_PORT(port))
228 return (void __iomem *)port88796l(port, size > 1);
229 else if (is_pci_ioaddr(port))
230 return (void __iomem *)pci_ioaddr(port);
231
232 return (void __iomem *)port;
233}
diff --git a/arch/sh/boards/renesas/r7780rp/setup.c b/arch/sh/boards/renesas/r7780rp/setup.c
index 0d74db9f1792..2faba6679e64 100644
--- a/arch/sh/boards/renesas/r7780rp/setup.c
+++ b/arch/sh/boards/renesas/r7780rp/setup.c
@@ -187,31 +187,7 @@ static void __init r7780rp_setup(char **cmdline_p)
187struct sh_machine_vector mv_r7780rp __initmv = { 187struct sh_machine_vector mv_r7780rp __initmv = {
188 .mv_name = "Highlander R7780RP-1", 188 .mv_name = "Highlander R7780RP-1",
189 .mv_setup = r7780rp_setup, 189 .mv_setup = r7780rp_setup,
190
191 .mv_nr_irqs = 109, 190 .mv_nr_irqs = 109,
192
193 .mv_inb = r7780rp_inb,
194 .mv_inw = r7780rp_inw,
195 .mv_inl = r7780rp_inl,
196 .mv_outb = r7780rp_outb,
197 .mv_outw = r7780rp_outw,
198 .mv_outl = r7780rp_outl,
199
200 .mv_inb_p = r7780rp_inb_p,
201 .mv_inw_p = r7780rp_inw,
202 .mv_inl_p = r7780rp_inl,
203 .mv_outb_p = r7780rp_outb_p,
204 .mv_outw_p = r7780rp_outw,
205 .mv_outl_p = r7780rp_outl,
206
207 .mv_insb = r7780rp_insb,
208 .mv_insw = r7780rp_insw,
209 .mv_insl = r7780rp_insl,
210 .mv_outsb = r7780rp_outsb,
211 .mv_outsw = r7780rp_outsw,
212 .mv_outsl = r7780rp_outsl,
213
214 .mv_ioport_map = r7780rp_ioport_map,
215 .mv_init_irq = init_r7780rp_IRQ, 191 .mv_init_irq = init_r7780rp_IRQ,
216}; 192};
217ALIAS_MV(r7780rp) 193ALIAS_MV(r7780rp)
diff --git a/arch/sh/boards/renesas/rts7751r2d/setup.c b/arch/sh/boards/renesas/rts7751r2d/setup.c
index 44b42082a0af..593f26a85e9c 100644
--- a/arch/sh/boards/renesas/rts7751r2d/setup.c
+++ b/arch/sh/boards/renesas/rts7751r2d/setup.c
@@ -12,6 +12,7 @@
12#include <linux/platform_device.h> 12#include <linux/platform_device.h>
13#include <linux/pata_platform.h> 13#include <linux/pata_platform.h>
14#include <linux/serial_8250.h> 14#include <linux/serial_8250.h>
15#include <linux/sm501.h>
15#include <linux/pm.h> 16#include <linux/pm.h>
16#include <asm/machvec.h> 17#include <asm/machvec.h>
17#include <asm/rts7751r2d.h> 18#include <asm/rts7751r2d.h>
@@ -111,10 +112,35 @@ static struct platform_device heartbeat_device = {
111 .resource = heartbeat_resources, 112 .resource = heartbeat_resources,
112}; 113};
113 114
115static struct resource sm501_resources[] = {
116 [0] = {
117 .start = 0x10000000,
118 .end = 0x13e00000 - 1,
119 .flags = IORESOURCE_MEM,
120 },
121 [1] = {
122 .start = 0x13e00000,
123 .end = 0x13ffffff,
124 .flags = IORESOURCE_MEM,
125 },
126 [2] = {
127 .start = 32,
128 .flags = IORESOURCE_IRQ,
129 },
130};
131
132static struct platform_device sm501_device = {
133 .name = "sm501",
134 .id = -1,
135 .num_resources = ARRAY_SIZE(sm501_resources),
136 .resource = sm501_resources,
137};
138
114static struct platform_device *rts7751r2d_devices[] __initdata = { 139static struct platform_device *rts7751r2d_devices[] __initdata = {
115 &uart_device, 140 &uart_device,
116 &heartbeat_device, 141 &heartbeat_device,
117 &cf_ide_device, 142 &cf_ide_device,
143 &sm501_device,
118}; 144};
119 145
120static int __init rts7751r2d_devices_setup(void) 146static int __init rts7751r2d_devices_setup(void)
diff --git a/arch/sh/configs/rts7751r2d_defconfig b/arch/sh/configs/rts7751r2d_defconfig
index db6a02df5af6..a59bb78bd071 100644
--- a/arch/sh/configs/rts7751r2d_defconfig
+++ b/arch/sh/configs/rts7751r2d_defconfig
@@ -1,14 +1,13 @@
1# 1#
2# Automatically generated make config: don't edit 2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.20 3# Linux kernel version: 2.6.21-rc1
4# Thu Feb 15 17:17:29 2007 4# Thu Mar 1 16:42:40 2007
5# 5#
6CONFIG_SUPERH=y 6CONFIG_SUPERH=y
7CONFIG_RWSEM_GENERIC_SPINLOCK=y 7CONFIG_RWSEM_GENERIC_SPINLOCK=y
8CONFIG_GENERIC_FIND_NEXT_BIT=y 8CONFIG_GENERIC_FIND_NEXT_BIT=y
9CONFIG_GENERIC_HWEIGHT=y 9CONFIG_GENERIC_HWEIGHT=y
10CONFIG_GENERIC_HARDIRQS=y 10CONFIG_GENERIC_HARDIRQS=y
11CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
12CONFIG_GENERIC_IRQ_PROBE=y 11CONFIG_GENERIC_IRQ_PROBE=y
13CONFIG_GENERIC_CALIBRATE_DELAY=y 12CONFIG_GENERIC_CALIBRATE_DELAY=y
14# CONFIG_GENERIC_TIME is not set 13# CONFIG_GENERIC_TIME is not set
@@ -33,6 +32,7 @@ CONFIG_LOCALVERSION_AUTO=y
33CONFIG_SWAP=y 32CONFIG_SWAP=y
34CONFIG_SYSVIPC=y 33CONFIG_SYSVIPC=y
35# CONFIG_IPC_NS is not set 34# CONFIG_IPC_NS is not set
35CONFIG_SYSVIPC_SYSCTL=y
36# CONFIG_POSIX_MQUEUE is not set 36# CONFIG_POSIX_MQUEUE is not set
37# CONFIG_BSD_PROCESS_ACCT is not set 37# CONFIG_BSD_PROCESS_ACCT is not set
38# CONFIG_TASKSTATS is not set 38# CONFIG_TASKSTATS is not set
@@ -119,7 +119,6 @@ CONFIG_SH_RTS7751R2D=y
119# CONFIG_SH_SHMIN is not set 119# CONFIG_SH_SHMIN is not set
120# CONFIG_SH_7206_SOLUTION_ENGINE is not set 120# CONFIG_SH_7206_SOLUTION_ENGINE is not set
121# CONFIG_SH_7619_SOLUTION_ENGINE is not set 121# CONFIG_SH_7619_SOLUTION_ENGINE is not set
122# CONFIG_SH_ASDAP310 is not set
123# CONFIG_SH_UNKNOWN is not set 122# CONFIG_SH_UNKNOWN is not set
124 123
125# 124#
@@ -281,7 +280,7 @@ CONFIG_ZERO_PAGE_OFFSET=0x00010000
281CONFIG_BOOT_LINK_OFFSET=0x00800000 280CONFIG_BOOT_LINK_OFFSET=0x00800000
282# CONFIG_UBC_WAKEUP is not set 281# CONFIG_UBC_WAKEUP is not set
283CONFIG_CMDLINE_BOOL=y 282CONFIG_CMDLINE_BOOL=y
284CONFIG_CMDLINE="console=ttySC0,115200 root=/dev/sda1" 283CONFIG_CMDLINE="console=tty0 console=ttySC0,115200 root=/dev/sda1"
285 284
286# 285#
287# Bus options 286# Bus options
@@ -433,6 +432,7 @@ CONFIG_FW_LOADER=m
433# 432#
434# Plug and Play support 433# Plug and Play support
435# 434#
435# CONFIG_PNPACPI is not set
436 436
437# 437#
438# Block devices 438# Block devices
@@ -770,7 +770,26 @@ CONFIG_NET_WIRELESS=y
770# 770#
771# Input device support 771# Input device support
772# 772#
773# CONFIG_INPUT is not set 773CONFIG_INPUT=y
774# CONFIG_INPUT_FF_MEMLESS is not set
775
776#
777# Userland interfaces
778#
779# CONFIG_INPUT_MOUSEDEV is not set
780# CONFIG_INPUT_JOYDEV is not set
781# CONFIG_INPUT_TSDEV is not set
782# CONFIG_INPUT_EVDEV is not set
783# CONFIG_INPUT_EVBUG is not set
784
785#
786# Input Device Drivers
787#
788# CONFIG_INPUT_KEYBOARD is not set
789# CONFIG_INPUT_MOUSE is not set
790# CONFIG_INPUT_JOYSTICK is not set
791# CONFIG_INPUT_TOUCHSCREEN is not set
792# CONFIG_INPUT_MISC is not set
774 793
775# 794#
776# Hardware I/O ports 795# Hardware I/O ports
@@ -781,7 +800,10 @@ CONFIG_NET_WIRELESS=y
781# 800#
782# Character devices 801# Character devices
783# 802#
784# CONFIG_VT is not set 803CONFIG_VT=y
804CONFIG_VT_CONSOLE=y
805CONFIG_HW_CONSOLE=y
806CONFIG_VT_HW_CONSOLE_BINDING=y
785# CONFIG_SERIAL_NONSTANDARD is not set 807# CONFIG_SERIAL_NONSTANDARD is not set
786 808
787# 809#
@@ -857,6 +879,11 @@ CONFIG_HWMON=y
857# CONFIG_HWMON_DEBUG_CHIP is not set 879# CONFIG_HWMON_DEBUG_CHIP is not set
858 880
859# 881#
882# Multifunction device drivers
883#
884CONFIG_MFD_SM501=y
885
886#
860# Multimedia devices 887# Multimedia devices
861# 888#
862# CONFIG_VIDEO_DEV is not set 889# CONFIG_VIDEO_DEV is not set
@@ -869,9 +896,66 @@ CONFIG_HWMON=y
869# 896#
870# Graphics support 897# Graphics support
871# 898#
872CONFIG_FIRMWARE_EDID=y
873# CONFIG_FB is not set
874# CONFIG_BACKLIGHT_LCD_SUPPORT is not set 899# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
900CONFIG_FB=y
901# CONFIG_FIRMWARE_EDID is not set
902# CONFIG_FB_DDC is not set
903CONFIG_FB_CFB_FILLRECT=y
904CONFIG_FB_CFB_COPYAREA=y
905CONFIG_FB_CFB_IMAGEBLIT=y
906# CONFIG_FB_SVGALIB is not set
907# CONFIG_FB_MACMODES is not set
908# CONFIG_FB_BACKLIGHT is not set
909# CONFIG_FB_MODE_HELPERS is not set
910# CONFIG_FB_TILEBLITTING is not set
911
912#
913# Frambuffer hardware drivers
914#
915# CONFIG_FB_CIRRUS is not set
916# CONFIG_FB_PM2 is not set
917# CONFIG_FB_CYBER2000 is not set
918# CONFIG_FB_ASILIANT is not set
919# CONFIG_FB_IMSTT is not set
920# CONFIG_FB_EPSON1355 is not set
921# CONFIG_FB_S1D13XXX is not set
922# CONFIG_FB_NVIDIA is not set
923# CONFIG_FB_RIVA is not set
924# CONFIG_FB_MATROX is not set
925# CONFIG_FB_RADEON is not set
926# CONFIG_FB_ATY128 is not set
927# CONFIG_FB_ATY is not set
928# CONFIG_FB_S3 is not set
929# CONFIG_FB_SAVAGE is not set
930# CONFIG_FB_SIS is not set
931# CONFIG_FB_NEOMAGIC is not set
932# CONFIG_FB_KYRO is not set
933# CONFIG_FB_3DFX is not set
934# CONFIG_FB_VOODOO1 is not set
935# CONFIG_FB_TRIDENT is not set
936CONFIG_FB_SM501=y
937# CONFIG_FB_VIRTUAL is not set
938
939#
940# Console display driver support
941#
942CONFIG_DUMMY_CONSOLE=y
943CONFIG_FRAMEBUFFER_CONSOLE=y
944# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
945# CONFIG_FONTS is not set
946CONFIG_FONT_8x8=y
947CONFIG_FONT_8x16=y
948
949#
950# Logo configuration
951#
952CONFIG_LOGO=y
953# CONFIG_LOGO_LINUX_MONO is not set
954# CONFIG_LOGO_LINUX_VGA16 is not set
955# CONFIG_LOGO_LINUX_CLUT224 is not set
956# CONFIG_LOGO_SUPERH_MONO is not set
957# CONFIG_LOGO_SUPERH_VGA16 is not set
958CONFIG_LOGO_SUPERH_CLUT224=y
875 959
876# 960#
877# Sound 961# Sound
@@ -985,6 +1069,12 @@ CONFIG_SOUND_PRIME=m
985CONFIG_AC97_BUS=m 1069CONFIG_AC97_BUS=m
986 1070
987# 1071#
1072# HID Devices
1073#
1074CONFIG_HID=y
1075# CONFIG_HID_DEBUG is not set
1076
1077#
988# USB support 1078# USB support
989# 1079#
990CONFIG_USB_ARCH_HAS_HCD=y 1080CONFIG_USB_ARCH_HAS_HCD=y
@@ -1237,7 +1327,7 @@ CONFIG_LOG_BUF_SHIFT=14
1237CONFIG_EARLY_SCIF_CONSOLE=y 1327CONFIG_EARLY_SCIF_CONSOLE=y
1238CONFIG_EARLY_SCIF_CONSOLE_PORT=0xffe80000 1328CONFIG_EARLY_SCIF_CONSOLE_PORT=0xffe80000
1239CONFIG_EARLY_PRINTK=y 1329CONFIG_EARLY_PRINTK=y
1240# CONFIG_KGDB is not set 1330# CONFIG_SH_KGDB is not set
1241 1331
1242# 1332#
1243# Security options 1333# Security options
diff --git a/arch/sh/kernel/entry-common.S b/arch/sh/kernel/entry-common.S
index ab4ebb856c2a..b46728027195 100644
--- a/arch/sh/kernel/entry-common.S
+++ b/arch/sh/kernel/entry-common.S
@@ -224,7 +224,7 @@ work_resched:
224syscall_exit_work: 224syscall_exit_work:
225 ! r0: current_thread_info->flags 225 ! r0: current_thread_info->flags
226 ! r8: current_thread_info 226 ! r8: current_thread_info
227 tst #_TIF_SYSCALL_TRACE, r0 227 tst #_TIF_SYSCALL_TRACE | _TIF_SINGLESTEP, r0
228 bt/s work_pending 228 bt/s work_pending
229 tst #_TIF_NEED_RESCHED, r0 229 tst #_TIF_NEED_RESCHED, r0
230#ifdef CONFIG_TRACE_IRQFLAGS 230#ifdef CONFIG_TRACE_IRQFLAGS
diff --git a/arch/sh/kernel/io_generic.c b/arch/sh/kernel/io_generic.c
index 66626c03e1ee..771ea4230441 100644
--- a/arch/sh/kernel/io_generic.c
+++ b/arch/sh/kernel/io_generic.c
@@ -14,7 +14,6 @@
14#include <linux/module.h> 14#include <linux/module.h>
15#include <linux/io.h> 15#include <linux/io.h>
16#include <asm/machvec.h> 16#include <asm/machvec.h>
17#include <asm/cacheflush.h>
18 17
19#ifdef CONFIG_CPU_SH3 18#ifdef CONFIG_CPU_SH3
20/* SH3 has a PCMCIA bug that needs a dummy read from area 6 for a 19/* SH3 has a PCMCIA bug that needs a dummy read from area 6 for a
@@ -96,7 +95,6 @@ void generic_insw(unsigned long port, void *dst, unsigned long count)
96 while (count--) 95 while (count--)
97 *buf++ = *port_addr; 96 *buf++ = *port_addr;
98 97
99 flush_dcache_all();
100 dummy_read(); 98 dummy_read();
101} 99}
102 100
@@ -171,7 +169,6 @@ void generic_outsw(unsigned long port, const void *src, unsigned long count)
171 while (count--) 169 while (count--)
172 *port_addr = *buf++; 170 *port_addr = *buf++;
173 171
174 flush_dcache_all();
175 dummy_read(); 172 dummy_read();
176} 173}
177 174
diff --git a/arch/sh/kernel/process.c b/arch/sh/kernel/process.c
index 9d6a438b3eaf..e7607366ac4e 100644
--- a/arch/sh/kernel/process.c
+++ b/arch/sh/kernel/process.c
@@ -250,12 +250,11 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
250 childregs->regs[15] = usp; 250 childregs->regs[15] = usp;
251 ti->addr_limit = USER_DS; 251 ti->addr_limit = USER_DS;
252 } else { 252 } else {
253 childregs->regs[15] = (unsigned long)task_stack_page(p) + 253 childregs->regs[15] = (unsigned long)childregs;
254 THREAD_SIZE;
255 ti->addr_limit = KERNEL_DS; 254 ti->addr_limit = KERNEL_DS;
256 } 255 }
257 256
258 if (clone_flags & CLONE_SETTLS) 257 if (clone_flags & CLONE_SETTLS)
259 childregs->gbr = childregs->regs[0]; 258 childregs->gbr = childregs->regs[0];
260 259
261 childregs->regs[0] = 0; /* Set return value for child */ 260 childregs->regs[0] = 0; /* Set return value for child */
diff --git a/arch/sh/kernel/ptrace.c b/arch/sh/kernel/ptrace.c
index 04ca13a041c1..855f7246cfff 100644
--- a/arch/sh/kernel/ptrace.c
+++ b/arch/sh/kernel/ptrace.c
@@ -8,7 +8,6 @@
8 * SuperH version: Copyright (C) 1999, 2000 Kaz Kojima & Niibe Yutaka 8 * SuperH version: Copyright (C) 1999, 2000 Kaz Kojima & Niibe Yutaka
9 * 9 *
10 */ 10 */
11
12#include <linux/kernel.h> 11#include <linux/kernel.h>
13#include <linux/sched.h> 12#include <linux/sched.h>
14#include <linux/mm.h> 13#include <linux/mm.h>
@@ -20,8 +19,7 @@
20#include <linux/slab.h> 19#include <linux/slab.h>
21#include <linux/security.h> 20#include <linux/security.h>
22#include <linux/signal.h> 21#include <linux/signal.h>
23 22#include <linux/io.h>
24#include <asm/io.h>
25#include <asm/uaccess.h> 23#include <asm/uaccess.h>
26#include <asm/pgtable.h> 24#include <asm/pgtable.h>
27#include <asm/system.h> 25#include <asm/system.h>
@@ -59,6 +57,23 @@ static inline int put_stack_long(struct task_struct *task, int offset,
59 return 0; 57 return 0;
60} 58}
61 59
60static void ptrace_disable_singlestep(struct task_struct *child)
61{
62 clear_tsk_thread_flag(child, TIF_SINGLESTEP);
63
64 /*
65 * Ensure the UBC is not programmed at the next context switch.
66 *
67 * Normally this is not needed but there are sequences such as
68 * singlestep, signal delivery, and continue that leave the
69 * ubc_pc non-zero leading to spurious SIGTRAPs.
70 */
71 if (child->thread.ubc_pc != 0) {
72 ubc_usercnt -= 1;
73 child->thread.ubc_pc = 0;
74 }
75}
76
62/* 77/*
63 * Called by kernel/ptrace.c when detaching.. 78 * Called by kernel/ptrace.c when detaching..
64 * 79 *
@@ -66,7 +81,7 @@ static inline int put_stack_long(struct task_struct *task, int offset,
66 */ 81 */
67void ptrace_disable(struct task_struct *child) 82void ptrace_disable(struct task_struct *child)
68{ 83{
69 /* nothing to do.. */ 84 ptrace_disable_singlestep(child);
70} 85}
71 86
72long arch_ptrace(struct task_struct *child, long request, long addr, long data) 87long arch_ptrace(struct task_struct *child, long request, long addr, long data)
@@ -76,7 +91,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
76 91
77 switch (request) { 92 switch (request) {
78 /* when I and D space are separate, these will need to be fixed. */ 93 /* when I and D space are separate, these will need to be fixed. */
79 case PTRACE_PEEKTEXT: /* read word at location addr. */ 94 case PTRACE_PEEKTEXT: /* read word at location addr. */
80 case PTRACE_PEEKDATA: { 95 case PTRACE_PEEKDATA: {
81 unsigned long tmp; 96 unsigned long tmp;
82 int copied; 97 int copied;
@@ -94,7 +109,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
94 unsigned long tmp; 109 unsigned long tmp;
95 110
96 ret = -EIO; 111 ret = -EIO;
97 if ((addr & 3) || addr < 0 || 112 if ((addr & 3) || addr < 0 ||
98 addr > sizeof(struct user) - 3) 113 addr > sizeof(struct user) - 3)
99 break; 114 break;
100 115
@@ -129,7 +144,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
129 144
130 case PTRACE_POKEUSR: /* write the word at location addr in the USER area */ 145 case PTRACE_POKEUSR: /* write the word at location addr in the USER area */
131 ret = -EIO; 146 ret = -EIO;
132 if ((addr & 3) || addr < 0 || 147 if ((addr & 3) || addr < 0 ||
133 addr > sizeof(struct user) - 3) 148 addr > sizeof(struct user) - 3)
134 break; 149 break;
135 150
@@ -156,6 +171,9 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
156 set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); 171 set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
157 else 172 else
158 clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); 173 clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
174
175 ptrace_disable_singlestep(child);
176
159 child->exit_code = data; 177 child->exit_code = data;
160 wake_up_process(child); 178 wake_up_process(child);
161 ret = 0; 179 ret = 0;
@@ -163,14 +181,15 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
163 } 181 }
164 182
165/* 183/*
166 * make the child exit. Best I can do is send it a sigkill. 184 * make the child exit. Best I can do is send it a sigkill.
167 * perhaps it should be put in the status that it wants to 185 * perhaps it should be put in the status that it wants to
168 * exit. 186 * exit.
169 */ 187 */
170 case PTRACE_KILL: { 188 case PTRACE_KILL: {
171 ret = 0; 189 ret = 0;
172 if (child->exit_state == EXIT_ZOMBIE) /* already dead */ 190 if (child->exit_state == EXIT_ZOMBIE) /* already dead */
173 break; 191 break;
192 ptrace_disable_singlestep(child);
174 child->exit_code = SIGKILL; 193 child->exit_code = SIGKILL;
175 wake_up_process(child); 194 wake_up_process(child);
176 break; 195 break;
@@ -196,6 +215,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
196 ubc_usercnt += 1; 215 ubc_usercnt += 1;
197 child->thread.ubc_pc = pc; 216 child->thread.ubc_pc = pc;
198 217
218 set_tsk_thread_flag(child, TIF_SINGLESTEP);
199 child->exit_code = data; 219 child->exit_code = data;
200 /* give it a chance to run. */ 220 /* give it a chance to run. */
201 wake_up_process(child); 221 wake_up_process(child);
@@ -248,14 +268,15 @@ asmlinkage void do_syscall_trace(void)
248{ 268{
249 struct task_struct *tsk = current; 269 struct task_struct *tsk = current;
250 270
251 if (!test_thread_flag(TIF_SYSCALL_TRACE)) 271 if (!test_thread_flag(TIF_SYSCALL_TRACE) &&
272 !test_thread_flag(TIF_SINGLESTEP))
252 return; 273 return;
253 if (!(tsk->ptrace & PT_PTRACED)) 274 if (!(tsk->ptrace & PT_PTRACED))
254 return; 275 return;
255 /* the 0x80 provides a way for the tracing parent to distinguish 276 /* the 0x80 provides a way for the tracing parent to distinguish
256 between a syscall stop and SIGTRAP delivery */ 277 between a syscall stop and SIGTRAP delivery */
257 ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) 278 ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) &&
258 ? 0x80 : 0)); 279 !test_thread_flag(TIF_SINGLESTEP) ? 0x80 : 0));
259 280
260 /* 281 /*
261 * this isn't the same as continuing with a signal, but it will do 282 * this isn't the same as continuing with a signal, but it will do
diff --git a/arch/sh/kernel/signal.c b/arch/sh/kernel/signal.c
index 32f10a03fbb5..9f39ef1f73da 100644
--- a/arch/sh/kernel/signal.c
+++ b/arch/sh/kernel/signal.c
@@ -589,6 +589,8 @@ static void do_signal(struct pt_regs *regs, unsigned int save_r0)
589 if (test_thread_flag(TIF_RESTORE_SIGMASK)) 589 if (test_thread_flag(TIF_RESTORE_SIGMASK))
590 clear_thread_flag(TIF_RESTORE_SIGMASK); 590 clear_thread_flag(TIF_RESTORE_SIGMASK);
591 } 591 }
592
593 return;
592 } 594 }
593 595
594 no_signal: 596 no_signal:
@@ -598,7 +600,7 @@ static void do_signal(struct pt_regs *regs, unsigned int save_r0)
598 if (regs->regs[0] == -ERESTARTNOHAND || 600 if (regs->regs[0] == -ERESTARTNOHAND ||
599 regs->regs[0] == -ERESTARTSYS || 601 regs->regs[0] == -ERESTARTSYS ||
600 regs->regs[0] == -ERESTARTNOINTR) { 602 regs->regs[0] == -ERESTARTNOINTR) {
601 regs->regs[0] = save_r0; 603 regs->regs[0] = save_r0;
602 regs->pc -= 2; 604 regs->pc -= 2;
603 } else if (regs->regs[0] == -ERESTART_RESTARTBLOCK) { 605 } else if (regs->regs[0] == -ERESTART_RESTARTBLOCK) {
604 regs->pc -= 2; 606 regs->pc -= 2;
diff --git a/arch/sh/kernel/vmlinux.lds.S b/arch/sh/kernel/vmlinux.lds.S
index 75de165867a0..78a6c09875b2 100644
--- a/arch/sh/kernel/vmlinux.lds.S
+++ b/arch/sh/kernel/vmlinux.lds.S
@@ -3,6 +3,7 @@
3 * Written by Niibe Yutaka 3 * Written by Niibe Yutaka
4 */ 4 */
5#include <asm/thread_info.h> 5#include <asm/thread_info.h>
6#include <asm/cache.h>
6#include <asm-generic/vmlinux.lds.h> 7#include <asm-generic/vmlinux.lds.h>
7 8
8#ifdef CONFIG_CPU_LITTLE_ENDIAN 9#ifdef CONFIG_CPU_LITTLE_ENDIAN
@@ -53,7 +54,7 @@ SECTIONS
53 . = ALIGN(PAGE_SIZE); 54 . = ALIGN(PAGE_SIZE);
54 .data.page_aligned : { *(.data.page_aligned) } 55 .data.page_aligned : { *(.data.page_aligned) }
55 56
56 . = ALIGN(32); 57 . = ALIGN(L1_CACHE_BYTES);
57 __per_cpu_start = .; 58 __per_cpu_start = .;
58 .data.percpu : { *(.data.percpu) } 59 .data.percpu : { *(.data.percpu) }
59 __per_cpu_end = .; 60 __per_cpu_end = .;
diff --git a/arch/sh/mm/cache-sh4.c b/arch/sh/mm/cache-sh4.c
index e0cd4b7f4aeb..981b04089055 100644
--- a/arch/sh/mm/cache-sh4.c
+++ b/arch/sh/mm/cache-sh4.c
@@ -237,20 +237,10 @@ static inline void flush_cache_4096(unsigned long start,
237/* 237/*
238 * Write back & invalidate the D-cache of the page. 238 * Write back & invalidate the D-cache of the page.
239 * (To avoid "alias" issues) 239 * (To avoid "alias" issues)
240 *
241 * This uses a lazy write-back on UP, which is explicitly
242 * disabled on SMP.
243 */ 240 */
244void flush_dcache_page(struct page *page) 241void flush_dcache_page(struct page *page)
245{ 242{
246#ifndef CONFIG_SMP 243 if (test_bit(PG_mapped, &page->flags)) {
247 struct address_space *mapping = page_mapping(page);
248
249 if (mapping && !mapping_mapped(mapping))
250 set_bit(PG_dcache_dirty, &page->flags);
251 else
252#endif
253 {
254 unsigned long phys = PHYSADDR(page_address(page)); 244 unsigned long phys = PHYSADDR(page_address(page));
255 unsigned long addr = CACHE_OC_ADDRESS_ARRAY; 245 unsigned long addr = CACHE_OC_ADDRESS_ARRAY;
256 int i, n; 246 int i, n;
diff --git a/arch/sh/mm/cache-sh7705.c b/arch/sh/mm/cache-sh7705.c
index 31f8deb7a158..4896d7376926 100644
--- a/arch/sh/mm/cache-sh7705.c
+++ b/arch/sh/mm/cache-sh7705.c
@@ -3,11 +3,11 @@
3 * 3 *
4 * Copyright (C) 1999, 2000 Niibe Yutaka 4 * Copyright (C) 1999, 2000 Niibe Yutaka
5 * Copyright (C) 2004 Alex Song 5 * Copyright (C) 2004 Alex Song
6 * Copyright (C) 2006 Paul Mundt
7 * 6 *
8 * This file is subject to the terms and conditions of the GNU General Public 7 * This file is subject to the terms and conditions of the GNU General Public
9 * License. See the file "COPYING" in the main directory of this archive 8 * License. See the file "COPYING" in the main directory of this archive
10 * for more details. 9 * for more details.
10 *
11 */ 11 */
12#include <linux/init.h> 12#include <linux/init.h>
13#include <linux/mman.h> 13#include <linux/mman.h>
@@ -51,6 +51,7 @@ static inline void cache_wback_all(void)
51 51
52 if ((data & v) == v) 52 if ((data & v) == v)
53 ctrl_outl(data & ~v, addr); 53 ctrl_outl(data & ~v, addr);
54
54 } 55 }
55 56
56 addrstart += current_cpu_data.dcache.way_incr; 57 addrstart += current_cpu_data.dcache.way_incr;
@@ -127,11 +128,7 @@ static void __flush_dcache_page(unsigned long phys)
127 */ 128 */
128void flush_dcache_page(struct page *page) 129void flush_dcache_page(struct page *page)
129{ 130{
130 struct address_space *mapping = page_mapping(page); 131 if (test_bit(PG_mapped, &page->flags))
131
132 if (mapping && !mapping_mapped(mapping))
133 set_bit(PG_dcache_dirty, &page->flags);
134 else
135 __flush_dcache_page(PHYSADDR(page_address(page))); 132 __flush_dcache_page(PHYSADDR(page_address(page)));
136} 133}
137 134
diff --git a/arch/sh/mm/pg-sh4.c b/arch/sh/mm/pg-sh4.c
index 969efeceb928..df69da9ca69c 100644
--- a/arch/sh/mm/pg-sh4.c
+++ b/arch/sh/mm/pg-sh4.c
@@ -23,6 +23,7 @@ extern struct mutex p3map_mutex[];
23 */ 23 */
24void clear_user_page(void *to, unsigned long address, struct page *page) 24void clear_user_page(void *to, unsigned long address, struct page *page)
25{ 25{
26 __set_bit(PG_mapped, &page->flags);
26 if (((address ^ (unsigned long)to) & CACHE_ALIAS) == 0) 27 if (((address ^ (unsigned long)to) & CACHE_ALIAS) == 0)
27 clear_page(to); 28 clear_page(to);
28 else { 29 else {
@@ -58,6 +59,7 @@ void clear_user_page(void *to, unsigned long address, struct page *page)
58void copy_user_page(void *to, void *from, unsigned long address, 59void copy_user_page(void *to, void *from, unsigned long address,
59 struct page *page) 60 struct page *page)
60{ 61{
62 __set_bit(PG_mapped, &page->flags);
61 if (((address ^ (unsigned long)to) & CACHE_ALIAS) == 0) 63 if (((address ^ (unsigned long)to) & CACHE_ALIAS) == 0)
62 copy_page(to, from); 64 copy_page(to, from);
63 else { 65 else {
@@ -82,3 +84,23 @@ void copy_user_page(void *to, void *from, unsigned long address,
82 mutex_unlock(&p3map_mutex[(address & CACHE_ALIAS)>>12]); 84 mutex_unlock(&p3map_mutex[(address & CACHE_ALIAS)>>12]);
83 } 85 }
84} 86}
87
88/*
89 * For SH-4, we have our own implementation for ptep_get_and_clear
90 */
91inline pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
92{
93 pte_t pte = *ptep;
94
95 pte_clear(mm, addr, ptep);
96 if (!pte_not_present(pte)) {
97 unsigned long pfn = pte_pfn(pte);
98 if (pfn_valid(pfn)) {
99 struct page *page = pfn_to_page(pfn);
100 struct address_space *mapping = page_mapping(page);
101 if (!mapping || !mapping_writably_mapped(mapping))
102 __clear_bit(PG_mapped, &page->flags);
103 }
104 }
105 return pte;
106}
diff --git a/arch/sh/mm/pg-sh7705.c b/arch/sh/mm/pg-sh7705.c
index 887ab9d18ccd..a4b015f95a3a 100644
--- a/arch/sh/mm/pg-sh7705.c
+++ b/arch/sh/mm/pg-sh7705.c
@@ -7,7 +7,9 @@
7 * This file is subject to the terms and conditions of the GNU General Public 7 * This file is subject to the terms and conditions of the GNU General Public
8 * License. See the file "COPYING" in the main directory of this archive 8 * License. See the file "COPYING" in the main directory of this archive
9 * for more details. 9 * for more details.
10 *
10 */ 11 */
12
11#include <linux/init.h> 13#include <linux/init.h>
12#include <linux/mman.h> 14#include <linux/mman.h>
13#include <linux/mm.h> 15#include <linux/mm.h>
@@ -74,6 +76,7 @@ void clear_user_page(void *to, unsigned long address, struct page *pg)
74{ 76{
75 struct page *page = virt_to_page(to); 77 struct page *page = virt_to_page(to);
76 78
79 __set_bit(PG_mapped, &page->flags);
77 if (((address ^ (unsigned long)to) & CACHE_ALIAS) == 0) { 80 if (((address ^ (unsigned long)to) & CACHE_ALIAS) == 0) {
78 clear_page(to); 81 clear_page(to);
79 __flush_wback_region(to, PAGE_SIZE); 82 __flush_wback_region(to, PAGE_SIZE);
@@ -92,11 +95,12 @@ void clear_user_page(void *to, unsigned long address, struct page *pg)
92 * @from: P1 address 95 * @from: P1 address
93 * @address: U0 address to be mapped 96 * @address: U0 address to be mapped
94 */ 97 */
95void copy_user_page(void *to, void *from, unsigned long address, 98void copy_user_page(void *to, void *from, unsigned long address, struct page *pg)
96 struct page *pg)
97{ 99{
98 struct page *page = virt_to_page(to); 100 struct page *page = virt_to_page(to);
99 101
102
103 __set_bit(PG_mapped, &page->flags);
100 if (((address ^ (unsigned long)to) & CACHE_ALIAS) == 0) { 104 if (((address ^ (unsigned long)to) & CACHE_ALIAS) == 0) {
101 copy_page(to, from); 105 copy_page(to, from);
102 __flush_wback_region(to, PAGE_SIZE); 106 __flush_wback_region(to, PAGE_SIZE);
@@ -108,3 +112,26 @@ void copy_user_page(void *to, void *from, unsigned long address,
108 __flush_wback_region(to, PAGE_SIZE); 112 __flush_wback_region(to, PAGE_SIZE);
109 } 113 }
110} 114}
115
116/*
117 * For SH7705, we have our own implementation for ptep_get_and_clear
118 * Copied from pg-sh4.c
119 */
120inline pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
121{
122 pte_t pte = *ptep;
123
124 pte_clear(mm, addr, ptep);
125 if (!pte_not_present(pte)) {
126 unsigned long pfn = pte_pfn(pte);
127 if (pfn_valid(pfn)) {
128 struct page *page = pfn_to_page(pfn);
129 struct address_space *mapping = page_mapping(page);
130 if (!mapping || !mapping_writably_mapped(mapping))
131 __clear_bit(PG_mapped, &page->flags);
132 }
133 }
134
135 return pte;
136}
137
diff --git a/arch/sh/mm/tlb-flush.c b/arch/sh/mm/tlb-flush.c
index d2f7b4a2eb05..6f45c1f8a7fe 100644
--- a/arch/sh/mm/tlb-flush.c
+++ b/arch/sh/mm/tlb-flush.c
@@ -2,17 +2,15 @@
2 * TLB flushing operations for SH with an MMU. 2 * TLB flushing operations for SH with an MMU.
3 * 3 *
4 * Copyright (C) 1999 Niibe Yutaka 4 * Copyright (C) 1999 Niibe Yutaka
5 * Copyright (C) 2003 - 2006 Paul Mundt 5 * Copyright (C) 2003 Paul Mundt
6 * 6 *
7 * This file is subject to the terms and conditions of the GNU General Public 7 * This file is subject to the terms and conditions of the GNU General Public
8 * License. See the file "COPYING" in the main directory of this archive 8 * License. See the file "COPYING" in the main directory of this archive
9 * for more details. 9 * for more details.
10 */ 10 */
11#include <linux/mm.h> 11#include <linux/mm.h>
12#include <linux/io.h>
13#include <asm/mmu_context.h> 12#include <asm/mmu_context.h>
14#include <asm/tlbflush.h> 13#include <asm/tlbflush.h>
15#include <asm/cacheflush.h>
16 14
17void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page) 15void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
18{ 16{
@@ -140,54 +138,3 @@ void local_flush_tlb_all(void)
140 ctrl_barrier(); 138 ctrl_barrier();
141 local_irq_restore(flags); 139 local_irq_restore(flags);
142} 140}
143
144void update_mmu_cache(struct vm_area_struct *vma,
145 unsigned long address, pte_t pte)
146{
147 unsigned long flags;
148 unsigned long pteval;
149 unsigned long vpn;
150 struct page *page;
151 unsigned long pfn = pte_pfn(pte);
152 struct address_space *mapping;
153
154 if (!pfn_valid(pfn))
155 return;
156
157 page = pfn_to_page(pfn);
158 mapping = page_mapping(page);
159 if (mapping) {
160 unsigned long phys = pte_val(pte) & PTE_PHYS_MASK;
161 int dirty = test_and_clear_bit(PG_dcache_dirty, &page->flags);
162
163 if (dirty)
164 __flush_wback_region((void *)P1SEGADDR(phys),
165 PAGE_SIZE);
166 }
167
168 local_irq_save(flags);
169
170 /* Set PTEH register */
171 vpn = (address & MMU_VPN_MASK) | get_asid();
172 ctrl_outl(vpn, MMU_PTEH);
173
174 pteval = pte_val(pte);
175
176#ifdef CONFIG_CPU_HAS_PTEA
177 /* Set PTEA register */
178 /* TODO: make this look less hacky */
179 ctrl_outl(((pteval >> 28) & 0xe) | (pteval & 0x1), MMU_PTEA);
180#endif
181
182 /* Set PTEL register */
183 pteval &= _PAGE_FLAGS_HARDWARE_MASK; /* drop software flags */
184#if defined(CONFIG_SH_WRITETHROUGH) && defined(CONFIG_CPU_SH4)
185 pteval |= _PAGE_WT;
186#endif
187 /* conveniently, we want all the software flags to be 0 anyway */
188 ctrl_outl(pteval, MMU_PTEL);
189
190 /* Load the TLB */
191 asm volatile("ldtlb": /* no output */ : /* no input */ : "memory");
192 local_irq_restore(flags);
193}
diff --git a/arch/sh/mm/tlb-sh3.c b/arch/sh/mm/tlb-sh3.c
index e5e76eb7ee09..7fbfd5a11ffa 100644
--- a/arch/sh/mm/tlb-sh3.c
+++ b/arch/sh/mm/tlb-sh3.c
@@ -8,9 +8,69 @@
8 * 8 *
9 * Released under the terms of the GNU GPL v2.0. 9 * Released under the terms of the GNU GPL v2.0.
10 */ 10 */
11#include <linux/io.h> 11#include <linux/signal.h>
12#include <linux/sched.h>
13#include <linux/kernel.h>
14#include <linux/errno.h>
15#include <linux/string.h>
16#include <linux/types.h>
17#include <linux/ptrace.h>
18#include <linux/mman.h>
19#include <linux/mm.h>
20#include <linux/smp.h>
21#include <linux/smp_lock.h>
22#include <linux/interrupt.h>
23
12#include <asm/system.h> 24#include <asm/system.h>
25#include <asm/io.h>
26#include <asm/uaccess.h>
27#include <asm/pgalloc.h>
13#include <asm/mmu_context.h> 28#include <asm/mmu_context.h>
29#include <asm/cacheflush.h>
30
31void update_mmu_cache(struct vm_area_struct * vma,
32 unsigned long address, pte_t pte)
33{
34 unsigned long flags;
35 unsigned long pteval;
36 unsigned long vpn;
37
38 /* Ptrace may call this routine. */
39 if (vma && current->active_mm != vma->vm_mm)
40 return;
41
42#if defined(CONFIG_SH7705_CACHE_32KB)
43 {
44 struct page *page = pte_page(pte);
45 unsigned long pfn = pte_pfn(pte);
46
47 if (pfn_valid(pfn) && !test_bit(PG_mapped, &page->flags)) {
48 unsigned long phys = pte_val(pte) & PTE_PHYS_MASK;
49
50 __flush_wback_region((void *)P1SEGADDR(phys),
51 PAGE_SIZE);
52 __set_bit(PG_mapped, &page->flags);
53 }
54 }
55#endif
56
57 local_irq_save(flags);
58
59 /* Set PTEH register */
60 vpn = (address & MMU_VPN_MASK) | get_asid();
61 ctrl_outl(vpn, MMU_PTEH);
62
63 pteval = pte_val(pte);
64
65 /* Set PTEL register */
66 pteval &= _PAGE_FLAGS_HARDWARE_MASK; /* drop software flags */
67 /* conveniently, we want all the software flags to be 0 anyway */
68 ctrl_outl(pteval, MMU_PTEL);
69
70 /* Load the TLB */
71 asm volatile("ldtlb": /* no output */ : /* no input */ : "memory");
72 local_irq_restore(flags);
73}
14 74
15void local_flush_tlb_one(unsigned long asid, unsigned long page) 75void local_flush_tlb_one(unsigned long asid, unsigned long page)
16{ 76{
@@ -34,3 +94,4 @@ void local_flush_tlb_one(unsigned long asid, unsigned long page)
34 for (i = 0; i < ways; i++) 94 for (i = 0; i < ways; i++)
35 ctrl_outl(data, addr + (i << 8)); 95 ctrl_outl(data, addr + (i << 8));
36} 96}
97
diff --git a/arch/sh/mm/tlb-sh4.c b/arch/sh/mm/tlb-sh4.c
index 221e7095473d..f74cf667c8fa 100644
--- a/arch/sh/mm/tlb-sh4.c
+++ b/arch/sh/mm/tlb-sh4.c
@@ -8,9 +8,74 @@
8 * 8 *
9 * Released under the terms of the GNU GPL v2.0. 9 * Released under the terms of the GNU GPL v2.0.
10 */ 10 */
11#include <linux/io.h> 11#include <linux/signal.h>
12#include <linux/sched.h>
13#include <linux/kernel.h>
14#include <linux/errno.h>
15#include <linux/string.h>
16#include <linux/types.h>
17#include <linux/ptrace.h>
18#include <linux/mman.h>
19#include <linux/mm.h>
20#include <linux/smp.h>
21#include <linux/smp_lock.h>
22#include <linux/interrupt.h>
23
12#include <asm/system.h> 24#include <asm/system.h>
25#include <asm/io.h>
26#include <asm/uaccess.h>
27#include <asm/pgalloc.h>
13#include <asm/mmu_context.h> 28#include <asm/mmu_context.h>
29#include <asm/cacheflush.h>
30
31void update_mmu_cache(struct vm_area_struct * vma,
32 unsigned long address, pte_t pte)
33{
34 unsigned long flags;
35 unsigned long pteval;
36 unsigned long vpn;
37 struct page *page;
38 unsigned long pfn;
39
40 /* Ptrace may call this routine. */
41 if (vma && current->active_mm != vma->vm_mm)
42 return;
43
44 pfn = pte_pfn(pte);
45 if (pfn_valid(pfn)) {
46 page = pfn_to_page(pfn);
47 if (!test_bit(PG_mapped, &page->flags)) {
48 unsigned long phys = pte_val(pte) & PTE_PHYS_MASK;
49 __flush_wback_region((void *)P1SEGADDR(phys), PAGE_SIZE);
50 __set_bit(PG_mapped, &page->flags);
51 }
52 }
53
54 local_irq_save(flags);
55
56 /* Set PTEH register */
57 vpn = (address & MMU_VPN_MASK) | get_asid();
58 ctrl_outl(vpn, MMU_PTEH);
59
60 pteval = pte_val(pte);
61
62 /* Set PTEA register */
63 if (cpu_data->flags & CPU_HAS_PTEA)
64 /* TODO: make this look less hacky */
65 ctrl_outl(((pteval >> 28) & 0xe) | (pteval & 0x1), MMU_PTEA);
66
67 /* Set PTEL register */
68 pteval &= _PAGE_FLAGS_HARDWARE_MASK; /* drop software flags */
69#ifdef CONFIG_SH_WRITETHROUGH
70 pteval |= _PAGE_WT;
71#endif
72 /* conveniently, we want all the software flags to be 0 anyway */
73 ctrl_outl(pteval, MMU_PTEL);
74
75 /* Load the TLB */
76 asm volatile("ldtlb": /* no output */ : /* no input */ : "memory");
77 local_irq_restore(flags);
78}
14 79
15void local_flush_tlb_one(unsigned long asid, unsigned long page) 80void local_flush_tlb_one(unsigned long asid, unsigned long page)
16{ 81{
@@ -28,3 +93,4 @@ void local_flush_tlb_one(unsigned long asid, unsigned long page)
28 ctrl_outl(data, addr); 93 ctrl_outl(data, addr);
29 back_to_P1(); 94 back_to_P1();
30} 95}
96
diff --git a/arch/um/drivers/daemon_user.c b/arch/um/drivers/daemon_user.c
index 310af0f1e49e..021b82c7a759 100644
--- a/arch/um/drivers/daemon_user.c
+++ b/arch/um/drivers/daemon_user.c
@@ -56,30 +56,31 @@ static int connect_to_switch(struct daemon_data *pri)
56 56
57 pri->control = socket(AF_UNIX, SOCK_STREAM, 0); 57 pri->control = socket(AF_UNIX, SOCK_STREAM, 0);
58 if(pri->control < 0){ 58 if(pri->control < 0){
59 err = -errno;
59 printk("daemon_open : control socket failed, errno = %d\n", 60 printk("daemon_open : control socket failed, errno = %d\n",
60 errno); 61 -err);
61 return(-errno); 62 return err;
62 } 63 }
63 64
64 if(connect(pri->control, (struct sockaddr *) ctl_addr, 65 if(connect(pri->control, (struct sockaddr *) ctl_addr,
65 sizeof(*ctl_addr)) < 0){ 66 sizeof(*ctl_addr)) < 0){
66 printk("daemon_open : control connect failed, errno = %d\n",
67 errno);
68 err = -errno; 67 err = -errno;
68 printk("daemon_open : control connect failed, errno = %d\n",
69 -err);
69 goto out; 70 goto out;
70 } 71 }
71 72
72 fd = socket(AF_UNIX, SOCK_DGRAM, 0); 73 fd = socket(AF_UNIX, SOCK_DGRAM, 0);
73 if(fd < 0){ 74 if(fd < 0){
74 printk("daemon_open : data socket failed, errno = %d\n",
75 errno);
76 err = -errno; 75 err = -errno;
76 printk("daemon_open : data socket failed, errno = %d\n",
77 -err);
77 goto out; 78 goto out;
78 } 79 }
79 if(bind(fd, (struct sockaddr *) local_addr, sizeof(*local_addr)) < 0){ 80 if(bind(fd, (struct sockaddr *) local_addr, sizeof(*local_addr)) < 0){
80 printk("daemon_open : data bind failed, errno = %d\n",
81 errno);
82 err = -errno; 81 err = -errno;
82 printk("daemon_open : data bind failed, errno = %d\n",
83 -err);
83 goto out_close; 84 goto out_close;
84 } 85 }
85 86
diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c
index 01d4ab6b0ef1..f75d7b05c481 100644
--- a/arch/um/drivers/line.c
+++ b/arch/um/drivers/line.c
@@ -370,10 +370,10 @@ static irqreturn_t line_write_interrupt(int irq, void *data)
370 struct tty_struct *tty = line->tty; 370 struct tty_struct *tty = line->tty;
371 int err; 371 int err;
372 372
373 /* Interrupts are enabled here because we registered the interrupt with 373 /* Interrupts are disabled here because we registered the interrupt with
374 * IRQF_DISABLED (see line_setup_irq).*/ 374 * IRQF_DISABLED (see line_setup_irq).*/
375 375
376 spin_lock_irq(&line->lock); 376 spin_lock(&line->lock);
377 err = flush_buffer(line); 377 err = flush_buffer(line);
378 if (err == 0) { 378 if (err == 0) {
379 return IRQ_NONE; 379 return IRQ_NONE;
@@ -381,7 +381,7 @@ static irqreturn_t line_write_interrupt(int irq, void *data)
381 line->head = line->buffer; 381 line->head = line->buffer;
382 line->tail = line->buffer; 382 line->tail = line->buffer;
383 } 383 }
384 spin_unlock_irq(&line->lock); 384 spin_unlock(&line->lock);
385 385
386 if(tty == NULL) 386 if(tty == NULL)
387 return IRQ_NONE; 387 return IRQ_NONE;
diff --git a/arch/um/drivers/mcast_user.c b/arch/um/drivers/mcast_user.c
index 8138f5ea1bf7..b827e82884c9 100644
--- a/arch/um/drivers/mcast_user.c
+++ b/arch/um/drivers/mcast_user.c
@@ -50,6 +50,14 @@ static void mcast_user_init(void *data, void *dev)
50 pri->dev = dev; 50 pri->dev = dev;
51} 51}
52 52
53static void mcast_remove(void *data)
54{
55 struct mcast_data *pri = data;
56
57 kfree(pri->mcast_addr);
58 pri->mcast_addr = NULL;
59}
60
53static int mcast_open(void *data) 61static int mcast_open(void *data)
54{ 62{
55 struct mcast_data *pri = data; 63 struct mcast_data *pri = data;
@@ -157,7 +165,7 @@ const struct net_user_info mcast_user_info = {
157 .init = mcast_user_init, 165 .init = mcast_user_init,
158 .open = mcast_open, 166 .open = mcast_open,
159 .close = mcast_close, 167 .close = mcast_close,
160 .remove = NULL, 168 .remove = mcast_remove,
161 .set_mtu = mcast_set_mtu, 169 .set_mtu = mcast_set_mtu,
162 .add_address = NULL, 170 .add_address = NULL,
163 .delete_address = NULL, 171 .delete_address = NULL,
diff --git a/arch/um/drivers/ssl.c b/arch/um/drivers/ssl.c
index fc22b9bd9153..4b382a6e710f 100644
--- a/arch/um/drivers/ssl.c
+++ b/arch/um/drivers/ssl.c
@@ -179,7 +179,7 @@ static struct console ssl_cons = {
179 .write = ssl_console_write, 179 .write = ssl_console_write,
180 .device = ssl_console_device, 180 .device = ssl_console_device,
181 .setup = ssl_console_setup, 181 .setup = ssl_console_setup,
182 .flags = CON_PRINTBUFFER, 182 .flags = CON_PRINTBUFFER|CON_ANYTIME,
183 .index = -1, 183 .index = -1,
184}; 184};
185 185
diff --git a/arch/um/drivers/stdio_console.c b/arch/um/drivers/stdio_console.c
index 7ff0b0fc37e7..76d1f1c980ef 100644
--- a/arch/um/drivers/stdio_console.c
+++ b/arch/um/drivers/stdio_console.c
@@ -153,7 +153,7 @@ static struct console stdiocons = {
153 .write = uml_console_write, 153 .write = uml_console_write,
154 .device = uml_console_device, 154 .device = uml_console_device,
155 .setup = uml_console_setup, 155 .setup = uml_console_setup,
156 .flags = CON_PRINTBUFFER, 156 .flags = CON_PRINTBUFFER|CON_ANYTIME,
157 .index = -1, 157 .index = -1,
158}; 158};
159 159
diff --git a/arch/um/include/os.h b/arch/um/include/os.h
index 8629bd191492..5c74da410451 100644
--- a/arch/um/include/os.h
+++ b/arch/um/include/os.h
@@ -192,7 +192,9 @@ extern int os_process_parent(int pid);
192extern void os_stop_process(int pid); 192extern void os_stop_process(int pid);
193extern void os_kill_process(int pid, int reap_child); 193extern void os_kill_process(int pid, int reap_child);
194extern void os_kill_ptraced_process(int pid, int reap_child); 194extern void os_kill_ptraced_process(int pid, int reap_child);
195#ifdef UML_CONFIG_MODE_TT
195extern void os_usr1_process(int pid); 196extern void os_usr1_process(int pid);
197#endif
196extern long os_ptrace_ldt(long pid, long addr, long data); 198extern long os_ptrace_ldt(long pid, long addr, long data);
197 199
198extern int os_getpid(void); 200extern int os_getpid(void);
@@ -261,7 +263,6 @@ extern void block_signals(void);
261extern void unblock_signals(void); 263extern void unblock_signals(void);
262extern int get_signals(void); 264extern int get_signals(void);
263extern int set_signals(int enable); 265extern int set_signals(int enable);
264extern void os_usr1_signal(int on);
265 266
266/* trap.c */ 267/* trap.c */
267extern void os_fill_handlinfo(struct kern_handlers h); 268extern void os_fill_handlinfo(struct kern_handlers h);
diff --git a/arch/um/kernel/irq.c b/arch/um/kernel/irq.c
index 50a288bb875a..dbf2f5bc842f 100644
--- a/arch/um/kernel/irq.c
+++ b/arch/um/kernel/irq.c
@@ -142,6 +142,7 @@ int activate_fd(int irq, int fd, int type, void *dev_id)
142 .events = events, 142 .events = events,
143 .current_events = 0 } ); 143 .current_events = 0 } );
144 144
145 err = -EBUSY;
145 spin_lock_irqsave(&irq_lock, flags); 146 spin_lock_irqsave(&irq_lock, flags);
146 for (irq_fd = active_fds; irq_fd != NULL; irq_fd = irq_fd->next) { 147 for (irq_fd = active_fds; irq_fd != NULL; irq_fd = irq_fd->next) {
147 if ((irq_fd->fd == fd) && (irq_fd->type == type)) { 148 if ((irq_fd->fd == fd) && (irq_fd->type == type)) {
diff --git a/arch/um/os-Linux/process.c b/arch/um/os-Linux/process.c
index c692a192957a..76bdd6712417 100644
--- a/arch/um/os-Linux/process.c
+++ b/arch/um/os-Linux/process.c
@@ -21,6 +21,7 @@
21#include "longjmp.h" 21#include "longjmp.h"
22#include "skas_ptrace.h" 22#include "skas_ptrace.h"
23#include "kern_constants.h" 23#include "kern_constants.h"
24#include "uml-config.h"
24 25
25#define ARBITRARY_ADDR -1 26#define ARBITRARY_ADDR -1
26#define FAILURE_PID -1 27#define FAILURE_PID -1
@@ -131,10 +132,12 @@ void os_kill_ptraced_process(int pid, int reap_child)
131 CATCH_EINTR(waitpid(pid, NULL, 0)); 132 CATCH_EINTR(waitpid(pid, NULL, 0));
132} 133}
133 134
135#ifdef UML_CONFIG_MODE_TT
134void os_usr1_process(int pid) 136void os_usr1_process(int pid)
135{ 137{
136 kill(pid, SIGUSR1); 138 kill(pid, SIGUSR1);
137} 139}
140#endif
138 141
139/* Don't use the glibc version, which caches the result in TLS. It misses some 142/* Don't use the glibc version, which caches the result in TLS. It misses some
140 * syscalls, and also breaks with clone(), which does not unshare the TLS. 143 * syscalls, and also breaks with clone(), which does not unshare the TLS.
diff --git a/arch/um/os-Linux/signal.c b/arch/um/os-Linux/signal.c
index b897e8592d77..266768629fee 100644
--- a/arch/um/os-Linux/signal.c
+++ b/arch/um/os-Linux/signal.c
@@ -243,8 +243,3 @@ int set_signals(int enable)
243 243
244 return ret; 244 return ret;
245} 245}
246
247void os_usr1_signal(int on)
248{
249 change_sig(SIGUSR1, on);
250}
diff --git a/arch/um/sys-x86_64/syscalls.c b/arch/um/sys-x86_64/syscalls.c
index 01b91f9fa789..b3f6350cac44 100644
--- a/arch/um/sys-x86_64/syscalls.c
+++ b/arch/um/sys-x86_64/syscalls.c
@@ -103,6 +103,9 @@ long arch_prctl_skas(struct task_struct *task, int code,
103 103
104 switch(code){ 104 switch(code){
105 case ARCH_SET_FS: 105 case ARCH_SET_FS:
106 current->thread.arch.fs = (unsigned long) ptr;
107 save_registers(pid, &current->thread.regs.regs);
108 break;
106 case ARCH_SET_GS: 109 case ARCH_SET_GS:
107 save_registers(pid, &current->thread.regs.regs); 110 save_registers(pid, &current->thread.regs.regs);
108 break; 111 break;
@@ -140,9 +143,8 @@ long sys_clone(unsigned long clone_flags, unsigned long newsp,
140 143
141void arch_switch_to_skas(struct task_struct *from, struct task_struct *to) 144void arch_switch_to_skas(struct task_struct *from, struct task_struct *to)
142{ 145{
143 if(to->thread.arch.fs == 0) 146 if((to->thread.arch.fs == 0) || (to->mm == NULL))
144 return; 147 return;
145 148
146 arch_prctl_skas(to, ARCH_SET_FS, (void __user *) to->thread.arch.fs); 149 arch_prctl_skas(to, ARCH_SET_FS, (void __user *) to->thread.arch.fs);
147} 150}
148
diff --git a/arch/x86_64/ia32/ptrace32.c b/arch/x86_64/ia32/ptrace32.c
index 04566fe5de49..4de3a54318f4 100644
--- a/arch/x86_64/ia32/ptrace32.c
+++ b/arch/x86_64/ia32/ptrace32.c
@@ -243,6 +243,7 @@ asmlinkage long sys32_ptrace(long request, u32 pid, u32 addr, u32 data)
243 case PTRACE_SINGLESTEP: 243 case PTRACE_SINGLESTEP:
244 case PTRACE_DETACH: 244 case PTRACE_DETACH:
245 case PTRACE_SYSCALL: 245 case PTRACE_SYSCALL:
246 case PTRACE_OLDSETOPTIONS:
246 case PTRACE_SETOPTIONS: 247 case PTRACE_SETOPTIONS:
247 case PTRACE_SET_THREAD_AREA: 248 case PTRACE_SET_THREAD_AREA:
248 case PTRACE_GET_THREAD_AREA: 249 case PTRACE_GET_THREAD_AREA:
diff --git a/arch/x86_64/kernel/early-quirks.c b/arch/x86_64/kernel/early-quirks.c
index 8047ea8c2ab2..dec587b293bf 100644
--- a/arch/x86_64/kernel/early-quirks.c
+++ b/arch/x86_64/kernel/early-quirks.c
@@ -30,11 +30,8 @@ static void via_bugs(void)
30 30
31#ifdef CONFIG_ACPI 31#ifdef CONFIG_ACPI
32 32
33static int nvidia_hpet_detected __initdata;
34
35static int __init nvidia_hpet_check(struct acpi_table_header *header) 33static int __init nvidia_hpet_check(struct acpi_table_header *header)
36{ 34{
37 nvidia_hpet_detected = 1;
38 return 0; 35 return 0;
39} 36}
40#endif 37#endif
@@ -52,11 +49,7 @@ static void nvidia_bugs(void)
52 if (acpi_use_timer_override) 49 if (acpi_use_timer_override)
53 return; 50 return;
54 51
55 nvidia_hpet_detected = 0; 52 if (acpi_table_parse(ACPI_SIG_HPET, nvidia_hpet_check)) {
56 if (acpi_table_parse(ACPI_SIG_HPET, nvidia_hpet_check))
57 return;
58
59 if (nvidia_hpet_detected == 0) {
60 acpi_skip_timer_override = 1; 53 acpi_skip_timer_override = 1;
61 printk(KERN_INFO "Nvidia board " 54 printk(KERN_INFO "Nvidia board "
62 "detected. Ignoring ACPI " 55 "detected. Ignoring ACPI "
diff --git a/arch/x86_64/kernel/smpboot.c b/arch/x86_64/kernel/smpboot.c
index 35443729aad8..cd4643a37022 100644
--- a/arch/x86_64/kernel/smpboot.c
+++ b/arch/x86_64/kernel/smpboot.c
@@ -923,8 +923,9 @@ void __init smp_prepare_boot_cpu(void)
923 */ 923 */
924int __cpuinit __cpu_up(unsigned int cpu) 924int __cpuinit __cpu_up(unsigned int cpu)
925{ 925{
926 int err;
927 int apicid = cpu_present_to_apicid(cpu); 926 int apicid = cpu_present_to_apicid(cpu);
927 unsigned long flags;
928 int err;
928 929
929 WARN_ON(irqs_disabled()); 930 WARN_ON(irqs_disabled());
930 931
@@ -958,7 +959,9 @@ int __cpuinit __cpu_up(unsigned int cpu)
958 /* 959 /*
959 * Make sure and check TSC sync: 960 * Make sure and check TSC sync:
960 */ 961 */
962 local_irq_save(flags);
961 check_tsc_sync_source(cpu); 963 check_tsc_sync_source(cpu);
964 local_irq_restore(flags);
962 965
963 while (!cpu_isset(cpu, cpu_online_map)) 966 while (!cpu_isset(cpu, cpu_online_map))
964 cpu_relax(); 967 cpu_relax();