aboutsummaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/frv/Kconfig4
-rw-r--r--arch/frv/Makefile2
-rw-r--r--arch/frv/kernel/break.S77
-rw-r--r--arch/frv/kernel/entry-table.S39
-rw-r--r--arch/frv/kernel/entry.S91
-rw-r--r--arch/frv/kernel/head.S3
-rw-r--r--arch/frv/kernel/irq.c41
-rw-r--r--arch/frv/mm/kmap.c9
-rw-r--r--arch/h8300/Kconfig4
-rw-r--r--arch/h8300/Kconfig.cpu2
-rw-r--r--arch/i386/boot/.gitignore3
-rw-r--r--arch/i386/boot/tools/.gitignore1
-rw-r--r--arch/i386/kernel/.gitignore1
-rw-r--r--arch/i386/kernel/vsyscall-sysenter.S15
-rw-r--r--arch/ia64/kernel/ia64_ksyms.c15
-rw-r--r--arch/ia64/kernel/time.c39
-rw-r--r--arch/ia64/kernel/traps.c8
-rw-r--r--arch/ia64/sn/kernel/io_init.c97
-rw-r--r--arch/ia64/sn/kernel/setup.c4
-rw-r--r--arch/ia64/sn/kernel/sn2/prominfo_proc.c25
-rw-r--r--arch/ia64/sn/kernel/sn2/sn2_smp.c35
-rw-r--r--arch/ia64/sn/kernel/sn2/sn_proc_fs.c22
-rw-r--r--arch/ia64/sn/kernel/sn2/timer.c19
-rw-r--r--arch/ia64/sn/kernel/sn2/timer_interrupt.c7
-rw-r--r--arch/ia64/sn/kernel/tiocx.c4
-rw-r--r--arch/ia64/sn/kernel/xpc_channel.c8
-rw-r--r--arch/ia64/sn/kernel/xpc_main.c20
-rw-r--r--arch/ia64/sn/pci/pci_dma.c16
-rw-r--r--arch/ia64/sn/pci/pcibr/pcibr_ate.c29
-rw-r--r--arch/ia64/sn/pci/pcibr/pcibr_dma.c14
-rw-r--r--arch/ia64/sn/pci/pcibr/pcibr_provider.c9
-rw-r--r--arch/m68k/Kconfig4
-rw-r--r--arch/m68knommu/Kconfig4
-rw-r--r--arch/mips/Makefile1
-rw-r--r--arch/mips/kernel/process.c158
-rw-r--r--arch/mips/kernel/signal-common.h2
-rw-r--r--arch/mips/kernel/signal32.c2
-rw-r--r--arch/mips/kernel/signal_n32.c2
-rw-r--r--arch/mips/kernel/smp_mt.c34
-rw-r--r--arch/mips/mm/c-r4k.c104
-rw-r--r--arch/mips/mm/c-tx39.c70
-rw-r--r--arch/parisc/Kconfig5
-rw-r--r--arch/s390/lib/delay.c2
-rw-r--r--arch/v850/Kconfig4
44 files changed, 522 insertions, 533 deletions
diff --git a/arch/frv/Kconfig b/arch/frv/Kconfig
index 60a617aff8b..e0838371237 100644
--- a/arch/frv/Kconfig
+++ b/arch/frv/Kconfig
@@ -25,6 +25,10 @@ config GENERIC_HARDIRQS
bool
default n
+config TIME_LOW_RES
+ bool
+ default y
+
mainmenu "Fujitsu FR-V Kernel Configuration"
source "init/Kconfig"
diff --git a/arch/frv/Makefile b/arch/frv/Makefile
index 90c0fb8d9dc..d163747d17c 100644
--- a/arch/frv/Makefile
+++ b/arch/frv/Makefile
@@ -81,7 +81,7 @@ endif
# - reserve CC3 for use with atomic ops
# - all the extra registers are dealt with only at context switch time
CFLAGS += -mno-fdpic -mgpr-32 -msoft-float -mno-media
-CFLAGS += -ffixed-fcc3 -ffixed-cc3 -ffixed-gr15
+CFLAGS += -ffixed-fcc3 -ffixed-cc3 -ffixed-gr15 -ffixed-icc2
AFLAGS += -mno-fdpic
ASFLAGS += -mno-fdpic
diff --git a/arch/frv/kernel/break.S b/arch/frv/kernel/break.S
index 33233dc23e2..687c48d62dd 100644
--- a/arch/frv/kernel/break.S
+++ b/arch/frv/kernel/break.S
@@ -200,12 +200,20 @@ __break_step:
movsg bpcsr,gr2
sethi.p %hi(__entry_kernel_external_interrupt),gr3
setlo %lo(__entry_kernel_external_interrupt),gr3
- subcc gr2,gr3,gr0,icc0
+ subcc.p gr2,gr3,gr0,icc0
+ sethi %hi(__entry_uspace_external_interrupt),gr3
+ setlo.p %lo(__entry_uspace_external_interrupt),gr3
beq icc0,#2,__break_step_kernel_external_interrupt
- sethi.p %hi(__entry_uspace_external_interrupt),gr3
- setlo %lo(__entry_uspace_external_interrupt),gr3
- subcc gr2,gr3,gr0,icc0
+ subcc.p gr2,gr3,gr0,icc0
+ sethi %hi(__entry_kernel_external_interrupt_virtually_disabled),gr3
+ setlo.p %lo(__entry_kernel_external_interrupt_virtually_disabled),gr3
beq icc0,#2,__break_step_uspace_external_interrupt
+ subcc.p gr2,gr3,gr0,icc0
+ sethi %hi(__entry_kernel_external_interrupt_virtual_reenable),gr3
+ setlo.p %lo(__entry_kernel_external_interrupt_virtual_reenable),gr3
+ beq icc0,#2,__break_step_kernel_external_interrupt_virtually_disabled
+ subcc gr2,gr3,gr0,icc0
+ beq icc0,#2,__break_step_kernel_external_interrupt_virtual_reenable
LEDS 0x2007,gr2
@@ -254,6 +262,9 @@ __break_step_kernel_softprog_interrupt:
# step through an external interrupt from kernel mode
.globl __break_step_kernel_external_interrupt
__break_step_kernel_external_interrupt:
+ # deal with virtual interrupt disablement
+ beq icc2,#0,__break_step_kernel_external_interrupt_virtually_disabled
+
sethi.p %hi(__entry_kernel_external_interrupt_reentry),gr3
setlo %lo(__entry_kernel_external_interrupt_reentry),gr3
@@ -294,6 +305,64 @@ __break_return_as_kernel_prologue:
#endif
rett #1
+# we single-stepped into an interrupt handler whilst interrupts were merely virtually disabled
+# need to really disable interrupts, set flag, fix up and return
+__break_step_kernel_external_interrupt_virtually_disabled:
+ movsg psr,gr2
+ andi gr2,#~PSR_PIL,gr2
+ ori gr2,#PSR_PIL_14,gr2 /* debugging interrupts only */
+ movgs gr2,psr
+
+ ldi @(gr31,#REG_CCR),gr3
+ movgs gr3,ccr
+ subcc.p gr0,gr0,gr0,icc2 /* leave Z set, clear C */
+
+ # exceptions must've been enabled and we must've been in supervisor mode
+ setlos BPSR_BET|BPSR_BS,gr3
+ movgs gr3,bpsr
+
+ # return to where the interrupt happened
+ movsg pcsr,gr2
+ movgs gr2,bpcsr
+
+ lddi.p @(gr31,#REG_GR(2)),gr2
+
+ xor gr31,gr31,gr31
+ movgs gr0,brr
+#ifdef CONFIG_MMU
+ movsg scr3,gr31
+#endif
+ rett #1
+
+# we stepped through into the virtual interrupt reenablement trap
+#
+# we also want to single step anyway, but after fixing up so that we get an event on the
+# instruction after the broken-into exception returns
+ .globl __break_step_kernel_external_interrupt_virtual_reenable
+__break_step_kernel_external_interrupt_virtual_reenable:
+ movsg psr,gr2
+ andi gr2,#~PSR_PIL,gr2
+ movgs gr2,psr
+
+ ldi @(gr31,#REG_CCR),gr3
+ movgs gr3,ccr
+ subicc gr0,#1,gr0,icc2 /* clear Z, set C */
+
+ # save the adjusted ICC2
+ movsg ccr,gr3
+ sti gr3,@(gr31,#REG_CCR)
+
+ # exceptions must've been enabled and we must've been in supervisor mode
+ setlos BPSR_BET|BPSR_BS,gr3
+ movgs gr3,bpsr
+
+ # return to where the trap happened
+ movsg pcsr,gr2
+ movgs gr2,bpcsr
+
+ # and then process the single step
+ bra __break_continue
+
# step through an internal exception from uspace mode
.globl __break_step_uspace_softprog_interrupt
__break_step_uspace_softprog_interrupt:
diff --git a/arch/frv/kernel/entry-table.S b/arch/frv/kernel/entry-table.S
index 9b9243e2103..81568acea9c 100644
--- a/arch/frv/kernel/entry-table.S
+++ b/arch/frv/kernel/entry-table.S
@@ -116,6 +116,8 @@ __break_kerneltrap_fixup_table:
.long __break_step_uspace_external_interrupt
.section .trap.kernel
.org \tbr_tt
+ # deal with virtual interrupt disablement
+ beq icc2,#0,__entry_kernel_external_interrupt_virtually_disabled
bra __entry_kernel_external_interrupt
.section .trap.fixup.kernel
.org \tbr_tt >> 2
@@ -259,25 +261,52 @@ __trap_fixup_kernel_data_tlb_miss:
.org TBR_TT_TRAP0
.rept 127
bra __entry_uspace_softprog_interrupt
- bra __break_step_uspace_softprog_interrupt
- .long 0,0
+ .long 0,0,0
.endr
.org TBR_TT_BREAK
bra __entry_break
.long 0,0,0
+ .section .trap.fixup.user
+ .org TBR_TT_TRAP0 >> 2
+ .rept 127
+ .long __break_step_uspace_softprog_interrupt
+ .endr
+ .org TBR_TT_BREAK >> 2
+ .long 0
+
# miscellaneous kernel mode entry points
.section .trap.kernel
.org TBR_TT_TRAP0
- .rept 127
bra __entry_kernel_softprog_interrupt
- bra __break_step_kernel_softprog_interrupt
- .long 0,0
+ .org TBR_TT_TRAP1
+ bra __entry_kernel_softprog_interrupt
+
+ # trap #2 in kernel - reenable interrupts
+ .org TBR_TT_TRAP2
+ bra __entry_kernel_external_interrupt_virtual_reenable
+
+ # miscellaneous kernel traps
+ .org TBR_TT_TRAP3
+ .rept 124
+ bra __entry_kernel_softprog_interrupt
+ .long 0,0,0
.endr
.org TBR_TT_BREAK
bra __entry_break
.long 0,0,0
+ .section .trap.fixup.kernel
+ .org TBR_TT_TRAP0 >> 2
+ .long __break_step_kernel_softprog_interrupt
+ .long __break_step_kernel_softprog_interrupt
+ .long __break_step_kernel_external_interrupt_virtual_reenable
+ .rept 124
+ .long __break_step_kernel_softprog_interrupt
+ .endr
+ .org TBR_TT_BREAK >> 2
+ .long 0
+
# miscellaneous debug mode entry points
.section .trap.break
.org TBR_TT_BREAK
diff --git a/arch/frv/kernel/entry.S b/arch/frv/kernel/entry.S
index 5f6548388b7..1d21c8d34d8 100644
--- a/arch/frv/kernel/entry.S
+++ b/arch/frv/kernel/entry.S
@@ -141,7 +141,10 @@ __entry_uspace_external_interrupt_reentry:
movsg gner0,gr4
movsg gner1,gr5
- stdi gr4,@(gr28,#REG_GNER0)
+ stdi.p gr4,@(gr28,#REG_GNER0)
+
+ # interrupts start off fully disabled in the interrupt handler
+ subcc gr0,gr0,gr0,icc2 /* set Z and clear C */
# set up kernel global registers
sethi.p %hi(__kernel_current_task),gr5
@@ -193,9 +196,8 @@ __entry_uspace_external_interrupt_reentry:
.type __entry_kernel_external_interrupt,@function
__entry_kernel_external_interrupt:
LEDS 0x6210
-
- sub sp,gr15,gr31
- LEDS32
+// sub sp,gr15,gr31
+// LEDS32
# set up the stack pointer
or.p sp,gr0,gr30
@@ -231,7 +233,10 @@ __entry_kernel_external_interrupt_reentry:
stdi gr24,@(gr28,#REG_GR(24))
stdi gr26,@(gr28,#REG_GR(26))
sti gr29,@(gr28,#REG_GR(29))
- stdi gr30,@(gr28,#REG_GR(30))
+ stdi.p gr30,@(gr28,#REG_GR(30))
+
+ # note virtual interrupts will be fully enabled upon return
+ subicc gr0,#1,gr0,icc2 /* clear Z, set C */
movsg tbr ,gr20
movsg psr ,gr22
@@ -267,7 +272,10 @@ __entry_kernel_external_interrupt_reentry:
movsg gner0,gr4
movsg gner1,gr5
- stdi gr4,@(gr28,#REG_GNER0)
+ stdi.p gr4,@(gr28,#REG_GNER0)
+
+ # interrupts start off fully disabled in the interrupt handler
+ subcc gr0,gr0,gr0,icc2 /* set Z and clear C */
# set the return address
sethi.p %hi(__entry_return_from_kernel_interrupt),gr4
@@ -291,6 +299,45 @@ __entry_kernel_external_interrupt_reentry:
.size __entry_kernel_external_interrupt,.-__entry_kernel_external_interrupt
+###############################################################################
+#
+# deal with interrupts that were actually virtually disabled
+# - we need to really disable them, flag the fact and return immediately
+# - if you change this, you must alter break.S also
+#
+###############################################################################
+ .balign L1_CACHE_BYTES
+ .globl __entry_kernel_external_interrupt_virtually_disabled
+ .type __entry_kernel_external_interrupt_virtually_disabled,@function
+__entry_kernel_external_interrupt_virtually_disabled:
+ movsg psr,gr30
+ andi gr30,#~PSR_PIL,gr30
+ ori gr30,#PSR_PIL_14,gr30 ; debugging interrupts only
+ movgs gr30,psr
+ subcc gr0,gr0,gr0,icc2 ; leave Z set, clear C
+ rett #0
+
+ .size __entry_kernel_external_interrupt_virtually_disabled,.-__entry_kernel_external_interrupt_virtually_disabled
+
+###############################################################################
+#
+# deal with re-enablement of interrupts that were pending when virtually re-enabled
+# - set ICC2.C, re-enable the real interrupts and return
+# - we can clear ICC2.Z because we shouldn't be here if it's not 0 [due to TIHI]
+# - if you change this, you must alter break.S also
+#
+###############################################################################
+ .balign L1_CACHE_BYTES
+ .globl __entry_kernel_external_interrupt_virtual_reenable
+ .type __entry_kernel_external_interrupt_virtual_reenable,@function
+__entry_kernel_external_interrupt_virtual_reenable:
+ movsg psr,gr30
+ andi gr30,#~PSR_PIL,gr30 ; re-enable interrupts
+ movgs gr30,psr
+ subicc gr0,#1,gr0,icc2 ; clear Z, set C
+ rett #0
+
+ .size __entry_kernel_external_interrupt_virtual_reenable,.-__entry_kernel_external_interrupt_virtual_reenable
###############################################################################
#
@@ -335,6 +382,7 @@ __entry_uspace_softprog_interrupt_reentry:
sethi.p %hi(__entry_return_from_user_exception),gr23
setlo %lo(__entry_return_from_user_exception),gr23
+
bra __entry_common
.size __entry_uspace_softprog_interrupt,.-__entry_uspace_softprog_interrupt
@@ -495,7 +543,10 @@ __entry_common:
movsg gner0,gr4
movsg gner1,gr5
- stdi gr4,@(gr28,#REG_GNER0)
+ stdi.p gr4,@(gr28,#REG_GNER0)
+
+ # set up virtual interrupt disablement
+ subicc gr0,#1,gr0,icc2 /* clear Z flag, set C flag */
# set up kernel global registers
sethi.p %hi(__kernel_current_task),gr5
@@ -1418,11 +1469,27 @@ sys_call_table:
.long sys_add_key
.long sys_request_key
.long sys_keyctl
- .long sys_ni_syscall // sys_vperfctr_open
- .long sys_ni_syscall // sys_vperfctr_control /* 290 */
- .long sys_ni_syscall // sys_vperfctr_unlink
- .long sys_ni_syscall // sys_vperfctr_iresume
- .long sys_ni_syscall // sys_vperfctr_read
+ .long sys_ioprio_set
+ .long sys_ioprio_get /* 290 */
+ .long sys_inotify_init
+ .long sys_inotify_add_watch
+ .long sys_inotify_rm_watch
+ .long sys_migrate_pages
+ .long sys_openat /* 295 */
+ .long sys_mkdirat
+ .long sys_mknodat
+ .long sys_fchownat
+ .long sys_futimesat
+ .long sys_newfstatat /* 300 */
+ .long sys_unlinkat
+ .long sys_renameat
+ .long sys_linkat
+ .long sys_symlinkat
+ .long sys_readlinkat /* 305 */
+ .long sys_fchmodat
+ .long sys_faccessat
+ .long sys_pselect6
+ .long sys_ppoll
syscall_table_size = (. - sys_call_table)
diff --git a/arch/frv/kernel/head.S b/arch/frv/kernel/head.S
index c73b4fe9f6c..29a5265489b 100644
--- a/arch/frv/kernel/head.S
+++ b/arch/frv/kernel/head.S
@@ -513,6 +513,9 @@ __head_mmu_enabled:
movgs gr0,ccr
movgs gr0,cccr
+ # initialise the virtual interrupt handling
+ subcc gr0,gr0,gr0,icc2 /* set Z, clear C */
+
#ifdef CONFIG_MMU
movgs gr3,scr2
movgs gr3,scr3
diff --git a/arch/frv/kernel/irq.c b/arch/frv/kernel/irq.c
index 59580c59c62..27ab4c30aac 100644
--- a/arch/frv/kernel/irq.c
+++ b/arch/frv/kernel/irq.c
@@ -287,18 +287,11 @@ asmlinkage void do_IRQ(void)
struct irq_source *source;
int level, cpu;
+ irq_enter();
+
level = (__frame->tbr >> 4) & 0xf;
cpu = smp_processor_id();
-#if 0
- {
- static u32 irqcount;
- *(volatile u32 *) 0xe1200004 = ~((irqcount++ << 8) | level);
- *(volatile u16 *) 0xffc00100 = (u16) ~0x9999;
- mb();
- }
-#endif
-
if ((unsigned long) __frame - (unsigned long) (current + 1) < 512)
BUG();
@@ -308,40 +301,12 @@ asmlinkage void do_IRQ(void)
kstat_this_cpu.irqs[level]++;
- irq_enter();
-
for (source = frv_irq_levels[level].sources; source; source = source->next)
source->doirq(source);
- irq_exit();
-
__clr_MASK(level);
- /* only process softirqs if we didn't interrupt another interrupt handler */
- if ((__frame->psr & PSR_PIL) == PSR_PIL_0)
- if (local_softirq_pending())
- do_softirq();
-
-#ifdef CONFIG_PREEMPT
- local_irq_disable();
- while (--current->preempt_count == 0) {
- if (!(__frame->psr & PSR_S) ||
- current->need_resched == 0 ||
- in_interrupt())
- break;
- current->preempt_count++;
- local_irq_enable();
- preempt_schedule();
- local_irq_disable();
- }
-#endif
-
-#if 0
- {
- *(volatile u16 *) 0xffc00100 = (u16) ~0x6666;
- mb();
- }
-#endif
+ irq_exit();
} /* end do_IRQ() */
diff --git a/arch/frv/mm/kmap.c b/arch/frv/mm/kmap.c
index 539f45e6d15..c54f18e65ea 100644
--- a/arch/frv/mm/kmap.c
+++ b/arch/frv/mm/kmap.c
@@ -44,15 +44,6 @@ void iounmap(void *addr)
}
/*
- * __iounmap unmaps nearly everything, so be careful
- * it doesn't free currently pointer/page tables anymore but it
- * wans't used anyway and might be added later.
- */
-void __iounmap(void *addr, unsigned long size)
-{
-}
-
-/*
* Set new cache mode for some kernel address space.
* The caller must push data for that range itself, if such data may already
* be in the cache.
diff --git a/arch/h8300/Kconfig b/arch/h8300/Kconfig
index 80940d712ac..98308b018a3 100644
--- a/arch/h8300/Kconfig
+++ b/arch/h8300/Kconfig
@@ -33,6 +33,10 @@ config GENERIC_CALIBRATE_DELAY
bool
default y
+config TIME_LOW_RES
+ bool
+ default y
+
config ISA
bool
default y
diff --git a/arch/h8300/Kconfig.cpu b/arch/h8300/Kconfig.cpu
index a380167a13c..582797db960 100644
--- a/arch/h8300/Kconfig.cpu
+++ b/arch/h8300/Kconfig.cpu
@@ -169,7 +169,7 @@ endif
config CPU_H8300H
bool
- depends on (H8002 || H83007 || H83048 || H83068)
+ depends on (H83002 || H83007 || H83048 || H83068)
default y
config CPU_H8S
diff --git a/arch/i386/boot/.gitignore b/arch/i386/boot/.gitignore
new file mode 100644
index 00000000000..495f20c085d
--- /dev/null
+++ b/arch/i386/boot/.gitignore
@@ -0,0 +1,3 @@
+bootsect
+bzImage
+setup
diff --git a/arch/i386/boot/tools/.gitignore b/arch/i386/boot/tools/.gitignore
new file mode 100644
index 00000000000..378eac25d31
--- /dev/null
+++ b/arch/i386/boot/tools/.gitignore
@@ -0,0 +1 @@
+build
diff --git a/arch/i386/kernel/.gitignore b/arch/i386/kernel/.gitignore
new file mode 100644
index 00000000000..40836ad9079
--- /dev/null
+++ b/arch/i386/kernel/.gitignore
@@ -0,0 +1 @@
+vsyscall.lds
diff --git a/arch/i386/kernel/vsyscall-sysenter.S b/arch/i386/kernel/vsyscall-sysenter.S
index 4daefb2ec1b..76b72815940 100644
--- a/arch/i386/kernel/vsyscall-sysenter.S
+++ b/arch/i386/kernel/vsyscall-sysenter.S
@@ -7,6 +7,21 @@
* for details.
*/
+/*
+ * The caller puts arg2 in %ecx, which gets pushed. The kernel will use
+ * %ecx itself for arg2. The pushing is because the sysexit instruction
+ * (found in entry.S) requires that we clobber %ecx with the desired %esp.
+ * User code might expect that %ecx is unclobbered though, as it would be
+ * for returning via the iret instruction, so we must push and pop.
+ *
+ * The caller puts arg3 in %edx, which the sysexit instruction requires
+ * for %eip. Thus, exactly as for arg2, we must push and pop.
+ *
+ * Arg6 is different. The caller puts arg6 in %ebp. Since the sysenter
+ * instruction clobbers %esp, the user's %esp won't even survive entry
+ * into the kernel. We store %esp in %ebp. Code in entry.S must fetch
+ * arg6 from the stack.
+ */
.text
.globl __kernel_vsyscall
.type __kernel_vsyscall,@function
diff --git a/arch/ia64/kernel/ia64_ksyms.c b/arch/ia64/kernel/ia64_ksyms.c
index e72de580ebb..bbcfd08378a 100644
--- a/arch/ia64/kernel/ia64_ksyms.c
+++ b/arch/ia64/kernel/ia64_ksyms.c
@@ -10,23 +10,8 @@
#include <linux/string.h>
EXPORT_SYMBOL(memset);
-EXPORT_SYMBOL(memchr);
-EXPORT_SYMBOL(memcmp);
EXPORT_SYMBOL(memcpy);
-EXPORT_SYMBOL(memmove);
-EXPORT_SYMBOL(memscan);
-EXPORT_SYMBOL(strcat);
-EXPORT_SYMBOL(strchr);
-EXPORT_SYMBOL(strcmp);
-EXPORT_SYMBOL(strcpy);
EXPORT_SYMBOL(strlen);
-EXPORT_SYMBOL(strncat);
-EXPORT_SYMBOL(strncmp);
-EXPORT_SYMBOL(strncpy);
-EXPORT_SYMBOL(strnlen);
-EXPORT_SYMBOL(strrchr);
-EXPORT_SYMBOL(strstr);
-EXPORT_SYMBOL(strpbrk);
#include <asm/checksum.h>
EXPORT_SYMBOL(ip_fast_csum); /* hand-coded assembly */
diff --git a/arch/ia64/kernel/time.c b/arch/ia64/kernel/time.c
index a094ec49ccf..307d01e15b2 100644
--- a/arch/ia64/kernel/time.c
+++ b/arch/ia64/kernel/time.c
@@ -250,32 +250,27 @@ time_init (void)
set_normalized_timespec(&wall_to_monotonic, -xtime.tv_sec, -xtime.tv_nsec);
}
-#define SMALLUSECS 100
-
-void
-udelay (unsigned long usecs)
+/*
+ * Generic udelay assumes that if preemption is allowed and the thread
+ * migrates to another CPU, that the ITC values are synchronized across
+ * all CPUs.
+ */
+static void
+ia64_itc_udelay (unsigned long usecs)
{
- unsigned long start;
- unsigned long cycles;
- unsigned long smallusecs;
+ unsigned long start = ia64_get_itc();
+ unsigned long end = start + usecs*local_cpu_data->cyc_per_usec;
- /*
- * Execute the non-preemptible delay loop (because the ITC might
- * not be synchronized between CPUS) in relatively short time
- * chunks, allowing preemption between the chunks.
- */
- while (usecs > 0) {
- smallusecs = (usecs > SMALLUSECS) ? SMALLUSECS : usecs;
- preempt_disable();
- cycles = smallusecs*local_cpu_data->cyc_per_usec;
- start = ia64_get_itc();
+ while (time_before(ia64_get_itc(), end))
+ cpu_relax();
+}
- while (ia64_get_itc() - start < cycles)
- cpu_relax();
+void (*ia64_udelay)(unsigned long usecs) = &ia64_itc_udelay;
- preempt_enable();
- usecs -= smallusecs;
- }
+void
+udelay (unsigned long usecs)
+{
+ (*ia64_udelay)(usecs);
}
EXPORT_SYMBOL(udelay);
diff --git a/arch/ia64/kernel/traps.c b/arch/ia64/kernel/traps.c
index 55391901b01..dabd6c32641 100644
--- a/arch/ia64/kernel/traps.c
+++ b/arch/ia64/kernel/traps.c
@@ -16,6 +16,7 @@
#include <linux/module.h> /* for EXPORT_SYMBOL */
#include <linux/hardirq.h>
#include <linux/kprobes.h>
+#include <linux/delay.h> /* for ssleep() */
#include <asm/fpswa.h>
#include <asm/ia32.h>
@@ -116,6 +117,13 @@ die (const char *str, struct pt_regs *regs, long err)
bust_spinlocks(0);
die.lock_owner = -1;
spin_unlock_irq(&die.lock);
+
+ if (panic_on_oops) {
+ printk(KERN_EMERG "Fatal exception: panic in 5 seconds\n");
+ ssleep(5);
+ panic("Fatal exception");
+ }
+
do_exit(SIGSEGV);
}
diff --git a/arch/ia64/sn/kernel/io_init.c b/arch/ia64/sn/kernel/io_init.c
index 3437c239042..3edef0d32f8 100644
--- a/arch/ia64/sn/kernel/io_init.c
+++ b/arch/ia64/sn/kernel/io_init.c
@@ -23,6 +23,10 @@
#include "xtalk/hubdev.h"
#include "xtalk/xwidgetdev.h"
+
+extern void sn_init_cpei_timer(void);
+extern void register_sn_procfs(void);
+
static struct list_head sn_sysdata_list;
/* sysdata list struct */
@@ -40,12 +44,12 @@ struct brick {
struct slab_info slab_info[MAX_SLABS + 1];
};
-int sn_ioif_inited = 0; /* SN I/O infrastructure initialized? */
+int sn_ioif_inited; /* SN I/O infrastructure initialized? */
struct sn_pcibus_provider *sn_pci_provider[PCIIO_ASIC_MAX_TYPES]; /* indexed by asic type */
-static int max_segment_number = 0; /* Default highest segment number */
-static int max_pcibus_number = 255; /* Default highest pci bus number */
+static int max_segment_number; /* Default highest segment number */
+static int max_pcibus_number = 255; /* Default highest pci bus number */
/*
* Hooks and struct for unsupported pci providers
@@ -84,7 +88,6 @@ static inline u64
sal_get_device_dmaflush_list(u64 nasid, u64 widget_num, u64 device_num,
u64 address)
{
-
struct ia64_sal_retval ret_stuff;
ret_stuff.status = 0;
ret_stuff.v0 = 0;
@@ -94,7 +97,6 @@ sal_get_device_dmaflush_list(u64 nasid, u64 widget_num, u64 device_num,
(u64) nasid, (u64) widget_num,
(u64) device_num, (u64) address, 0, 0, 0);
return ret_stuff.status;
-
}
/*
@@ -102,7 +104,6 @@ sal_get_device_dmaflush_list(u64 nasid, u64 widget_num, u64 device_num,
*/
static inline u64 sal_get_hubdev_info(u64 handle, u64 address)
{
-
struct ia64_sal_retval ret_stuff;
ret_stuff.status = 0;
ret_stuff.v0 = 0;
@@ -118,7 +119,6 @@ static inline u64 sal_get_hubdev_info(u64 handle, u64 address)
*/
static inline u64 sal_get_pcibus_info(u64 segment, u64 busnum, u64 address)
{
-
struct ia64_sal_retval ret_stuff;
ret_stuff.status = 0;
ret_stuff.v0 = 0;
@@ -215,7 +215,7 @@ static void __init sn_fixup_ionodes(void)
struct hubdev_info *hubdev;
u64 status;
u64 nasid;
- int i, widget, device;
+ int i, widget, device, size;
/*
* Get SGI Specific HUB chipset information.
@@ -251,48 +251,37 @@ static void __init sn_fixup_ionodes(void)
if (!hubdev->hdi_flush_nasid_list.widget_p)
continue;
+ size = (HUB_WIDGET_ID_MAX + 1) *
+ sizeof(struct sn_flush_device_kernel *);
hubdev->hdi_flush_nasid_list.widget_p =
- kmalloc((HUB_WIDGET_ID_MAX + 1) *
- sizeof(struct sn_flush_device_kernel *),
- GFP_KERNEL);
- memset(hubdev->hdi_flush_nasid_list.widget_p, 0x0,
- (HUB_WIDGET_ID_MAX + 1) *
- sizeof(struct sn_flush_device_kernel *));
+ kzalloc(size, GFP_KERNEL);
+ if (!hubdev->hdi_flush_nasid_list.widget_p)
+ BUG();
for (widget = 0; widget <= HUB_WIDGET_ID_MAX; widget++) {
- sn_flush_device_kernel = kmalloc(DEV_PER_WIDGET *
- sizeof(struct
- sn_flush_device_kernel),
- GFP_KERNEL);
+ size = DEV_PER_WIDGET *
+ sizeof(struct sn_flush_device_kernel);
+ sn_flush_device_kernel = kzalloc(size, GFP_KERNEL);
if (!sn_flush_device_kernel)
BUG();
- memset(sn_flush_device_kernel, 0x0,
- DEV_PER_WIDGET *
- sizeof(struct sn_flush_device_kernel));
dev_entry = sn_flush_device_kernel;
for (device = 0; device < DEV_PER_WIDGET;
device++,dev_entry++) {
- dev_entry->common = kmalloc(sizeof(struct
- sn_flush_device_common),
- GFP_KERNEL);
+ size = sizeof(struct sn_flush_device_common);
+ dev_entry->common = kzalloc(size, GFP_KERNEL);
if (!dev_entry->common)
BUG();
- memset(dev_entry->common, 0x0, sizeof(struct
- sn_flush_device_common));
if (sn_prom_feature_available(
PRF_DEVICE_FLUSH_LIST))
status = sal_get_device_dmaflush_list(
- nasid,
- widget,
- device,
- (u64)(dev_entry->common));
+ nasid, widget, device,
+ (u64)(dev_entry->common));
else
status = sn_device_fixup_war(nasid,
- widget,
- device,
- dev_entry->common);
+ widget, device,
+ dev_entry->common);
if (status != SALRET_OK)
panic("SAL call failed: %s\n",
ia64_sal_strerror(status));
@@ -383,13 +372,12 @@ void sn_pci_fixup_slot(struct pci_dev *dev)
pci_dev_get(dev); /* for the sysdata pointer */
pcidev_info = kzalloc(sizeof(struct pcidev_info), GFP_KERNEL);
- if (pcidev_info <= 0)
+ if (!pcidev_info)
BUG(); /* Cannot afford to run out of memory */
- sn_irq_info = kmalloc(sizeof(struct sn_irq_info), GFP_KERNEL);
- if (sn_irq_info <= 0)
+ sn_irq_info = kzalloc(sizeof(struct sn_irq_info), GFP_KERNEL);
+ if (!sn_irq_info)
BUG(); /* Cannot afford to run out of memory */
- memset(sn_irq_info, 0, sizeof(struct sn_irq_info));
/* Call to retrieve pci device information needed by kernel. */
status = sal_get_pcidev_info((u64) segment, (u64) dev->bus->number,
@@ -482,13 +470,13 @@ void sn_pci_fixup_slot(struct pci_dev *dev)
*/
void sn_pci_controller_fixup(int segment, int busnum, struct pci_bus *bus)
{
- int status = 0;
+ int status;
int nasid, cnode;
struct pci_controller *controller;
struct sn_pci_controller *sn_controller;
struct pcibus_bussoft *prom_bussoft_ptr;
struct hubdev_info *hubdev_info;
- void *provider_soft = NULL;
+ void *provider_soft;
struct sn_pcibus_provider *provider;
status = sal_get_pcibus_info((u64) segment, (u64) busnum,
@@ -535,6 +523,8 @@ void sn_pci_controller_fixup(int segment, int busnum, struct pci_bus *bus)
bus->sysdata = controller;
if (provider->bus_fixup)
provider_soft = (*provider->bus_fixup) (prom_bussoft_ptr, controller);
+ else
+ provider_soft = NULL;
if (provider_soft == NULL) {
/* fixup failed or not applicable */
@@ -638,13 +628,8 @@ void sn_bus_free_sysdata(void)
static int __init sn_pci_init(void)
{
- int i = 0;
- int j = 0;
+ int i, j;
struct pci_dev *pci_dev = NULL;
- extern void sn_init_cpei_timer(void);
-#ifdef CONFIG_PROC_FS
- extern void register_sn_procfs(void);
-#endif
if (!ia64_platform_is("sn2") || IS_RUNNING_ON_FAKE_PROM())
return 0;
@@ -700,32 +685,29 @@ static int __init sn_pci_init(void)
*/
void hubdev_init_node(nodepda_t * npda, cnodeid_t node)
{
-
struct hubdev_info *hubdev_info;
+ int size;
+ pg_data_t *pg;
+
+ size = sizeof(struct hubdev_info);
if (node >= num_online_nodes()) /* Headless/memless IO nodes */
- hubdev_info =
- (struct hubdev_info *)alloc_bootmem_node(NODE_DATA(0),
- sizeof(struct
- hubdev_info));
+ pg = NODE_DATA(0);
else
- hubdev_info =
- (struct hubdev_info *)alloc_bootmem_node(NODE_DATA(node),
- sizeof(struct
- hubdev_info));
- npda->pdinfo = (void *)hubdev_info;
+ pg = NODE_DATA(node);
+ hubdev_info = (struct hubdev_info *)alloc_bootmem_node(pg, size);
+
+ npda->pdinfo = (void *)hubdev_info;
}
geoid_t
cnodeid_get_geoid(cnodeid_t cnode)
{
-
struct hubdev_info *hubdev;
hubdev = (struct hubdev_info *)(NODEPDA(cnode)->pdinfo);
return hubdev->hdi_geoid;
-
}
subsys_initcall(sn_pci_init);
@@ -734,3 +716,4 @@ EXPORT_SYMBOL(sn_pci_unfixup_slot);
EXPORT_SYMBOL(sn_pci_controller_fixup);
EXPORT_SYMBOL(sn_bus_store_sysdata);
EXPORT_SYMBOL(sn_bus_free_sysdata);
+EXPORT_SYMBOL(sn_pcidev_info_get);
diff --git a/arch/ia64/sn/kernel/setup.c b/arch/ia64/sn/kernel/setup.c
index 48645ac120f..5b84836c217 100644
--- a/arch/ia64/sn/kernel/setup.c
+++ b/arch/ia64/sn/kernel/setup.c
@@ -75,7 +75,7 @@ EXPORT_SYMBOL(sn_rtc_cycles_per_second);
DEFINE_PER_CPU(struct sn_hub_info_s, __sn_hub_info);
EXPORT_PER_CPU_SYMBOL(__sn_hub_info);
-DEFINE_PER_CPU(short, __sn_cnodeid_to_nasid[MAX_NUMNODES]);
+DEFINE_PER_CPU(short, __sn_cnodeid_to_nasid[MAX_COMPACT_NODES]);
EXPORT_PER_CPU_SYMBOL(__sn_cnodeid_to_nasid);
DEFINE_PER_CPU(struct nodepda_s *, __sn_nodepda);
@@ -317,6 +317,7 @@ struct pcdp_vga_device {
#define PCDP_PCI_TRANS_IOPORT 0x02
#define PCDP_PCI_TRANS_MMIO 0x01
+#if defined(CONFIG_VT) && defined(CONFIG_VGA_CONSOLE)
static void
sn_scan_pcdp(void)
{
@@ -358,6 +359,7 @@ sn_scan_pcdp(void)
break; /* once we find the primary, we're done */
}
}
+#endif
static unsigned long sn2_rtc_initial;
diff --git a/arch/ia64/sn/kernel/sn2/prominfo_proc.c b/arch/ia64/sn/kernel/sn2/prominfo_proc.c
index 81c63b2f8ae..6ae276d5d50 100644
--- a/arch/ia64/sn/kernel/sn2/prominfo_proc.c
+++ b/arch/ia64/sn/kernel/sn2/prominfo_proc.c
@@ -3,7 +3,7 @@
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
- * Copyright (C) 1999,2001-2004 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (C) 1999,2001-2004, 2006 Silicon Graphics, Inc. All Rights Reserved.
*
* Module to export the system's Firmware Interface Tables, including
* PROM revision numbers and banners, in /proc
@@ -190,7 +190,7 @@ static int
read_version_entry(char *page, char **start, off_t off, int count, int *eof,
void *data)
{
- int len = 0;
+ int len;
/* data holds the NASID of the node */
len = dump_version(page, (unsigned long)data);
@@ -202,7 +202,7 @@ static int
read_fit_entry(char *page, char **start, off_t off, int count, int *eof,
void *data)
{
- int len = 0;
+ int len;
/* data holds the NASID of the node */
len = dump_fit(page, (unsigned long)data);
@@ -229,13 +229,16 @@ int __init prominfo_init(void)
struct proc_dir_entry *p;
cnodeid_t cnodeid;
unsigned long nasid;
+ int size;
char name[NODE_NAME_LEN];
if (!ia64_platform_is("sn2"))
return 0;
- proc_entries = kmalloc(num_online_nodes() * sizeof(struct proc_dir_entry *),
- GFP_KERNEL);
+ size = num_online_nodes() * sizeof(struct proc_dir_entry *);
+ proc_entries = kzalloc(size, GFP_KERNEL);
+ if (!proc_entries)
+ return -ENOMEM;
sgi_prominfo_entry = proc_mkdir("sgi_prominfo", NULL);
@@ -244,14 +247,12 @@ int __init prominfo_init(void)
sprintf(name, "node%d", cnodeid);
*entp = proc_mkdir(name, sgi_prominfo_entry);
nasid = cnodeid_to_nasid(cnodeid);
- p = create_proc_read_entry(
- "fit", 0, *entp, read_fit_entry,
- (void *)nasid);
+ p = create_proc_read_entry("fit", 0, *entp, read_fit_entry,
+ (void *)nasid);
if (p)
p->owner = THIS_MODULE;
- p = create_proc_read_entry(
- "version", 0, *entp, read_version_entry,
- (void *)nasid);
+ p = create_proc_read_entry("version", 0, *entp,
+ read_version_entry, (void *)nasid);
if (p)
p->owner = THIS_MODULE;
entp++;
@@ -263,7 +264,7 @@ int __init prominfo_init(void)
void __exit prominfo_exit(void)
{
struct proc_dir_entry **entp;
- unsigned cnodeid;
+ unsigned int cnodeid;
char name[NODE_NAME_LEN];
entp = proc_entries;
diff --git a/arch/ia64/sn/kernel/sn2/sn2_smp.c b/arch/ia64/sn/kernel/sn2/sn2_smp.c
index f153a4c35c7..24eefb2fc55 100644
--- a/arch/ia64/sn/kernel/sn2/sn2_smp.c
+++ b/arch/ia64/sn/kernel/sn2/sn2_smp.c
@@ -46,8 +46,14 @@ DECLARE_PER_CPU(struct ptc_stats, ptcstats);
static __cacheline_aligned DEFINE_SPINLOCK(sn2_global_ptc_lock);
-void sn2_ptc_deadlock_recovery(short *, short, short, int, volatile unsigned long *, unsigned long,
- volatile unsigned long *, unsigned long);
+extern unsigned long
+sn2_ptc_deadlock_recovery_core(volatile unsigned long *, unsigned long,
+ volatile unsigned long *, unsigned long,
+ volatile unsigned long *, unsigned long);
+void
+sn2_ptc_deadlock_recovery(short *, short, short, int,
+ volatile unsigned long *, unsigned long,
+ volatile unsigned long *, unsigned long);
/*
* Note: some is the following is captured here to make degugging easier
@@ -59,16 +65,6 @@ void sn2_ptc_deadlock_recovery(short *, short, short, int, volatile unsigned lon
#define reset_max_active_on_deadlock() 1
#define PTC_LOCK(sh1) ((sh1) ? &sn2_global_ptc_lock : &sn_nodepda->ptc_lock)
-static inline void ptc_lock(int sh1, unsigned long *flagp)
-{
- spin_lock_irqsave(PTC_LOCK(sh1), *flagp);
-}
-
-static inline void ptc_unlock(int sh1, unsigned long flags)
-{
- spin_unlock_irqrestore(PTC_LOCK(sh1), flags);
-}
-
struct ptc_stats {
unsigned long ptc_l;
unsigned long change_rid;
@@ -82,6 +78,8 @@ struct ptc_stats {
unsigned long shub_ptc_flushes_not_my_mm;
};
+#define sn2_ptctest 0
+
static inline unsigned long wait_piowc(void)
{
volatile unsigned long *piows;
@@ -200,7 +198,7 @@ sn2_global_tlb_purge(struct mm_struct *mm, unsigned long start,
max_active = max_active_pio(shub1);
itc = ia64_get_itc();
- ptc_lock(shub1, &flags);
+ spin_lock_irqsave(PTC_LOCK(shub1), flags);
itc2 = ia64_get_itc();
__get_cpu_var(ptcstats).lock_itc_clocks += itc2 - itc;
@@ -258,7 +256,7 @@ sn2_global_tlb_purge(struct mm_struct *mm, unsigned long start,
ia64_srlz_d();
}
- ptc_unlock(shub1, flags);
+ spin_unlock_irqrestore(PTC_LOCK(shub1), flags);
preempt_enable();
}
@@ -270,11 +268,12 @@ sn2_global_tlb_purge(struct mm_struct *mm, unsigned long start,
* TLB flush transaction. The recovery sequence is somewhat tricky & is
* coded in assembly language.
*/
-void sn2_ptc_deadlock_recovery(short *nasids, short ib, short ie, int mynasid, volatile unsigned long *ptc0, unsigned long data0,
- volatile unsigned long *ptc1, unsigned long data1)
+
+void
+sn2_ptc_deadlock_recovery(short *nasids, short ib, short ie, int mynasid,
+ volatile unsigned long *ptc0, unsigned long data0,
+ volatile unsigned long *ptc1, unsigned long data1)
{
- extern unsigned long sn2_ptc_deadlock_recovery_core(volatile unsigned long *, unsigned long,
- volatile unsigned long *, unsigned long, volatile unsigned long *, unsigned long);
short nasid, i;
unsigned long *piows, zeroval, n;
diff --git a/arch/ia64/sn/kernel/sn2/sn_proc_fs.c b/arch/ia64/sn/kernel/sn2/sn_proc_fs.c
index a06719d752a..c686d9c12f7 100644
--- a/arch/ia64/sn/kernel/sn2/sn_proc_fs.c
+++ b/arch/ia64/sn/kernel/sn2/sn_proc_fs.c
@@ -6,11 +6,11 @@
* Copyright (C) 2000-2005 Silicon Graphics, Inc. All rights reserved.
*/
#include <linux/config.h>
-#include <asm/uaccess.h>
#ifdef CONFIG_PROC_FS
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
+#include <asm/uaccess.h>
#include <asm/sn/sn_sal.h>
static int partition_id_show(struct seq_file *s, void *p)
@@ -90,10 +90,10 @@ static int coherence_id_open(struct inode *inode, struct file *file)
return single_open(file, coherence_id_show, NULL);
}
-static struct proc_dir_entry *sn_procfs_create_entry(
- const char *name, struct proc_dir_entry *parent,
- int (*openfunc)(struct inode *, struct file *),
- int (*releasefunc)(struct inode *, struct file *))
+static struct proc_dir_entry
+*sn_procfs_create_entry(const char *name, struct proc_dir_entry *parent,
+ int (*openfunc)(struct inode *, struct file *),
+ int (*releasefunc)(struct inode *, struct file *))
{
struct proc_dir_entry *e = create_proc_entry(name, 0444, parent);
@@ -126,24 +126,24 @@ void register_sn_procfs(void)
return;
sn_procfs_create_entry("partition_id", sgi_proc_dir,
- partition_id_open, single_release);
+ partition_id_open, single_release);
sn_procfs_create_entry("system_serial_number", sgi_proc_dir,
- system_serial_number_open, single_release);
+ system_serial_number_open, single_release);
sn_procfs_create_entry("licenseID", sgi_proc_dir,
- licenseID_open, single_release);
+ licenseID_open, single_release);
e = sn_procfs_create_entry("sn_force_interrupt", sgi_proc_dir,
- sn_force_interrupt_open, single_release);
+ sn_force_interrupt_open, single_release);
if (e)
e->proc_fops->write = sn_force_interrupt_write_proc;
sn_procfs_create_entry("coherence_id", sgi_proc_dir,
- coherence_id_open, single_release);
+ coherence_id_open, single_release);
sn_procfs_create_entry("sn_topology", sgi_proc_dir,
- sn_topology_open, sn_topology_release);
+ sn_topology_open, sn_topology_release);
}
#endif /* CONFIG_PROC_FS */
diff --git a/arch/ia64/sn/kernel/sn2/timer.c b/arch/ia64/sn/kernel/sn2/timer.c
index deb9baf4d47..56a88b6df4b 100644
--- a/arch/ia64/sn/kernel/sn2/timer.c
+++ b/arch/ia64/sn/kernel/sn2/timer.c
@@ -14,6 +14,7 @@
#include <asm/hw_irq.h>
#include <asm/system.h>
+#include <asm/timex.h>
#include <asm/sn/leds.h>
#include <asm/sn/shub_mmr.h>
@@ -28,9 +29,27 @@ static struct time_interpolator sn2_interpolator = {
.source = TIME_SOURCE_MMIO64
};
+/*
+ * sn udelay uses the RTC instead of the ITC because the ITC is not
+ * synchronized across all CPUs, and the thread may migrate to another CPU
+ * if preemption is enabled.
+ */
+static void
+ia64_sn_udelay (unsigned long usecs)
+{
+ unsigned long start = rtc_time();
+ unsigned long end = start +
+ usecs * sn_rtc_cycles_per_second / 1000000;
+
+ while (time_before((unsigned long)rtc_time(), end))
+ cpu_relax();
+}
+
void __init sn_timer_init(void)
{
sn2_interpolator.frequency = sn_rtc_cycles_per_second;
sn2_interpolator.addr = RTC_COUNTER_ADDR;
register_time_interpolator(&sn2_interpolator);
+
+ ia64_udelay = &ia64_sn_udelay;
}
diff --git a/arch/ia64/sn/kernel/sn2/timer_interrupt.c b/arch/ia64/sn/kernel/sn2/timer_interrupt.c
index adf5db2e2af..fa7f6994591 100644
--- a/arch/ia64/sn/kernel/sn2/timer_interrupt.c
+++ b/arch/ia64/sn/kernel/sn2/timer_interrupt.c
@@ -1,7 +1,7 @@
/*
*
*
- * Copyright (c) 2005 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2005, 2006 Silicon Graphics, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License
@@ -22,11 +22,6 @@
* License along with this program; if not, write the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
*
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
* For further information regarding this notice, see:
*
* http://oss.sgi.com/projects/GenInfo/NoticeExplan
diff --git a/arch/ia64/sn/kernel/tiocx.c b/arch/ia64/sn/kernel/tiocx.c
index d263d3e8fbb..8a56f8b5ffa 100644
--- a/arch/ia64/sn/kernel/tiocx.c
+++ b/arch/ia64/sn/kernel/tiocx.c
@@ -284,12 +284,10 @@ struct sn_irq_info *tiocx_irq_alloc(nasid_t nasid, int widget, int irq,
if ((nasid & 1) == 0)
return NULL;
- sn_irq_info = kmalloc(sn_irq_size, GFP_KERNEL);
+ sn_irq_info = kzalloc(sn_irq_size, GFP_KERNEL);
if (sn_irq_info == NULL)
return NULL;
- memset(sn_irq_info, 0x0, sn_irq_size);
-
status = tiocx_intr_alloc(nasid, widget, __pa(sn_irq_info), irq,
req_nasid, slice);
if (status) {
diff --git a/arch/ia64/sn/kernel/xpc_channel.c b/arch/ia64/sn/kernel/xpc_channel.c
index 36e5437a0fb..cdf6856ce08 100644
--- a/arch/ia64/sn/kernel/xpc_channel.c
+++ b/arch/ia64/sn/kernel/xpc_channel.c
@@ -738,7 +738,9 @@ xpc_process_disconnect(struct xpc_channel *ch, unsigned long *irq_flags)
/* make sure all activity has settled down first */
- if (atomic_read(&ch->references) > 0) {
+ if (atomic_read(&ch->references) > 0 ||
+ ((ch->flags & XPC_C_CONNECTEDCALLOUT_MADE) &&
+ !(ch->flags & XPC_C_DISCONNECTINGCALLOUT_MADE))) {
return;
}
DBUG_ON(atomic_read(&ch->kthreads_assigned) != 0);
@@ -775,7 +777,7 @@ xpc_process_disconnect(struct xpc_channel *ch, unsigned long *irq_flags)
/* both sides are disconnected now */
- if (ch->flags & XPC_C_CONNECTCALLOUT) {
+ if (ch->flags & XPC_C_DISCONNECTINGCALLOUT_MADE) {
spin_unlock_irqrestore(&ch->lock, *irq_flags);
xpc_disconnect_callout(ch, xpcDisconnected);
spin_lock_irqsave(&ch->lock, *irq_flags);
@@ -1300,7 +1302,7 @@ xpc_process_msg_IPI(struct xpc_partition *part, int ch_number)
"delivered=%d, partid=%d, channel=%d\n",
nmsgs_sent, ch->partid, ch->number);
- if (ch->flags & XPC_C_CONNECTCALLOUT) {
+ if (ch->flags & XPC_C_CONNECTEDCALLOUT_MADE) {
xpc_activate_kthreads(ch, nmsgs_sent);
}
}
diff --git a/arch/ia64/sn/kernel/xpc_main.c b/arch/ia64/sn/kernel/xpc_main.c
index 9cd460dfe27..8cbf1643257 100644
--- a/arch/ia64/sn/kernel/xpc_main.c
+++ b/arch/ia64/sn/kernel/xpc_main.c
@@ -750,12 +750,16 @@ xpc_daemonize_kthread(void *args)
/* let registerer know that connection has been established */
spin_lock_irqsave(&ch->lock, irq_flags);
- if (!(ch->flags & XPC_C_CONNECTCALLOUT)) {
- ch->flags |= XPC_C_CONNECTCALLOUT;
+ if (!(ch->flags & XPC_C_CONNECTEDCALLOUT)) {
+ ch->flags |= XPC_C_CONNECTEDCALLOUT;
spin_unlock_irqrestore(&ch->lock, irq_flags);
xpc_connected_callout(ch);
+ spin_lock_irqsave(&ch->lock, irq_flags);
+ ch->flags |= XPC_C_CONNECTEDCALLOUT_MADE;
+ spin_unlock_irqrestore(&ch->lock, irq_flags);
+
/*
* It is possible that while the callout was being
* made that the remote partition sent some messages.
@@ -777,15 +781,17 @@ xpc_daemonize_kthread(void *args)
if (atomic_dec_return(&ch->kthreads_assigned) == 0) {
spin_lock_irqsave(&ch->lock, irq_flags);
- if ((ch->flags & XPC_C_CONNECTCALLOUT) &&
- !(ch->flags & XPC_C_DISCONNECTCALLOUT)) {
- ch->flags |= XPC_C_DISCONNECTCALLOUT;
+ if ((ch->flags & XPC_C_CONNECTEDCALLOUT_MADE) &&
+ !(ch->flags & XPC_C_DISCONNECTINGCALLOUT)) {
+ ch->flags |= XPC_C_DISCONNECTINGCALLOUT;
spin_unlock_irqrestore(&ch->lock, irq_flags);
xpc_disconnect_callout(ch, xpcDisconnecting);
- } else {
- spin_unlock_irqrestore(&ch->lock, irq_flags);
+
+ spin_lock_irqsave(&ch->lock, irq_flags);
+ ch->flags |= XPC_C_DISCONNECTINGCALLOUT_MADE;
}
+ spin_unlock_irqrestore(&ch->lock, irq_flags);
if (atomic_dec_return(&part->nchannels_engaged) == 0) {
xpc_mark_partition_disengaged(part);
xpc_IPI_send_disengage(part);
diff --git a/arch/ia64/sn/pci/pci_dma.c b/arch/ia64/sn/pci/pci_dma.c
index 5a36292388e..b4b84c26921 100644
--- a/arch/ia64/sn/pci/pci_dma.c
+++ b/arch/ia64/sn/pci/pci_dma.c
@@ -335,10 +335,10 @@ int sn_pci_legacy_read(struct pci_bus *bus, u16 port, u32 *val, u8 size)
*/
SAL_CALL(isrv, SN_SAL_IOIF_PCI_SAFE,
- pci_domain_nr(bus), bus->number,
- 0, /* io */
- 0, /* read */
- port, size, __pa(val));
+ pci_domain_nr(bus), bus->number,
+ 0, /* io */
+ 0, /* read */
+ port, size, __pa(val));
if (isrv.status == 0)
return size;
@@ -381,10 +381,10 @@ int sn_pci_legacy_write(struct pci_bus *bus, u16 port, u32 val, u8 size)
*/
SAL_CALL(isrv, SN_SAL_IOIF_PCI_SAFE,
- pci_domain_nr(bus), bus->number,
- 0, /* io */
- 1, /* write */
- port, size, __pa(&val));
+ pci_domain_nr(bus), bus->number,
+ 0, /* io */
+ 1, /* write */
+ port, size, __pa(&val));
if (isrv.status == 0)
return size;
diff --git a/arch/ia64/sn/pci/pcibr/pcibr_ate.c b/arch/ia64/sn/pci/pcibr/pcibr_ate.c
index aa3fa5152a3..1f0253bfe0a 100644
--- a/arch/ia64/sn/pci/pcibr/pcibr_ate.c
+++ b/arch/ia64/sn/pci/pcibr/pcibr_ate.c
@@ -3,7 +3,7 @@
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
- * Copyright (C) 2001-2004 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 2001-2006 Silicon Graphics, Inc. All rights reserved.
*/
#include <linux/types.h>
@@ -12,7 +12,7 @@
#include <asm/sn/pcibus_provider_defs.h>
#include <asm/sn/pcidev.h>
-int pcibr_invalidate_ate = 0; /* by default don't invalidate ATE on free */
+int pcibr_invalidate_ate; /* by default don't invalidate ATE on free */
/*
* mark_ate: Mark the ate as either free or inuse.
@@ -20,14 +20,12 @@ int pcibr_invalidate_ate = 0; /* by default don't invalidate ATE on free */
static void mark_ate(struct ate_resource *ate_resource, int start, int number,
u64 value)
{
-
u64 *ate = ate_resource->ate;
int index;
int length = 0;
for (index = start; length < number; index++, length++)
ate[index] = value;
-
}
/*
@@ -37,7 +35,6 @@ static void mark_ate(struct ate_resource *ate_resource, int start, int number,
static int find_free_ate(struct ate_resource *ate_resource, int start,
int count)
{
-
u64 *ate = ate_resource->ate;
int index;
int start_free;
@@ -70,12 +67,10 @@ static int find_free_ate(struct ate_resource *ate_resource, int start,
static inline void free_ate_resource(struct ate_resource *ate_resource,
int start)
{
-
mark_ate(ate_resource, start, ate_resource->ate[start], 0);
if ((ate_resource->lowest_free_index > start) ||
(ate_resource->lowest_free_index < 0))
ate_resource->lowest_free_index = start;
-
}
/*
@@ -84,7 +79,6 @@ static inline void free_ate_resource(struct ate_resource *ate_resource,
static inline int alloc_ate_resource(struct ate_resource *ate_resource,
int ate_needed)
{
-
int start_index;
/*
@@ -118,19 +112,12 @@ static inline int alloc_ate_resource(struct ate_resource *ate_resource,
*/
int pcibr_ate_alloc(struct pcibus_info *pcibus_info, int count)
{
- int status = 0;
- u64 flag;
+ int status;
+ unsigned long flags;
- flag = pcibr_lock(pcibus_info);
+ spin_lock_irqsave(&pcibus_info->pbi_lock, flags);
status = alloc_ate_resource(&pcibus_info->pbi_int_ate_resource, count);
-
- if (status < 0) {
- /* Failed to allocate */
- pcibr_unlock(pcibus_info, flag);
- return -1;
- }
-
- pcibr_unlock(pcibus_info, flag);
+ spin_unlock_irqrestore(&pcibus_info->pbi_lock, flags);
return status;
}
@@ -182,7 +169,7 @@ void pcibr_ate_free(struct pcibus_info *pcibus_info, int index)
ate_write(pcibus_info, index, count, (ate & ~PCI32_ATE_V));
}
- flags = pcibr_lock(pcibus_info);
+ spin_lock_irqsave(&pcibus_info->pbi_lock, flags);
free_ate_resource(&pcibus_info->pbi_int_ate_resource, index);
- pcibr_unlock(pcibus_info, flags);
+ spin_unlock_irqrestore(&pcibus_info->pbi_lock, flags);
}
diff --git a/arch/ia64/sn/pci/pcibr/pcibr_dma.c b/arch/ia64/sn/pci/pcibr/pcibr_dma.c
index 54ce5b7ceed..9f86bb6519a 100644
--- a/arch/ia64/sn/pci/pcibr/pcibr_dma.c
+++ b/arch/ia64/sn/pci/pcibr/pcibr_dma.c
@@ -137,14 +137,12 @@ pcibr_dmatrans_direct64(struct pcidev_info * info, u64 paddr,
pci_addr |= PCI64_ATTR_VIRTUAL;
return pci_addr;
-
}
static dma_addr_t
pcibr_dmatrans_direct32(struct pcidev_info * info,
u64 paddr, size_t req_size, u64 flags)
{
-
struct pcidev_info *pcidev_info = info->pdi_host_pcidev_info;
struct pcibus_info *pcibus_info = (struct pcibus_info *)pcidev_info->
pdi_pcibus_info;
@@ -171,7 +169,6 @@ pcibr_dmatrans_direct32(struct pcidev_info * info,
}
return PCI32_DIRECT_BASE | offset;
-
}
/*
@@ -218,9 +215,8 @@ void sn_dma_flush(u64 addr)
u64 flags;
u64 itte;
struct hubdev_info *hubinfo;
- volatile struct sn_flush_device_kernel *p;
- volatile struct sn_flush_device_common *common;
-
+ struct sn_flush_device_kernel *p;
+ struct sn_flush_device_common *common;
struct sn_flush_nasid_entry *flush_nasid_list;
if (!sn_ioif_inited)
@@ -310,8 +306,7 @@ void sn_dma_flush(u64 addr)
(common->sfdl_slot - 1));
}
} else {
- spin_lock_irqsave((spinlock_t *)&p->sfdl_flush_lock,
- flags);
+ spin_lock_irqsave(&p->sfdl_flush_lock, flags);
*common->sfdl_flush_addr = 0;
/* force an interrupt. */
@@ -322,8 +317,7 @@ void sn_dma_flush(u64 addr)
cpu_relax();
/* okay, everything is synched up. */
- spin_unlock_irqrestore((spinlock_t *)&p->sfdl_flush_lock,
- flags);
+ spin_unlock_irqrestore(&p->sfdl_flush_lock, flags);
}
return;
}
diff --git a/arch/ia64/sn/pci/pcibr/pcibr_provider.c b/arch/ia64/sn/pci/pcibr/pcibr_provider.c
index 2fac27049bf..98f716bd92f 100644
--- a/arch/ia64/sn/pci/pcibr/pcibr_provider.c
+++ b/arch/ia64/sn/pci/pcibr/pcibr_provider.c
@@ -163,9 +163,12 @@ pcibr_bus_fixup(struct pcibus_bussoft *prom_bussoft, struct pci_controller *cont
/* Setup the PMU ATE map */
soft->pbi_int_ate_resource.lowest_free_index = 0;
soft->pbi_int_ate_resource.ate =
- kmalloc(soft->pbi_int_ate_size * sizeof(u64), GFP_KERNEL);
- memset(soft->pbi_int_ate_resource.ate, 0,
- (soft->pbi_int_ate_size * sizeof(u64)));
+ kzalloc(soft->pbi_int_ate_size * sizeof(u64), GFP_KERNEL);
+
+ if (!soft->pbi_int_ate_resource.ate) {
+ kfree(soft);
+ return NULL;
+ }
if (prom_bussoft->bs_asic_type == PCIIO_ASIC_TYPE_TIOCP) {
/* TIO PCI Bridge: find nearest node with CPUs */
diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig
index 96b91982805..8849439e88d 100644
--- a/arch/m68k/Kconfig
+++ b/arch/m68k/Kconfig
@@ -21,6 +21,10 @@ config GENERIC_CALIBRATE_DELAY
bool
default y
+config TIME_LOW_RES
+ bool
+ default y
+
config ARCH_MAY_HAVE_PC_FDC
bool
depends on Q40 || (BROKEN && SUN3X)
diff --git a/arch/m68knommu/Kconfig b/arch/m68knommu/Kconfig
index e2a6e864896..e50858dbc23 100644
--- a/arch/m68knommu/Kconfig
+++ b/arch/m68knommu/Kconfig
@@ -29,6 +29,10 @@ config GENERIC_CALIBRATE_DELAY
bool
default y
+config TIME_LOW_RES
+ bool
+ default y
+
source "init/Kconfig"
menu "Processor type and features"
diff --git a/arch/mips/Makefile b/arch/mips/Makefile
index 6a57407df1b..38c0f3360d5 100644
--- a/arch/mips/Makefile
+++ b/arch/mips/Makefile
@@ -94,7 +94,6 @@ endif
# machines may also. Since BFD is incredibly buggy with respect to
# crossformat linking we rely on the elf2ecoff tool for format conversion.
#
-cflags-y += -I $(TOPDIR)/include/asm/gcc
cflags-y += -G 0 -mno-abicalls -fno-pic -pipe
LDFLAGS_vmlinux += -G 0 -static -n -nostdlib
MODFLAGS += -mlong-calls
diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c
index 5232fc75293..092679c2dca 100644
--- a/arch/mips/kernel/process.c
+++ b/arch/mips/kernel/process.c
@@ -25,6 +25,7 @@
#include <linux/a.out.h>
#include <linux/init.h>
#include <linux/completion.h>
+#include <linux/kallsyms.h>
#include <asm/abi.h>
#include <asm/bootinfo.h>
@@ -272,46 +273,19 @@ long kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
static struct mips_frame_info {
void *func;
- int omit_fp; /* compiled without fno-omit-frame-pointer */
- int frame_offset;
+ unsigned long func_size;
+ int frame_size;
int pc_offset;
-} schedule_frame, mfinfo[] = {
- { schedule, 0 }, /* must be first */
- /* arch/mips/kernel/semaphore.c */
- { __down, 1 },
- { __down_interruptible, 1 },
- /* kernel/sched.c */
-#ifdef CONFIG_PREEMPT
- { preempt_schedule, 0 },
-#endif
- { wait_for_completion, 0 },
- { interruptible_sleep_on, 0 },
- { interruptible_sleep_on_timeout, 0 },
- { sleep_on, 0 },
- { sleep_on_timeout, 0 },
- { yield, 0 },
- { io_schedule, 0 },
- { io_schedule_timeout, 0 },
-#if defined(CONFIG_SMP) && defined(CONFIG_PREEMPT)
- { __preempt_spin_lock, 0 },
- { __preempt_write_lock, 0 },
-#endif
- /* kernel/timer.c */
- { schedule_timeout, 1 },
-/* { nanosleep_restart, 1 }, */
- /* lib/rwsem-spinlock.c */
- { __down_read, 1 },
- { __down_write, 1 },
-};
+} *schedule_frame, mfinfo[64];
+static int mfinfo_num;
-static int mips_frame_info_initialized;
static int __init get_frame_info(struct mips_frame_info *info)
{
int i;
void *func = info->func;
union mips_instruction *ip = (union mips_instruction *)func;
info->pc_offset = -1;
- info->frame_offset = info->omit_fp ? 0 : -1;
+ info->frame_size = 0;
for (i = 0; i < 128; i++, ip++) {
/* if jal, jalr, jr, stop. */
if (ip->j_format.opcode == jal_op ||
@@ -320,6 +294,23 @@ static int __init get_frame_info(struct mips_frame_info *info)
ip->r_format.func == jr_op)))
break;
+ if (info->func_size && i >= info->func_size / 4)
+ break;
+ if (
+#ifdef CONFIG_32BIT
+ ip->i_format.opcode == addiu_op &&
+#endif
+#ifdef CONFIG_64BIT
+ ip->i_format.opcode == daddiu_op &&
+#endif
+ ip->i_format.rs == 29 &&
+ ip->i_format.rt == 29) {
+ /* addiu/daddiu sp,sp,-imm */
+ if (info->frame_size)
+ continue;
+ info->frame_size = - ip->i_format.simmediate;
+ }
+
if (
#ifdef CONFIG_32BIT
ip->i_format.opcode == sw_op &&
@@ -327,31 +318,20 @@ static int __init get_frame_info(struct mips_frame_info *info)
#ifdef CONFIG_64BIT
ip->i_format.opcode == sd_op &&
#endif
- ip->i_format.rs == 29)
- {
+ ip->i_format.rs == 29 &&
+ ip->i_format.rt == 31) {
/* sw / sd $ra, offset($sp) */
- if (ip->i_format.rt == 31) {
- if (info->pc_offset != -1)
- continue;
- info->pc_offset =
- ip->i_format.simmediate / sizeof(long);
- }
- /* sw / sd $s8, offset($sp) */
- if (ip->i_format.rt == 30) {
-//#if 0 /* gcc 3.4 does aggressive optimization... */
- if (info->frame_offset != -1)
- continue;
-//#endif
- info->frame_offset =
- ip->i_format.simmediate / sizeof(long);
- }
+ if (info->pc_offset != -1)
+ continue;
+ info->pc_offset =
+ ip->i_format.simmediate / sizeof(long);
}
}
- if (info->pc_offset == -1 || info->frame_offset == -1) {
- printk("Can't analyze prologue code at %p\n", func);
+ if (info->pc_offset == -1 || info->frame_size == 0) {
+ if (func == schedule)
+ printk("Can't analyze prologue code at %p\n", func);
info->pc_offset = -1;
- info->frame_offset = -1;
- return -1;
+ info->frame_size = 0;
}
return 0;
@@ -359,25 +339,36 @@ static int __init get_frame_info(struct mips_frame_info *info)
static int __init frame_info_init(void)
{
- int i, found;
- for (i = 0; i < ARRAY_SIZE(mfinfo); i++)
- if (get_frame_info(&mfinfo[i]))
- return -1;
- schedule_frame = mfinfo[0];
- /* bubble sort */
- do {
- struct mips_frame_info tmp;
- found = 0;
- for (i = 1; i < ARRAY_SIZE(mfinfo); i++) {
- if (mfinfo[i-1].func > mfinfo[i].func) {
- tmp = mfinfo[i];
- mfinfo[i] = mfinfo[i-1];
- mfinfo[i-1] = tmp;
- found = 1;
- }
- }
- } while (found);
- mips_frame_info_initialized = 1;
+ int i;
+#ifdef CONFIG_KALLSYMS
+ char *modname;
+ char namebuf[KSYM_NAME_LEN + 1];
+ unsigned long start, size, ofs;
+ extern char __sched_text_start[], __sched_text_end[];
+ extern char __lock_text_start[], __lock_text_end[];
+
+ start = (unsigned long)__sched_text_start;
+ for (i = 0; i < ARRAY_SIZE(mfinfo); i++) {
+ if (start == (unsigned long)schedule)
+ schedule_frame = &mfinfo[i];
+ if (!kallsyms_lookup(start, &size, &ofs, &modname, namebuf))
+ break;
+ mfinfo[i].func = (void *)(start + ofs);
+ mfinfo[i].func_size = size;
+ start += size - ofs;
+ if (start >= (unsigned long)__lock_text_end)
+ break;
+ if (start == (unsigned long)__sched_text_end)
+ start = (unsigned long)__lock_text_start;
+ }
+#else
+ mfinfo[0].func = schedule;
+ schedule_frame = &mfinfo[0];
+#endif
+ for (i = 0; i < ARRAY_SIZE(mfinfo) && mfinfo[i].func; i++)
+ get_frame_info(&mfinfo[i]);
+
+ mfinfo_num = i;
return 0;
}
@@ -394,47 +385,52 @@ unsigned long thread_saved_pc(struct task_struct *tsk)
if (t->reg31 == (unsigned long) ret_from_fork)
return t->reg31;
- if (schedule_frame.pc_offset < 0)
+ if (!schedule_frame || schedule_frame->pc_offset < 0)
return 0;
- return ((unsigned long *)t->reg29)[schedule_frame.pc_offset];
+ return ((unsigned long *)t->reg29)[schedule_frame->pc_offset];
}
/* get_wchan - a maintenance nightmare^W^Wpain in the ass ... */
unsigned long get_wchan(struct task_struct *p)
{
unsigned long stack_page;
- unsigned long frame, pc;
+ unsigned long pc;
+#ifdef CONFIG_KALLSYMS
+ unsigned long frame;
+#endif
if (!p || p == current || p->state == TASK_RUNNING)
return 0;
stack_page = (unsigned long)task_stack_page(p);
- if (!stack_page || !mips_frame_info_initialized)
+ if (!stack_page || !mfinfo_num)
return 0;
pc = thread_saved_pc(p);
+#ifdef CONFIG_KALLSYMS
if (!in_sched_functions(pc))
return pc;
- frame = ((unsigned long *)p->thread.reg30)[schedule_frame.frame_offset];
+ frame = p->thread.reg29 + schedule_frame->frame_size;
do {
int i;
if (frame < stack_page || frame > stack_page + THREAD_SIZE - 32)
return 0;
- for (i = ARRAY_SIZE(mfinfo) - 1; i >= 0; i--) {
+ for (i = mfinfo_num - 1; i >= 0; i--) {
if (pc >= (unsigned long) mfinfo[i].func)
break;
}
if (i < 0)
break;
- if (mfinfo[i].omit_fp)
- break;
pc = ((unsigned long *)frame)[mfinfo[i].pc_offset];
- frame = ((unsigned long *)frame)[mfinfo[i].frame_offset];
+ if (!mfinfo[i].frame_size)
+ break;
+ frame += mfinfo[i].frame_size;
} while (in_sched_functions(pc));
+#endif
return pc;
}
diff --git a/arch/mips/kernel/signal-common.h b/arch/mips/kernel/signal-common.h
index 0fbc492d24b..36bfc2588aa 100644
--- a/arch/mips/kernel/signal-common.h
+++ b/arch/mips/kernel/signal-common.h
@@ -176,7 +176,7 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size)
if ((ka->sa.sa_flags & SA_ONSTACK) && (sas_ss_flags (sp) == 0))
sp = current->sas_ss_sp + current->sas_ss_size;
- return (void __user *)((sp - frame_size) & (ICACHE_REFILLS_WORKAROUND_WAR ? 32 : ALMASK));
+ return (void __user *)((sp - frame_size) & (ICACHE_REFILLS_WORKAROUND_WAR ? ~(cpu_icache_line_size()-1) : ALMASK));
}
static inline int install_sigtramp(unsigned int __user *tramp,
diff --git a/arch/mips/kernel/signal32.c b/arch/mips/kernel/signal32.c
index da3271e1fda..8a8b8dd9041 100644
--- a/arch/mips/kernel/signal32.c
+++ b/arch/mips/kernel/signal32.c
@@ -537,7 +537,7 @@ _sys32_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
/* The ucontext contains a stack32_t, so we must convert! */
if (__get_user(sp, &frame->rs_uc.uc_stack.ss_sp))
goto badframe;
- st.ss_size = (long) sp;
+ st.ss_sp = (void *)(long) sp;
if (__get_user(st.ss_size, &frame->rs_uc.uc_stack.ss_size))
goto badframe;
if (__get_user(st.ss_flags, &frame->rs_uc.uc_stack.ss_flags))
diff --git a/arch/mips/kernel/signal_n32.c b/arch/mips/kernel/signal_n32.c
index 384fc4a639a..5a3776096f0 100644
--- a/arch/mips/kernel/signal_n32.c
+++ b/arch/mips/kernel/signal_n32.c
@@ -108,7 +108,7 @@ _sysn32_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
/* The ucontext contains a stack32_t, so we must convert! */
if (__get_user(sp, &frame->rs_uc.uc_stack.ss_sp))
goto badframe;
- st.ss_size = (long) sp;
+ st.ss_sp = (void *)(long) sp;
if (__get_user(st.ss_size, &frame->rs_uc.uc_stack.ss_size))
goto badframe;
if (__get_user(st.ss_flags, &frame->rs_uc.uc_stack.ss_flags))
diff --git a/arch/mips/kernel/smp_mt.c b/arch/mips/kernel/smp_mt.c
index 794a1c3de2a..c930364830d 100644
--- a/arch/mips/kernel/smp_mt.c
+++ b/arch/mips/kernel/smp_mt.c
@@ -68,6 +68,8 @@ void __init sanitize_tlb_entries(void)
set_c0_mvpcontrol(MVPCONTROL_VPC);
+ back_to_back_c0_hazard();
+
/* Disable TLB sharing */
clear_c0_mvpcontrol(MVPCONTROL_STLB);
@@ -102,35 +104,6 @@ void __init sanitize_tlb_entries(void)
clear_c0_mvpcontrol(MVPCONTROL_VPC);
}
-#if 0
-/*
- * Use c0_MVPConf0 to find out how many CPUs are available, setting up
- * phys_cpu_present_map and the logical/physical mappings.
- */
-void __init prom_build_cpu_map(void)
-{
- int i, num, ncpus;
-
- cpus_clear(phys_cpu_present_map);
-
- /* assume we boot on cpu 0.... */
- cpu_set(0, phys_cpu_present_map);
- __cpu_number_map[0] = 0;
- __cpu_logical_map[0] = 0;
-
- if (cpu_has_mipsmt) {
- ncpus = ((read_c0_mvpconf0() & (MVPCONF0_PVPE)) >> MVPCONF0_PVPE_SHIFT) + 1;
- for (i=1, num=0; i< NR_CPUS && i<ncpus; i++) {
- cpu_set(i, phys_cpu_present_map);
- __cpu_number_map[i] = ++num;
- __cpu_logical_map[num] = i;
- }
-
- printk(KERN_INFO "%i available secondary CPU(s)\n", num);
- }
-}
-#endif
-
static void ipi_resched_dispatch (struct pt_regs *regs)
{
do_IRQ(MIPS_CPU_IPI_RESCHED_IRQ, regs);
@@ -222,6 +195,9 @@ void prom_prepare_cpus(unsigned int max_cpus)
/* set config to be the same as vpe0, particularly kseg0 coherency alg */
write_vpe_c0_config( read_c0_config());
+
+ /* Propagate Config7 */
+ write_vpe_c0_config7(read_c0_config7());
}
}
diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c
index e51c38cef88..1b71d91e826 100644
--- a/arch/mips/mm/c-r4k.c
+++ b/arch/mips/mm/c-r4k.c
@@ -471,61 +471,29 @@ struct flush_icache_range_args {
static inline void local_r4k_flush_icache_range(void *args)
{
struct flush_icache_range_args *fir_args = args;
- unsigned long dc_lsize = cpu_dcache_line_size();
- unsigned long ic_lsize = cpu_icache_line_size();
- unsigned long sc_lsize = cpu_scache_line_size();
unsigned long start = fir_args->start;
unsigned long end = fir_args->end;
- unsigned long addr, aend;
if (!cpu_has_ic_fills_f_dc) {
if (end - start > dcache_size) {
r4k_blast_dcache();
} else {
R4600_HIT_CACHEOP_WAR_IMPL;
- addr = start & ~(dc_lsize - 1);
- aend = (end - 1) & ~(dc_lsize - 1);
-
- while (1) {
- /* Hit_Writeback_Inv_D */
- protected_writeback_dcache_line(addr);
- if (addr == aend)
- break;
- addr += dc_lsize;
- }
+ protected_blast_dcache_range(start, end);
}
if (!cpu_icache_snoops_remote_store) {
- if (end - start > scache_size) {
+ if (end - start > scache_size)
r4k_blast_scache();
- } else {
- addr = start & ~(sc_lsize - 1);
- aend = (end - 1) & ~(sc_lsize - 1);
-
- while (1) {
- /* Hit_Writeback_Inv_SD */
- protected_writeback_scache_line(addr);
- if (addr == aend)
- break;
- addr += sc_lsize;
- }
- }
+ else
+ protected_blast_scache_range(start, end);
}
}
if (end - start > icache_size)
r4k_blast_icache();
- else {
- addr = start & ~(ic_lsize - 1);
- aend = (end - 1) & ~(ic_lsize - 1);
- while (1) {
- /* Hit_Invalidate_I */
- protected_flush_icache_line(addr);
- if (addr == aend)
- break;
- addr += ic_lsize;
- }
- }
+ else
+ protected_blast_icache_range(start, end);
}
static void r4k_flush_icache_range(unsigned long start, unsigned long end)
@@ -619,27 +587,14 @@ static void r4k_flush_icache_page(struct vm_area_struct *vma,
static void r4k_dma_cache_wback_inv(unsigned long addr, unsigned long size)
{
- unsigned long end, a;
-
/* Catch bad driver code */
BUG_ON(size == 0);
if (cpu_has_subset_pcaches) {
- unsigned long sc_lsize = cpu_scache_line_size();
-
- if (size >= scache_size) {
+ if (size >= scache_size)
r4k_blast_scache();
- return;
- }
-
- a = addr & ~(sc_lsize - 1);
- end = (addr + size - 1) & ~(sc_lsize - 1);
- while (1) {
- flush_scache_line(a); /* Hit_Writeback_Inv_SD */
- if (a == end)
- break;
- a += sc_lsize;
- }
+ else
+ blast_scache_range(addr, addr + size);
return;
}
@@ -651,17 +606,8 @@ static void r4k_dma_cache_wback_inv(unsigned long addr, unsigned long size)
if (size >= dcache_size) {
r4k_blast_dcache();
} else {
- unsigned long dc_lsize = cpu_dcache_line_size();
-
R4600_HIT_CACHEOP_WAR_IMPL;
- a = addr & ~(dc_lsize - 1);
- end = (addr + size - 1) & ~(dc_lsize - 1);
- while (1) {
- flush_dcache_line(a); /* Hit_Writeback_Inv_D */
- if (a == end)
- break;
- a += dc_lsize;
- }
+ blast_dcache_range(addr, addr + size);
}
bc_wback_inv(addr, size);
@@ -669,44 +615,22 @@ static void r4k_dma_cache_wback_inv(unsigned long addr, unsigned long size)
static void r4k_dma_cache_inv(unsigned long addr, unsigned long size)
{
- unsigned long end, a;
-
/* Catch bad driver code */
BUG_ON(size == 0);
if (cpu_has_subset_pcaches) {
- unsigned long sc_lsize = cpu_scache_line_size();
-
- if (size >= scache_size) {
+ if (size >= scache_size)
r4k_blast_scache();
- return;
- }
-
- a = addr & ~(sc_lsize - 1);
- end = (addr + size - 1) & ~(sc_lsize - 1);
- while (1) {
- flush_scache_line(a); /* Hit_Writeback_Inv_SD */
- if (a == end)
- break;
- a += sc_lsize;
- }
+ else
+ blast_scache_range(addr, addr + size);
return;
}
if (size >= dcache_size) {
r4k_blast_dcache();
} else {
- unsigned long dc_lsize = cpu_dcache_line_size();
-
R4600_HIT_CACHEOP_WAR_IMPL;
- a = addr & ~(dc_lsize - 1);
- end = (addr + size - 1) & ~(dc_lsize - 1);
- while (1) {
- flush_dcache_line(a); /* Hit_Writeback_Inv_D */
- if (a == end)
- break;
- a += dc_lsize;
- }
+ blast_dcache_range(addr, addr + size);
}
bc_inv(addr, size);
diff --git a/arch/mips/mm/c-tx39.c b/arch/mips/mm/c-tx39.c
index 0a97a9434eb..7c572bea4a9 100644
--- a/arch/mips/mm/c-tx39.c
+++ b/arch/mips/mm/c-tx39.c
@@ -44,8 +44,6 @@ __asm__ __volatile__( \
/* TX39H-style cache flush routines. */
static void tx39h_flush_icache_all(void)
{
- unsigned long start = KSEG0;
- unsigned long end = (start + icache_size);
unsigned long flags, config;
/* disable icache (set ICE#) */
@@ -53,33 +51,18 @@ static void tx39h_flush_icache_all(void)
config = read_c0_conf();
write_c0_conf(config & ~TX39_CONF_ICE);
TX39_STOP_STREAMING();
-
- /* invalidate icache */
- while (start < end) {
- cache16_unroll32(start, Index_Invalidate_I);
- start += 0x200;
- }
-
+ blast_icache16();
write_c0_conf(config);
local_irq_restore(flags);
}
static void tx39h_dma_cache_wback_inv(unsigned long addr, unsigned long size)
{
- unsigned long end, a;
- unsigned long dc_lsize = current_cpu_data.dcache.linesz;
-
/* Catch bad driver code */
BUG_ON(size == 0);
iob();
- a = addr & ~(dc_lsize - 1);
- end = (addr + size - 1) & ~(dc_lsize - 1);
- while (1) {
- invalidate_dcache_line(a); /* Hit_Invalidate_D */
- if (a == end) break;
- a += dc_lsize;
- }
+ blast_inv_dcache_range(addr, addr + size);
}
@@ -241,42 +224,21 @@ static void tx39_flush_data_cache_page(unsigned long addr)
static void tx39_flush_icache_range(unsigned long start, unsigned long end)
{
- unsigned long dc_lsize = current_cpu_data.dcache.linesz;
- unsigned long addr, aend;
-
if (end - start > dcache_size)
tx39_blast_dcache();
- else {
- addr = start & ~(dc_lsize - 1);
- aend = (end - 1) & ~(dc_lsize - 1);
-
- while (1) {
- /* Hit_Writeback_Inv_D */
- protected_writeback_dcache_line(addr);
- if (addr == aend)
- break;
- addr += dc_lsize;
- }
- }
+ else
+ protected_blast_dcache_range(start, end);
if (end - start > icache_size)
tx39_blast_icache();
else {
unsigned long flags, config;
- addr = start & ~(dc_lsize - 1);
- aend = (end - 1) & ~(dc_lsize - 1);
/* disable icache (set ICE#) */
local_irq_save(flags);
config = read_c0_conf();
write_c0_conf(config & ~TX39_CONF_ICE);
TX39_STOP_STREAMING();
- while (1) {
- /* Hit_Invalidate_I */
- protected_flush_icache_line(addr);
- if (addr == aend)
- break;
- addr += dc_lsize;
- }
+ protected_blast_icache_range(start, end);
write_c0_conf(config);
local_irq_restore(flags);
}
@@ -311,7 +273,7 @@ static void tx39_flush_icache_page(struct vm_area_struct *vma, struct page *page
static void tx39_dma_cache_wback_inv(unsigned long addr, unsigned long size)
{
- unsigned long end, a;
+ unsigned long end;
if (((size | addr) & (PAGE_SIZE - 1)) == 0) {
end = addr + size;
@@ -322,20 +284,13 @@ static void tx39_dma_cache_wback_inv(unsigned long addr, unsigned long size)
} else if (size > dcache_size) {
tx39_blast_dcache();
} else {
- unsigned long dc_lsize = current_cpu_data.dcache.linesz;
- a = addr & ~(dc_lsize - 1);
- end = (addr + size - 1) & ~(dc_lsize - 1);
- while (1) {
- flush_dcache_line(a); /* Hit_Writeback_Inv_D */
- if (a == end) break;
- a += dc_lsize;
- }
+ blast_dcache_range(addr, addr + size);
}
}
static void tx39_dma_cache_inv(unsigned long addr, unsigned long size)
{
- unsigned long end, a;
+ unsigned long end;
if (((size | addr) & (PAGE_SIZE - 1)) == 0) {
end = addr + size;
@@ -346,14 +301,7 @@ static void tx39_dma_cache_inv(unsigned long addr, unsigned long size)
} else if (size > dcache_size) {
tx39_blast_dcache();
} else {
- unsigned long dc_lsize = current_cpu_data.dcache.linesz;
- a = addr & ~(dc_lsize - 1);
- end = (addr + size - 1) & ~(dc_lsize - 1);
- while (1) {
- invalidate_dcache_line(a); /* Hit_Invalidate_D */
- if (a == end) break;
- a += dc_lsize;
- }
+ blast_inv_dcache_range(addr, addr + size);
}
}
diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig
index 7c914a4c67c..eca33cfa8a4 100644
--- a/arch/parisc/Kconfig
+++ b/arch/parisc/Kconfig
@@ -29,6 +29,11 @@ config GENERIC_CALIBRATE_DELAY
bool
default y
+config TIME_LOW_RES
+ bool
+ depends on SMP
+ default y
+
config GENERIC_ISA_DMA
bool
diff --git a/arch/s390/lib/delay.c b/arch/s390/lib/delay.c
index e96c35bddac..71f0a2fb307 100644
--- a/arch/s390/lib/delay.c
+++ b/arch/s390/lib/delay.c
@@ -30,7 +30,7 @@ void __delay(unsigned long loops)
*/
__asm__ __volatile__(
"0: brct %0,0b"
- : /* no outputs */ : "r" (loops/2) );
+ : /* no outputs */ : "r" ((loops/2) + 1));
}
/*
diff --git a/arch/v850/Kconfig b/arch/v850/Kconfig
index 04494638b96..e7fc3e50034 100644
--- a/arch/v850/Kconfig
+++ b/arch/v850/Kconfig
@@ -28,6 +28,10 @@ config GENERIC_IRQ_PROBE
bool
default y
+config TIME_LOW_RES
+ bool
+ default y
+
# Turn off some random 386 crap that can affect device config
config ISA
bool