aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/common/Kconfig1
-rw-r--r--arch/arm/mach-ns9xxx/mach-cc9p9360dev.c2
-rw-r--r--arch/arm/mach-pxa/tosa.c3
-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/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/irq.c14
-rw-r--r--arch/mips/arc/init.c6
-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/x86_64/kernel/smpboot.c5
34 files changed, 536 insertions, 415 deletions
diff --git a/arch/arm/common/Kconfig b/arch/arm/common/Kconfig
index 5e34ca6..3e07346 100644
--- a/arch/arm/common/Kconfig
+++ b/arch/arm/common/Kconfig
@@ -28,6 +28,7 @@ config SHARP_PARAM
config SHARPSL_PM
bool
+ select APM_EMULATION
config SHARP_SCOOP
bool
diff --git a/arch/arm/mach-ns9xxx/mach-cc9p9360dev.c b/arch/arm/mach-ns9xxx/mach-cc9p9360dev.c
index a193dd9..760c9d0 100644
--- a/arch/arm/mach-ns9xxx/mach-cc9p9360dev.c
+++ b/arch/arm/mach-ns9xxx/mach-cc9p9360dev.c
@@ -32,7 +32,7 @@ static void __init mach_cc9p9360dev_init_machine(void)
board_a9m9750dev_init_machine();
}
-MACHINE_START(CC9P9360DEV, "Connect Core 9P 9360 on an A9M9750 Devboard")
+MACHINE_START(CC9P9360DEV, "Digi ConnectCore 9P 9360 on an A9M9750 Devboard")
.map_io = mach_cc9p9360dev_map_io,
.init_irq = mach_cc9p9360dev_init_irq,
.init_machine = mach_cc9p9360dev_init_machine,
diff --git a/arch/arm/mach-pxa/tosa.c b/arch/arm/mach-pxa/tosa.c
index 7915a5a..7273877 100644
--- a/arch/arm/mach-pxa/tosa.c
+++ b/arch/arm/mach-pxa/tosa.c
@@ -28,6 +28,7 @@
#include <asm/hardware.h>
#include <asm/irq.h>
#include <asm/system.h>
+#include <asm/arch/pxa-regs.h>
#include <asm/arch/irda.h>
#include <asm/arch/mmc.h>
#include <asm/arch/udc.h>
@@ -35,8 +36,6 @@
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <asm/mach/irq.h>
-
-#include <asm/arch/pxa-regs.h>
#include <asm/arch/tosa.h>
#include <asm/hardware/scoop.h>
diff --git a/arch/avr32/kernel/ptrace.c b/arch/avr32/kernel/ptrace.c
index f2e81cd..6f4388f 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)
__mtdr(DBGREG_DC, dc);
ti = current_thread_info();
- ti->flags |= _TIF_BREAKPOINT;
+ set_ti_thread_flag(ti, TIF_BREAKPOINT);
/* The TLB miss handlers don't check thread flags */
if ((regs->pc >= (unsigned long)&itlb_miss)
@@ -328,7 +328,7 @@ asmlinkage void do_debug_priv(struct pt_regs *regs)
* single step.
*/
if ((regs->sr & MODE_MASK) != MODE_SUPERVISOR)
- ti->flags |= TIF_SINGLE_STEP;
+ set_ti_thread_flag(ti, TIF_SINGLE_STEP);
} else {
panic("Unable to handle debug trap at pc = %08lx\n",
regs->pc);
diff --git a/arch/avr32/kernel/traps.c b/arch/avr32/kernel/traps.c
index 7e803f4..adc01a1 100644
--- a/arch/avr32/kernel/traps.c
+++ b/arch/avr32/kernel/traps.c
@@ -49,39 +49,45 @@ out:
return;
}
+static inline int valid_stack_ptr(struct thread_info *tinfo, unsigned long p)
+{
+ return (p > (unsigned long)tinfo)
+ && (p < (unsigned long)tinfo + THREAD_SIZE - 3);
+}
+
#ifdef CONFIG_FRAME_POINTER
static inline void __show_trace(struct task_struct *tsk, unsigned long *sp,
struct pt_regs *regs)
{
- unsigned long __user *fp;
- unsigned long __user *last_fp = NULL;
-
- if (regs) {
- fp = (unsigned long __user *)regs->r7;
- } else if (tsk == current) {
- register unsigned long __user *real_fp __asm__("r7");
- fp = real_fp;
- } else {
- fp = (unsigned long __user *)tsk->thread.cpu_context.r7;
- }
+ unsigned long lr, fp;
+ struct thread_info *tinfo;
+
+ tinfo = (struct thread_info *)
+ ((unsigned long)sp & ~(THREAD_SIZE - 1));
+
+ if (regs)
+ fp = regs->r7;
+ else if (tsk == current)
+ asm("mov %0, r7" : "=r"(fp));
+ else
+ fp = tsk->thread.cpu_context.r7;
/*
- * Walk the stack until (a) we get an exception, (b) the frame
- * pointer becomes zero, or (c) the frame pointer gets stuck
- * at the same value.
+ * Walk the stack as long as the frame pointer (a) is within
+ * the kernel stack of the task, and (b) it doesn't move
+ * downwards.
*/
- while (fp && fp != last_fp) {
- unsigned long lr, new_fp = 0;
-
- last_fp = fp;
- if (__get_user(lr, fp))
- break;
- if (fp && __get_user(new_fp, fp + 1))
- break;
- fp = (unsigned long __user *)new_fp;
+ while (valid_stack_ptr(tinfo, fp)) {
+ unsigned long new_fp;
+ lr = *(unsigned long *)fp;
printk(" [<%08lx>] ", lr);
print_symbol("%s\n", lr);
+
+ new_fp = *(unsigned long *)(fp + 4);
+ if (new_fp <= fp)
+ break;
+ fp = new_fp;
}
printk("\n");
}
diff --git a/arch/avr32/mach-at32ap/at32ap7000.c b/arch/avr32/mach-at32ap/at32ap7000.c
index bc23550..472703f 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[] = {
DEFINE_DEV(atmel_spi, 1);
DEV_CLK(spi_clk, atmel_spi1, pba, 1);
-static void
+static void __init
at32_spi_setup_slaves(unsigned int bus_num, struct spi_board_info *b,
unsigned int n, const u8 *pins)
{
diff --git a/arch/avr32/mm/cache.c b/arch/avr32/mm/cache.c
index fb13f72..8f7b1c3 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)
void flush_icache_page(struct vm_area_struct *vma, struct page *page)
{
if (vma->vm_flags & VM_EXEC) {
- void *v = kmap(page);
+ void *v = page_address(page);
__flush_icache_range((unsigned long)v, (unsigned long)v + PAGE_SIZE);
- kunmap(v);
}
}
diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c
index 9b0dd27..4ff55e6 100644
--- a/arch/i386/kernel/smpboot.c
+++ b/arch/i386/kernel/smpboot.c
@@ -45,6 +45,7 @@
#include <linux/notifier.h>
#include <linux/cpu.h>
#include <linux/percpu.h>
+#include <linux/nmi.h>
#include <linux/delay.h>
#include <linux/mc146818rtc.h>
@@ -1278,8 +1279,9 @@ void __cpu_die(unsigned int cpu)
int __cpuinit __cpu_up(unsigned int cpu)
{
+ unsigned long flags;
#ifdef CONFIG_HOTPLUG_CPU
- int ret=0;
+ int ret = 0;
/*
* We do warm boot only on cpus that had booted earlier
@@ -1297,23 +1299,25 @@ int __cpuinit __cpu_up(unsigned int cpu)
/* In case one didn't come up */
if (!cpu_isset(cpu, cpu_callin_map)) {
printk(KERN_DEBUG "skipping cpu%d, didn't come online\n", cpu);
- local_irq_enable();
return -EIO;
}
- local_irq_enable();
-
per_cpu(cpu_state, cpu) = CPU_UP_PREPARE;
/* Unleash the CPU! */
cpu_set(cpu, smp_commenced_mask);
/*
- * Check TSC synchronization with the AP:
+ * Check TSC synchronization with the AP (keep irqs disabled
+ * while doing so):
*/
+ local_irq_save(flags);
check_tsc_sync_source(cpu);
+ local_irq_restore(flags);
- while (!cpu_isset(cpu, cpu_online_map))
+ while (!cpu_isset(cpu, cpu_online_map)) {
cpu_relax();
+ touch_nmi_watchdog();
+ }
#ifdef CONFIG_X86_GENERICARCH
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 75a2a2c..2236fab 100644
--- a/arch/ia64/kernel/asm-offsets.c
+++ b/arch/ia64/kernel/asm-offsets.c
@@ -35,6 +35,7 @@ void foo(void)
BLANK();
DEFINE(TI_FLAGS, offsetof(struct thread_info, flags));
+ DEFINE(TI_CPU, offsetof(struct thread_info, cpu));
DEFINE(TI_PRE_COUNT, offsetof(struct thread_info, preempt_count));
BLANK();
diff --git a/arch/ia64/kernel/efi.c b/arch/ia64/kernel/efi.c
index 4061593..49b9368 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)
if (!is_memory_available(md))
continue;
+#ifdef CONFIG_CRASH_DUMP
+ /* saved_max_pfn should ignore max_addr= command line arg */
+ if (saved_max_pfn < (efi_md_end(md) >> PAGE_SHIFT))
+ saved_max_pfn = (efi_md_end(md) >> PAGE_SHIFT);
+#endif
/*
* Round ends inward to granule boundaries
* Give trimmings to uncached allocator
@@ -1010,11 +1015,6 @@ efi_memmap_init(unsigned long *s, unsigned long *e)
} else
ae = efi_md_end(md);
-#ifdef CONFIG_CRASH_DUMP
- /* saved_max_pfn should ignore max_addr= command line arg */
- if (saved_max_pfn < (ae >> PAGE_SHIFT))
- saved_max_pfn = (ae >> PAGE_SHIFT);
-#endif
/* keep within max_addr= and min_addr= command line arg */
as = max(as, min_addr);
ae = min(ae, max_addr);
diff --git a/arch/ia64/kernel/fsys.S b/arch/ia64/kernel/fsys.S
index 7a05b1c..8589e84 100644
--- a/arch/ia64/kernel/fsys.S
+++ b/arch/ia64/kernel/fsys.S
@@ -10,6 +10,8 @@
* probably broke it along the way... ;-)
* 13-Jul-04 clameter Implement fsys_clock_gettime and revise fsys_gettimeofday to make
* it capable of using memory based clocks without falling back to C code.
+ * 08-Feb-07 Fenghua Yu Implement fsys_getcpu.
+ *
*/
#include <asm/asmmacro.h>
@@ -505,6 +507,59 @@ EX(.fail_efault, (p15) st8 [r34]=r3)
#endif
END(fsys_rt_sigprocmask)
+/*
+ * fsys_getcpu doesn't use the third parameter in this implementation. It reads
+ * current_thread_info()->cpu and corresponding node in cpu_to_node_map.
+ */
+ENTRY(fsys_getcpu)
+ .prologue
+ .altrp b6
+ .body
+ ;;
+ add r2=TI_FLAGS+IA64_TASK_SIZE,r16
+ tnat.nz p6,p0 = r32 // guard against NaT argument
+ add r3=TI_CPU+IA64_TASK_SIZE,r16
+ ;;
+ ld4 r3=[r3] // M r3 = thread_info->cpu
+ ld4 r2=[r2] // M r2 = thread_info->flags
+(p6) br.cond.spnt.few .fail_einval // B
+ ;;
+ tnat.nz p7,p0 = r33 // I guard against NaT argument
+(p7) br.cond.spnt.few .fail_einval // B
+#ifdef CONFIG_NUMA
+ movl r17=cpu_to_node_map
+ ;;
+EX(.fail_efault, probe.w.fault r32, 3) // M This takes 5 cycles
+EX(.fail_efault, probe.w.fault r33, 3) // M This takes 5 cycles
+ shladd r18=r3,1,r17
+ ;;
+ ld2 r20=[r18] // r20 = cpu_to_node_map[cpu]
+ and r2 = TIF_ALLWORK_MASK,r2
+ ;;
+ cmp.ne p8,p0=0,r2
+(p8) br.spnt.many fsys_fallback_syscall
+ ;;
+ ;;
+EX(.fail_efault, st4 [r32] = r3)
+EX(.fail_efault, st2 [r33] = r20)
+ mov r8=0
+ ;;
+#else
+EX(.fail_efault, probe.w.fault r32, 3) // M This takes 5 cycles
+EX(.fail_efault, probe.w.fault r33, 3) // M This takes 5 cycles
+ and r2 = TIF_ALLWORK_MASK,r2
+ ;;
+ cmp.ne p8,p0=0,r2
+(p8) br.spnt.many fsys_fallback_syscall
+ ;;
+EX(.fail_efault, st4 [r32] = r3)
+EX(.fail_efault, st2 [r33] = r0)
+ mov r8=0
+ ;;
+#endif
+ FSYS_RETURN
+END(fsys_getcpu)
+
ENTRY(fsys_fallback_syscall)
.prologue
.altrp b6
@@ -878,6 +933,56 @@ fsyscall_table:
data8 0 // timer_delete
data8 0 // clock_settime
data8 fsys_clock_gettime // clock_gettime
+ data8 0 // clock_getres // 1255
+ data8 0 // clock_nanosleep
+ data8 0 // fstatfs64
+ data8 0 // statfs64
+ data8 0 // mbind
+ data8 0 // get_mempolicy // 1260
+ data8 0 // set_mempolicy
+ data8 0 // mq_open
+ data8 0 // mq_unlink
+ data8 0 // mq_timedsend
+ data8 0 // mq_timedreceive // 1265
+ data8 0 // mq_notify
+ data8 0 // mq_getsetattr
+ data8 0 // kexec_load
+ data8 0 // vserver
+ data8 0 // waitid // 1270
+ data8 0 // add_key
+ data8 0 // request_key
+ data8 0 // keyctl
+ data8 0 // ioprio_set
+ data8 0 // ioprio_get // 1275
+ data8 0 // move_pages
+ data8 0 // inotify_init
+ data8 0 // inotify_add_watch
+ data8 0 // inotify_rm_watch
+ data8 0 // migrate_pages // 1280
+ data8 0 // openat
+ data8 0 // mkdirat
+ data8 0 // mknodat
+ data8 0 // fchownat
+ data8 0 // futimesat // 1285
+ data8 0 // newfstatat
+ data8 0 // unlinkat
+ data8 0 // renameat
+ data8 0 // linkat
+ data8 0 // symlinkat // 1290
+ data8 0 // readlinkat
+ data8 0 // fchmodat
+ data8 0 // faccessat
+ data8 0
+ data8 0 // 1295
+ data8 0 // unshare
+ data8 0 // splice
+ data8 0 // set_robust_list
+ data8 0 // get_robust_list
+ data8 0 // sync_file_range // 1300
+ data8 0 // tee
+ data8 0 // vmsplice
+ data8 0
+ data8 fsys_getcpu // getcpu // 1304
// fill in zeros for the remaining entries
.zero:
diff --git a/arch/ia64/kernel/iosapic.c b/arch/ia64/kernel/iosapic.c
index d6aab40..dcfbf3e 100644
--- a/arch/ia64/kernel/iosapic.c
+++ b/arch/ia64/kernel/iosapic.c
@@ -446,7 +446,7 @@ iosapic_end_level_irq (unsigned int irq)
#define iosapic_disable_level_irq mask_irq
#define iosapic_ack_level_irq nop
-struct hw_interrupt_type irq_type_iosapic_level = {
+struct irq_chip irq_type_iosapic_level = {
.name = "IO-SAPIC-level",
.startup = iosapic_startup_level_irq,
.shutdown = iosapic_shutdown_level_irq,
@@ -454,6 +454,8 @@ struct hw_interrupt_type irq_type_iosapic_level = {
.disable = iosapic_disable_level_irq,
.ack = iosapic_ack_level_irq,
.end = iosapic_end_level_irq,
+ .mask = mask_irq,
+ .unmask = unmask_irq,
.set_affinity = iosapic_set_affinity
};
@@ -493,7 +495,7 @@ iosapic_ack_edge_irq (unsigned int irq)
#define iosapic_disable_edge_irq nop
#define iosapic_end_edge_irq nop
-struct hw_interrupt_type irq_type_iosapic_edge = {
+struct irq_chip irq_type_iosapic_edge = {
.name = "IO-SAPIC-edge",
.startup = iosapic_startup_edge_irq,
.shutdown = iosapic_disable_edge_irq,
@@ -501,6 +503,8 @@ struct hw_interrupt_type irq_type_iosapic_edge = {
.disable = iosapic_disable_edge_irq,
.ack = iosapic_ack_edge_irq,
.end = iosapic_end_edge_irq,
+ .mask = mask_irq,
+ .unmask = unmask_irq,
.set_affinity = iosapic_set_affinity
};
diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c
index 7d6fe65..339e8a5 100644
--- a/arch/ia64/kernel/setup.c
+++ b/arch/ia64/kernel/setup.c
@@ -91,8 +91,6 @@ static struct resource code_resource = {
.name = "Kernel code",
.flags = IORESOURCE_BUSY | IORESOURCE_MEM
};
-extern void efi_initialize_iomem_resources(struct resource *,
- struct resource *);
extern char _text[], _end[], _etext[];
unsigned long ia64_max_cacheline_size;
diff --git a/arch/ia64/sn/kernel/irq.c b/arch/ia64/sn/kernel/irq.c
index 8c5bee0..8d2a1bf 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)
(void)sn_retarget_vector(sn_irq_info, nasid, slice);
}
-struct hw_interrupt_type irq_type_sn = {
+static void
+sn_mask_irq(unsigned int irq)
+{
+}
+
+static void
+sn_unmask_irq(unsigned int irq)
+{
+}
+
+struct irq_chip irq_type_sn = {
.name = "SN hub",
.startup = sn_startup_irq,
.shutdown = sn_shutdown_irq,
@@ -213,6 +223,8 @@ struct hw_interrupt_type irq_type_sn = {
.disable = sn_disable_irq,
.ack = sn_ack_irq,
.end = sn_end_irq,
+ .mask = sn_mask_irq,
+ .unmask = sn_unmask_irq,
.set_affinity = sn_set_affinity_irq
};
diff --git a/arch/mips/arc/init.c b/arch/mips/arc/init.c
index 0ac8f42..e2f75b1 100644
--- a/arch/mips/arc/init.c
+++ b/arch/mips/arc/init.c
@@ -23,16 +23,16 @@ LONG *_prom_argv, *_prom_envp;
void __init prom_init(void)
{
PSYSTEM_PARAMETER_BLOCK pb = PROMBLOCK;
+
romvec = ROMVECTOR;
- ULONG cnt;
- CHAR c;
prom_argc = fw_arg0;
_prom_argv = (LONG *) fw_arg1;
_prom_envp = (LONG *) fw_arg2;
if (pb->magic != 0x53435241) {
- printk(KERN_CRIT "Aieee, bad prom vector magic %08lx\n", pb->magic);
+ printk(KERN_CRIT "Aieee, bad prom vector magic %08lx\n",
+ (unsigned long) pb->magic);
while(1)
;
}
diff --git a/arch/sh/boards/renesas/r7780rp/Makefile b/arch/sh/boards/renesas/r7780rp/Makefile
index 3c93012..ed5f5a9 100644
--- a/arch/sh/boards/renesas/r7780rp/Makefile
+++ b/arch/sh/boards/renesas/r7780rp/Makefile
@@ -2,6 +2,6 @@
# Makefile for the R7780RP-1 specific parts of the kernel
#
-obj-y := setup.o io.o irq.o
+obj-y := setup.o irq.o
obj-$(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 f74d2ff..0000000
--- a/arch/sh/boards/renesas/r7780rp/io.c
+++ /dev/null
@@ -1,233 +0,0 @@
-/*
- * Copyright (C) 2001 Ian da Silva, Jeremy Siegel
- * Based largely on io_se.c.
- *
- * I/O routine for Renesas Solutions Highlander R7780RP-1
- *
- * Initial version only to support LAN access; some
- * placeholder code from io_r7780rp.c left in with the
- * expectation of later SuperIO and PCMCIA access.
- */
-#include <linux/pci.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/io.h>
-#include <asm/r7780rp.h>
-#include <asm/addrspace.h>
-
-static inline unsigned long port88796l(unsigned int port, int flag)
-{
- unsigned long addr;
-
- if (flag)
- addr = PA_AX88796L + ((port - AX88796L_IO_BASE) << 1);
- else
- addr = PA_AX88796L + ((port - AX88796L_IO_BASE) << 1) + 0x1000;
-
- return addr;
-}
-
-#if defined(CONFIG_NE2000) || defined(CONFIG_NE2000_MODULE)
-#define CHECK_AX88796L_PORT(port) \
- ((port >= AX88796L_IO_BASE) && (port < (AX88796L_IO_BASE+0x20)))
-#else
-#define CHECK_AX88796L_PORT(port) (0)
-#endif
-
-/*
- * General outline: remap really low stuff [eventually] to SuperIO,
- * stuff in PCI IO space (at or above window at pci.h:PCIBIOS_MIN_IO)
- * is mapped through the PCI IO window. Stuff with high bits (PXSEG)
- * should be way beyond the window, and is used w/o translation for
- * compatibility.
- */
-u8 r7780rp_inb(unsigned long port)
-{
- if (CHECK_AX88796L_PORT(port))
- return ctrl_inw(port88796l(port, 0)) & 0xff;
- else if (is_pci_ioaddr(port))
- return ctrl_inb(pci_ioaddr(port));
-
- return ctrl_inw(port) & 0xff;
-}
-
-u8 r7780rp_inb_p(unsigned long port)
-{
- u8 v;
-
- if (CHECK_AX88796L_PORT(port))
- v = ctrl_inw(port88796l(port, 0)) & 0xff;
- else if (is_pci_ioaddr(port))
- v = ctrl_inb(pci_ioaddr(port));
- else
- v = ctrl_inw(port) & 0xff;
-
- ctrl_delay();
-
- return v;
-}
-
-u16 r7780rp_inw(unsigned long port)
-{
- if (is_pci_ioaddr(port))
- return ctrl_inw(pci_ioaddr(port));
-
- return ctrl_inw(port);
-}
-
-u32 r7780rp_inl(unsigned long port)
-{
- if (is_pci_ioaddr(port))
- return ctrl_inl(pci_ioaddr(port));
-
- return ctrl_inl(port);
-}
-
-void r7780rp_outb(u8 value, unsigned long port)
-{
- if (CHECK_AX88796L_PORT(port))
- ctrl_outw(value, port88796l(port, 0));
- else if (is_pci_ioaddr(port))
- ctrl_outb(value, pci_ioaddr(port));
- else
- ctrl_outb(value, port);
-}
-
-void r7780rp_outb_p(u8 value, unsigned long port)
-{
- if (CHECK_AX88796L_PORT(port))
- ctrl_outw(value, port88796l(port, 0));
- else if (is_pci_ioaddr(port))
- ctrl_outb(value, pci_ioaddr(port));
- else
- ctrl_outb(value, port);
-
- ctrl_delay();
-}
-
-void r7780rp_outw(u16 value, unsigned long port)
-{
- if (is_pci_ioaddr(port))
- ctrl_outw(value, pci_ioaddr(port));
- else
- ctrl_outw(value, port);
-}
-
-void r7780rp_outl(u32 value, unsigned long port)
-{
- if (is_pci_ioaddr(port))
- ctrl_outl(value, pci_ioaddr(port));
- else
- ctrl_outl(value, port);
-}
-
-void r7780rp_insb(unsigned long port, void *dst, unsigned long count)
-{
- volatile u16 *p;
- u8 *buf = dst;
-
- if (CHECK_AX88796L_PORT(port)) {
- p = (volatile u16 *)port88796l(port, 0);
- while (count--)
- *buf++ = *p & 0xff;
- } else if (is_pci_ioaddr(port)) {
- volatile u8 *bp = (volatile u8 *)pci_ioaddr(port);
-
- while (count--)
- *buf++ = *bp;
- } else {
- p = (volatile u16 *)port;
- while (count--)
- *buf++ = *p & 0xff;
- }
-}
-
-void r7780rp_insw(unsigned long port, void *dst, unsigned long count)
-{
- volatile u16 *p;
- u16 *buf = dst;
-
- if (CHECK_AX88796L_PORT(port))
- p = (volatile u16 *)port88796l(port, 1);
- else if (is_pci_ioaddr(port))
- p = (volatile u16 *)pci_ioaddr(port);
- else
- p = (volatile u16 *)port;
-
- while (count--)
- *buf++ = *p;
-
- flush_dcache_all();
-}
-
-void r7780rp_insl(unsigned long port, void *dst, unsigned long count)
-{
- if (is_pci_ioaddr(port)) {
- volatile u32 *p = (volatile u32 *)pci_ioaddr(port);
- u32 *buf = dst;
-
- while (count--)
- *buf++ = *p;
- }
-}
-
-void r7780rp_outsb(unsigned long port, const void *src, unsigned long count)
-{
- volatile u16 *p;
- const u8 *buf = src;
-
- if (CHECK_AX88796L_PORT(port)) {
- p = (volatile u16 *)port88796l(port, 0);
- while (count--)
- *p = *buf++;
- } else if (is_pci_ioaddr(port)) {
- volatile u8 *bp = (volatile u8 *)pci_ioaddr(port);
-
- while (count--)
- *bp = *buf++;
- } else
- while (count--)
- ctrl_outb(*buf++, port);
-}
-
-void r7780rp_outsw(unsigned long port, const void *src, unsigned long count)
-{
- volatile u16 *p;
- const u16 *buf = src;
-
- if (CHECK_AX88796L_PORT(port))
- p = (volatile u16 *)port88796l(port, 1);
- else if (is_pci_ioaddr(port))
- p = (volatile u16 *)pci_ioaddr(port);
- else
- p = (volatile u16 *)port;
-
- while (count--)
- *p = *buf++;
-
- flush_dcache_all();
-}
-
-void r7780rp_outsl(unsigned long port, const void *src, unsigned long count)
-{
- const u32 *buf = src;
- u32 *p;
-
- if (is_pci_ioaddr(port))
- p = (u32 *)pci_ioaddr(port);
- else
- p = (u32 *)port;
-
- while (count--)
- ctrl_outl(*buf++, (unsigned long)p);
-}
-
-void __iomem *r7780rp_ioport_map(unsigned long port, unsigned int size)
-{
- if (CHECK_AX88796L_PORT(port))
- return (void __iomem *)port88796l(port, size > 1);
- else if (is_pci_ioaddr(port))
- return (void __iomem *)pci_ioaddr(port);
-
- return (void __iomem *)port;
-}
diff --git a/arch/sh/boards/renesas/r7780rp/setup.c b/arch/sh/boards/renesas/r7780rp/setup.c
index 0d74db9..2faba66 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)
struct sh_machine_vector mv_r7780rp __initmv = {
.mv_name = "Highlander R7780RP-1",
.mv_setup = r7780rp_setup,
-
.mv_nr_irqs = 109,
-
- .mv_inb = r7780rp_inb,
- .mv_inw = r7780rp_inw,
- .mv_inl = r7780rp_inl,
- .mv_outb = r7780rp_outb,
- .mv_outw = r7780rp_outw,
- .mv_outl = r7780rp_outl,
-
- .mv_inb_p = r7780rp_inb_p,
- .mv_inw_p = r7780rp_inw,
- .mv_inl_p = r7780rp_inl,
- .mv_outb_p = r7780rp_outb_p,
- .mv_outw_p = r7780rp_outw,
- .mv_outl_p = r7780rp_outl,
-
- .mv_insb = r7780rp_insb,
- .mv_insw = r7780rp_insw,
- .mv_insl = r7780rp_insl,
- .mv_outsb = r7780rp_outsb,
- .mv_outsw = r7780rp_outsw,
- .mv_outsl = r7780rp_outsl,
-
- .mv_ioport_map = r7780rp_ioport_map,
.mv_init_irq = init_r7780rp_IRQ,
};
ALIAS_MV(r7780rp)
diff --git a/arch/sh/boards/renesas/rts7751r2d/setup.c b/arch/sh/boards/renesas/rts7751r2d/setup.c
index 44b4208..593f26a 100644
--- a/arch/sh/boards/renesas/rts7751r2d/setup.c
+++ b/arch/sh/boards/renesas/rts7751r2d/setup.c
@@ -12,6 +12,7 @@
#include <linux/platform_device.h>
#include <linux/pata_platform.h>
#include <linux/serial_8250.h>
+#include <linux/sm501.h>
#include <linux/pm.h>
#include <asm/machvec.h>
#include <asm/rts7751r2d.h>
@@ -111,10 +112,35 @@ static struct platform_device heartbeat_device = {
.resource = heartbeat_resources,
};
+static struct resource sm501_resources[] = {
+ [0] = {
+ .start = 0x10000000,
+ .end = 0x13e00000 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 0x13e00000,
+ .end = 0x13ffffff,
+ .flags = IORESOURCE_MEM,
+ },
+ [2] = {
+ .start = 32,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device sm501_device = {
+ .name = "sm501",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(sm501_resources),
+ .resource = sm501_resources,
+};
+
static struct platform_device *rts7751r2d_devices[] __initdata = {
&uart_device,
&heartbeat_device,
&cf_ide_device,
+ &sm501_device,
};
static int __init rts7751r2d_devices_setup(void)
diff --git a/arch/sh/configs/rts7751r2d_defconfig b/arch/sh/configs/rts7751r2d_defconfig
index db6a02d..a59bb78 100644
--- a/arch/sh/configs/rts7751r2d_defconfig
+++ b/arch/sh/configs/rts7751r2d_defconfig
@@ -1,14 +1,13 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.20
-# Thu Feb 15 17:17:29 2007
+# Linux kernel version: 2.6.21-rc1
+# Thu Mar 1 16:42:40 2007
#
CONFIG_SUPERH=y
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_FIND_NEXT_BIT=y
CONFIG_GENERIC_HWEIGHT=y
CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
# CONFIG_GENERIC_TIME is not set
@@ -33,6 +32,7 @@ CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
# CONFIG_IPC_NS is not set
+CONFIG_SYSVIPC_SYSCTL=y
# CONFIG_POSIX_MQUEUE is not set
# CONFIG_BSD_PROCESS_ACCT is not set
# CONFIG_TASKSTATS is not set
@@ -119,7 +119,6 @@ CONFIG_SH_RTS7751R2D=y
# CONFIG_SH_SHMIN is not set
# CONFIG_SH_7206_SOLUTION_ENGINE is not set
# CONFIG_SH_7619_SOLUTION_ENGINE is not set
-# CONFIG_SH_ASDAP310 is not set
# CONFIG_SH_UNKNOWN is not set
#
@@ -281,7 +280,7 @@ CONFIG_ZERO_PAGE_OFFSET=0x00010000
CONFIG_BOOT_LINK_OFFSET=0x00800000
# CONFIG_UBC_WAKEUP is not set
CONFIG_CMDLINE_BOOL=y
-CONFIG_CMDLINE="console=ttySC0,115200 root=/dev/sda1"
+CONFIG_CMDLINE="console=tty0 console=ttySC0,115200 root=/dev/sda1"
#
# Bus options
@@ -433,6 +432,7 @@ CONFIG_FW_LOADER=m
#
# Plug and Play support
#
+# CONFIG_PNPACPI is not set
#
# Block devices
@@ -770,7 +770,26 @@ CONFIG_NET_WIRELESS=y
#
# Input device support
#
-# CONFIG_INPUT is not set
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+
+#
+# Userland interfaces
+#
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
#
# Hardware I/O ports
@@ -781,7 +800,10 @@ CONFIG_NET_WIRELESS=y
#
# Character devices
#
-# CONFIG_VT is not set
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+CONFIG_VT_HW_CONSOLE_BINDING=y
# CONFIG_SERIAL_NONSTANDARD is not set
#
@@ -857,6 +879,11 @@ CONFIG_HWMON=y
# CONFIG_HWMON_DEBUG_CHIP is not set
#
+# Multifunction device drivers
+#
+CONFIG_MFD_SM501=y
+
+#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
@@ -869,9 +896,66 @@ CONFIG_HWMON=y
#
# Graphics support
#
-CONFIG_FIRMWARE_EDID=y
-# CONFIG_FB is not set
# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+CONFIG_FB=y
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB_DDC is not set
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_SVGALIB is not set
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frambuffer hardware drivers
+#
+# CONFIG_FB_CIRRUS is not set
+# CONFIG_FB_PM2 is not set
+# CONFIG_FB_CYBER2000 is not set
+# CONFIG_FB_ASILIANT is not set
+# CONFIG_FB_IMSTT is not set
+# CONFIG_FB_EPSON1355 is not set
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_NVIDIA is not set
+# CONFIG_FB_RIVA is not set
+# CONFIG_FB_MATROX is not set
+# CONFIG_FB_RADEON is not set
+# CONFIG_FB_ATY128 is not set
+# CONFIG_FB_ATY is not set
+# CONFIG_FB_S3 is not set
+# CONFIG_FB_SAVAGE is not set
+# CONFIG_FB_SIS is not set
+# CONFIG_FB_NEOMAGIC is not set
+# CONFIG_FB_KYRO is not set
+# CONFIG_FB_3DFX is not set
+# CONFIG_FB_VOODOO1 is not set
+# CONFIG_FB_TRIDENT is not set
+CONFIG_FB_SM501=y
+# CONFIG_FB_VIRTUAL is not set
+
+#
+# Console display driver support
+#
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
+# CONFIG_FONTS is not set
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+
+#
+# Logo configuration
+#
+CONFIG_LOGO=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+# CONFIG_LOGO_LINUX_CLUT224 is not set
+# CONFIG_LOGO_SUPERH_MONO is not set
+# CONFIG_LOGO_SUPERH_VGA16 is not set
+CONFIG_LOGO_SUPERH_CLUT224=y
#
# Sound
@@ -985,6 +1069,12 @@ CONFIG_SOUND_PRIME=m
CONFIG_AC97_BUS=m
#
+# HID Devices
+#
+CONFIG_HID=y
+# CONFIG_HID_DEBUG is not set
+
+#
# USB support
#
CONFIG_USB_ARCH_HAS_HCD=y
@@ -1237,7 +1327,7 @@ CONFIG_LOG_BUF_SHIFT=14
CONFIG_EARLY_SCIF_CONSOLE=y
CONFIG_EARLY_SCIF_CONSOLE_PORT=0xffe80000
CONFIG_EARLY_PRINTK=y
-# CONFIG_KGDB is not set
+# CONFIG_SH_KGDB is not set
#
# Security options
diff --git a/arch/sh/kernel/entry-common.S b/arch/sh/kernel/entry-common.S
index ab4ebb8..b467280 100644
--- a/arch/sh/kernel/entry-common.S
+++ b/arch/sh/kernel/entry-common.S
@@ -224,7 +224,7 @@ work_resched:
syscall_exit_work:
! r0: current_thread_info->flags
! r8: current_thread_info
- tst #_TIF_SYSCALL_TRACE, r0
+ tst #_TIF_SYSCALL_TRACE | _TIF_SINGLESTEP, r0
bt/s work_pending
tst #_TIF_NEED_RESCHED, r0
#ifdef CONFIG_TRACE_IRQFLAGS
diff --git a/arch/sh/kernel/io_generic.c b/arch/sh/kernel/io_generic.c
index 66626c0..771ea42 100644
--- a/arch/sh/kernel/io_generic.c
+++ b/arch/sh/kernel/io_generic.c
@@ -14,7 +14,6 @@
#include <linux/module.h>
#include <linux/io.h>
#include <asm/machvec.h>
-#include <asm/cacheflush.h>
#ifdef CONFIG_CPU_SH3
/* 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)
while (count--)
*buf++ = *port_addr;
- flush_dcache_all();
dummy_read();
}
@@ -171,7 +169,6 @@ void generic_outsw(unsigned long port, const void *src, unsigned long count)
while (count--)
*port_addr = *buf++;
- flush_dcache_all();
dummy_read();
}
diff --git a/arch/sh/kernel/process.c b/arch/sh/kernel/process.c
index 9d6a438..e760736 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,
childregs->regs[15] = usp;
ti->addr_limit = USER_DS;
} else {
- childregs->regs[15] = (unsigned long)task_stack_page(p) +
- THREAD_SIZE;
+ childregs->regs[15] = (unsigned long)childregs;
ti->addr_limit = KERNEL_DS;
}
- if (clone_flags & CLONE_SETTLS)
+ if (clone_flags & CLONE_SETTLS)
childregs->gbr = childregs->regs[0];
childregs->regs[0] = 0; /* Set return value for child */
diff --git a/arch/sh/kernel/ptrace.c b/arch/sh/kernel/ptrace.c
index 04ca13a..855f724 100644
--- a/arch/sh/kernel/ptrace.c
+++ b/arch/sh/kernel/ptrace.c
@@ -8,7 +8,6 @@
* SuperH version: Copyright (C) 1999, 2000 Kaz Kojima & Niibe Yutaka
*
*/
-
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/mm.h>
@@ -20,8 +19,7 @@
#include <linux/slab.h>
#include <linux/security.h>
#include <linux/signal.h>
-
-#include <asm/io.h>
+#include <linux/io.h>
#include <asm/uaccess.h>
#include <asm/pgtable.h>
#include <asm/system.h>
@@ -59,6 +57,23 @@ static inline int put_stack_long(struct task_struct *task, int offset,
return 0;
}
+static void ptrace_disable_singlestep(struct task_struct *child)
+{
+ clear_tsk_thread_flag(child, TIF_SINGLESTEP);
+
+ /*
+ * Ensure the UBC is not programmed at the next context switch.
+ *
+ * Normally this is not needed but there are sequences such as
+ * singlestep, signal delivery, and continue that leave the
+ * ubc_pc non-zero leading to spurious SIGTRAPs.
+ */
+ if (child->thread.ubc_pc != 0) {
+ ubc_usercnt -= 1;
+ child->thread.ubc_pc = 0;
+ }
+}
+
/*
* Called by kernel/ptrace.c when detaching..
*
@@ -66,7 +81,7 @@ static inline int put_stack_long(struct task_struct *task, int offset,
*/
void ptrace_disable(struct task_struct *child)
{
- /* nothing to do.. */
+ ptrace_disable_singlestep(child);
}
long 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)
switch (request) {
/* when I and D space are separate, these will need to be fixed. */
- case PTRACE_PEEKTEXT: /* read word at location addr. */
+ case PTRACE_PEEKTEXT: /* read word at location addr. */
case PTRACE_PEEKDATA: {
unsigned long tmp;
int copied;
@@ -94,7 +109,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
unsigned long tmp;
ret = -EIO;
- if ((addr & 3) || addr < 0 ||
+ if ((addr & 3) || addr < 0 ||
addr > sizeof(struct user) - 3)
break;
@@ -129,7 +144,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
case PTRACE_POKEUSR: /* write the word at location addr in the USER area */
ret = -EIO;
- if ((addr & 3) || addr < 0 ||
+ if ((addr & 3) || addr < 0 ||
addr > sizeof(struct user) - 3)
break;
@@ -156,6 +171,9 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
else
clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
+
+ ptrace_disable_singlestep(child);
+
child->exit_code = data;
wake_up_process(child);
ret = 0;
@@ -163,14 +181,15 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
}
/*
- * make the child exit. Best I can do is send it a sigkill.
- * perhaps it should be put in the status that it wants to
+ * make the child exit. Best I can do is send it a sigkill.
+ * perhaps it should be put in the status that it wants to
* exit.
*/
case PTRACE_KILL: {
ret = 0;
if (child->exit_state == EXIT_ZOMBIE) /* already dead */
break;
+ ptrace_disable_singlestep(child);
child->exit_code = SIGKILL;
wake_up_process(child);
break;
@@ -196,6 +215,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
ubc_usercnt += 1;
child->thread.ubc_pc = pc;
+ set_tsk_thread_flag(child, TIF_SINGLESTEP);
child->exit_code = data;
/* give it a chance to run. */
wake_up_process(child);
@@ -248,14 +268,15 @@ asmlinkage void do_syscall_trace(void)
{
struct task_struct *tsk = current;
- if (!test_thread_flag(TIF_SYSCALL_TRACE))
+ if (!test_thread_flag(TIF_SYSCALL_TRACE) &&
+ !test_thread_flag(TIF_SINGLESTEP))
return;
if (!(tsk->ptrace & PT_PTRACED))
return;
/* the 0x80 provides a way for the tracing parent to distinguish
between a syscall stop and SIGTRAP delivery */
- ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
- ? 0x80 : 0));
+ ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) &&
+ !test_thread_flag(TIF_SINGLESTEP) ? 0x80 : 0));
/*
* 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 32f10a0..9f39ef1 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)
if (test_thread_flag(TIF_RESTORE_SIGMASK))
clear_thread_flag(TIF_RESTORE_SIGMASK);
}
+
+ return;
}
no_signal:
@@ -598,7 +600,7 @@ static void do_signal(struct pt_regs *regs, unsigned int save_r0)
if (regs->regs[0] == -ERESTARTNOHAND ||
regs->regs[0] == -ERESTARTSYS ||
regs->regs[0] == -ERESTARTNOINTR) {
- regs->regs[0] = save_r0;
+ regs->regs[0] = save_r0;
regs->pc -= 2;
} else if (regs->regs[0] == -ERESTART_RESTARTBLOCK) {
regs->pc -= 2;
diff --git a/arch/sh/kernel/vmlinux.lds.S b/arch/sh/kernel/vmlinux.lds.S
index 75de165..78a6c09 100644
--- a/arch/sh/kernel/vmlinux.lds.S
+++ b/arch/sh/kernel/vmlinux.lds.S
@@ -3,6 +3,7 @@
* Written by Niibe Yutaka
*/
#include <asm/thread_info.h>
+#include <asm/cache.h>
#include <asm-generic/vmlinux.lds.h>
#ifdef CONFIG_CPU_LITTLE_ENDIAN
@@ -53,7 +54,7 @@ SECTIONS
. = ALIGN(PAGE_SIZE);
.data.page_aligned : { *(.data.page_aligned) }
- . = ALIGN(32);
+ . = ALIGN(L1_CACHE_BYTES);
__per_cpu_start = .;
.data.percpu : { *(.data.percpu) }
__per_cpu_end = .;
diff --git a/arch/sh/mm/cache-sh4.c b/arch/sh/mm/cache-sh4.c
index e0cd4b7..981b040 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,
/*
* Write back & invalidate the D-cache of the page.
* (To avoid "alias" issues)
- *
- * This uses a lazy write-back on UP, which is explicitly
- * disabled on SMP.
*/
void flush_dcache_page(struct page *page)
{
-#ifndef CONFIG_SMP
- struct address_space *mapping = page_mapping(page);
-
- if (mapping && !mapping_mapped(mapping))
- set_bit(PG_dcache_dirty, &page->flags);
- else
-#endif
- {
+ if (test_bit(PG_mapped, &page->flags)) {
unsigned long phys = PHYSADDR(page_address(page));
unsigned long addr = CACHE_OC_ADDRESS_ARRAY;
int i, n;
diff --git a/arch/sh/mm/cache-sh7705.c b/arch/sh/mm/cache-sh7705.c
index 31f8deb..4896d73 100644
--- a/arch/sh/mm/cache-sh7705.c
+++ b/arch/sh/mm/cache-sh7705.c
@@ -3,11 +3,11 @@
*
* Copyright (C) 1999, 2000 Niibe Yutaka
* Copyright (C) 2004 Alex Song
- * Copyright (C) 2006 Paul Mundt
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
+ *
*/
#include <linux/init.h>
#include <linux/mman.h>
@@ -51,6 +51,7 @@ static inline void cache_wback_all(void)
if ((data & v) == v)
ctrl_outl(data & ~v, addr);
+
}
addrstart += current_cpu_data.dcache.way_incr;
@@ -127,11 +128,7 @@ static void __flush_dcache_page(unsigned long phys)
*/
void flush_dcache_page(struct page *page)
{
- struct address_space *mapping = page_mapping(page);
-
- if (mapping && !mapping_mapped(mapping))
- set_bit(PG_dcache_dirty, &page->flags);
- else
+ if (test_bit(PG_mapped, &page->flags))
__flush_dcache_page(PHYSADDR(page_address(page)));
}
diff --git a/arch/sh/mm/pg-sh4.c b/arch/sh/mm/pg-sh4.c
index 969efec..df69da9 100644
--- a/arch/sh/mm/pg-sh4.c
+++ b/arch/sh/mm/pg-sh4.c
@@ -23,6 +23,7 @@ extern struct mutex p3map_mutex[];
*/
void clear_user_page(void *to, unsigned long address, struct page *page)
{
+ __set_bit(PG_mapped, &page->flags);
if (((address ^ (unsigned long)to) & CACHE_ALIAS) == 0)
clear_page(to);
else {
@@ -58,6 +59,7 @@ void clear_user_page(void *to, unsigned long address, struct page *page)
void copy_user_page(void *to, void *from, unsigned long address,
struct page *page)
{
+ __set_bit(PG_mapped, &page->flags);
if (((address ^ (unsigned long)to) & CACHE_ALIAS) == 0)
copy_page(to, from);
else {
@@ -82,3 +84,23 @@ void copy_user_page(void *to, void *from, unsigned long address,
mutex_unlock(&p3map_mutex[(address & CACHE_ALIAS)>>12]);
}
}
+
+/*
+ * For SH-4, we have our own implementation for ptep_get_and_clear
+ */
+inline pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
+{
+ pte_t pte = *ptep;
+
+ pte_clear(mm, addr, ptep);
+ if (!pte_not_present(pte)) {
+ unsigned long pfn = pte_pfn(pte);
+ if (pfn_valid(pfn)) {
+ struct page *page = pfn_to_page(pfn);
+ struct address_space *mapping = page_mapping(page);
+ if (!mapping || !mapping_writably_mapped(mapping))
+ __clear_bit(PG_mapped, &page->flags);
+ }
+ }
+ return pte;
+}
diff --git a/arch/sh/mm/pg-sh7705.c b/arch/sh/mm/pg-sh7705.c
index 887ab9d..a4b015f 100644
--- a/arch/sh/mm/pg-sh7705.c
+++ b/arch/sh/mm/pg-sh7705.c
@@ -7,7 +7,9 @@
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
+ *
*/
+
#include <linux/init.h>
#include <linux/mman.h>
#include <linux/mm.h>
@@ -74,6 +76,7 @@ void clear_user_page(void *to, unsigned long address, struct page *pg)
{
struct page *page = virt_to_page(to);
+ __set_bit(PG_mapped, &page->flags);
if (((address ^ (unsigned long)to) & CACHE_ALIAS) == 0) {
clear_page(to);
__flush_wback_region(to, PAGE_SIZE);
@@ -92,11 +95,12 @@ void clear_user_page(void *to, unsigned long address, struct page *pg)
* @from: P1 address
* @address: U0 address to be mapped
*/
-void copy_user_page(void *to, void *from, unsigned long address,
- struct page *pg)
+void copy_user_page(void *to, void *from, unsigned long address, struct page *pg)
{
struct page *page = virt_to_page(to);
+
+ __set_bit(PG_mapped, &page->flags);
if (((address ^ (unsigned long)to) & CACHE_ALIAS) == 0) {
copy_page(to, from);
__flush_wback_region(to, PAGE_SIZE);
@@ -108,3 +112,26 @@ void copy_user_page(void *to, void *from, unsigned long address,
__flush_wback_region(to, PAGE_SIZE);
}
}
+
+/*
+ * For SH7705, we have our own implementation for ptep_get_and_clear
+ * Copied from pg-sh4.c
+ */
+inline pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
+{
+ pte_t pte = *ptep;
+
+ pte_clear(mm, addr, ptep);
+ if (!pte_not_present(pte)) {
+ unsigned long pfn = pte_pfn(pte);
+ if (pfn_valid(pfn)) {
+ struct page *page = pfn_to_page(pfn);
+ struct address_space *mapping = page_mapping(page);
+ if (!mapping || !mapping_writably_mapped(mapping))
+ __clear_bit(PG_mapped, &page->flags);
+ }
+ }
+
+ return pte;
+}
+
diff --git a/arch/sh/mm/tlb-flush.c b/arch/sh/mm/tlb-flush.c
index d2f7b4a..6f45c1f 100644
--- a/arch/sh/mm/tlb-flush.c
+++ b/arch/sh/mm/tlb-flush.c
@@ -2,17 +2,15 @@
* TLB flushing operations for SH with an MMU.
*
* Copyright (C) 1999 Niibe Yutaka
- * Copyright (C) 2003 - 2006 Paul Mundt
+ * Copyright (C) 2003 Paul Mundt
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*/
#include <linux/mm.h>
-#include <linux/io.h>
#include <asm/mmu_context.h>
#include <asm/tlbflush.h>
-#include <asm/cacheflush.h>
void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
{
@@ -140,54 +138,3 @@ void local_flush_tlb_all(void)
ctrl_barrier();
local_irq_restore(flags);
}
-
-void update_mmu_cache(struct vm_area_struct *vma,
- unsigned long address, pte_t pte)
-{
- unsigned long flags;
- unsigned long pteval;
- unsigned long vpn;
- struct page *page;
- unsigned long pfn = pte_pfn(pte);
- struct address_space *mapping;
-
- if (!pfn_valid(pfn))
- return;
-
- page = pfn_to_page(pfn);
- mapping = page_mapping(page);
- if (mapping) {
- unsigned long phys = pte_val(pte) & PTE_PHYS_MASK;
- int dirty = test_and_clear_bit(PG_dcache_dirty, &page->flags);
-
- if (dirty)
- __flush_wback_region((void *)P1SEGADDR(phys),
- PAGE_SIZE);
- }
-
- local_irq_save(flags);
-
- /* Set PTEH register */
- vpn = (address & MMU_VPN_MASK) | get_asid();
- ctrl_outl(vpn, MMU_PTEH);
-
- pteval = pte_val(pte);
-
-#ifdef CONFIG_CPU_HAS_PTEA
- /* Set PTEA register */
- /* TODO: make this look less hacky */
- ctrl_outl(((pteval >> 28) & 0xe) | (pteval & 0x1), MMU_PTEA);
-#endif
-
- /* Set PTEL register */
- pteval &= _PAGE_FLAGS_HARDWARE_MASK; /* drop software flags */
-#if defined(CONFIG_SH_WRITETHROUGH) && defined(CONFIG_CPU_SH4)
- pteval |= _PAGE_WT;
-#endif
- /* conveniently, we want all the software flags to be 0 anyway */
- ctrl_outl(pteval, MMU_PTEL);
-
- /* Load the TLB */
- asm volatile("ldtlb": /* no output */ : /* no input */ : "memory");
- local_irq_restore(flags);
-}
diff --git a/arch/sh/mm/tlb-sh3.c b/arch/sh/mm/tlb-sh3.c
index e5e76eb..7fbfd5a 100644
--- a/arch/sh/mm/tlb-sh3.c
+++ b/arch/sh/mm/tlb-sh3.c
@@ -8,9 +8,69 @@
*
* Released under the terms of the GNU GPL v2.0.
*/
-#include <linux/io.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/ptrace.h>
+#include <linux/mman.h>
+#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/interrupt.h>
+
#include <asm/system.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <asm/pgalloc.h>
#include <asm/mmu_context.h>
+#include <asm/cacheflush.h>
+
+void update_mmu_cache(struct vm_area_struct * vma,
+ unsigned long address, pte_t pte)
+{
+ unsigned long flags;
+ unsigned long pteval;
+ unsigned long vpn;
+
+ /* Ptrace may call this routine. */
+ if (vma && current->active_mm != vma->vm_mm)
+ return;
+
+#if defined(CONFIG_SH7705_CACHE_32KB)
+ {
+ struct page *page = pte_page(pte);
+ unsigned long pfn = pte_pfn(pte);
+
+ if (pfn_valid(pfn) && !test_bit(PG_mapped, &page->flags)) {
+ unsigned long phys = pte_val(pte) & PTE_PHYS_MASK;
+
+ __flush_wback_region((void *)P1SEGADDR(phys),
+ PAGE_SIZE);
+ __set_bit(PG_mapped, &page->flags);
+ }
+ }
+#endif
+
+ local_irq_save(flags);
+
+ /* Set PTEH register */
+ vpn = (address & MMU_VPN_MASK) | get_asid();
+ ctrl_outl(vpn, MMU_PTEH);
+
+ pteval = pte_val(pte);
+
+ /* Set PTEL register */
+ pteval &= _PAGE_FLAGS_HARDWARE_MASK; /* drop software flags */
+ /* conveniently, we want all the software flags to be 0 anyway */
+ ctrl_outl(pteval, MMU_PTEL);
+
+ /* Load the TLB */
+ asm volatile("ldtlb": /* no output */ : /* no input */ : "memory");
+ local_irq_restore(flags);
+}
void local_flush_tlb_one(unsigned long asid, unsigned long page)
{
@@ -34,3 +94,4 @@ void local_flush_tlb_one(unsigned long asid, unsigned long page)
for (i = 0; i < ways; i++)
ctrl_outl(data, addr + (i << 8));
}
+
diff --git a/arch/sh/mm/tlb-sh4.c b/arch/sh/mm/tlb-sh4.c
index 221e709..f74cf66 100644
--- a/arch/sh/mm/tlb-sh4.c
+++ b/arch/sh/mm/tlb-sh4.c
@@ -8,9 +8,74 @@
*
* Released under the terms of the GNU GPL v2.0.
*/
-#include <linux/io.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/ptrace.h>
+#include <linux/mman.h>
+#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/interrupt.h>
+
#include <asm/system.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <asm/pgalloc.h>
#include <asm/mmu_context.h>
+#include <asm/cacheflush.h>
+
+void update_mmu_cache(struct vm_area_struct * vma,
+ unsigned long address, pte_t pte)
+{
+ unsigned long flags;
+ unsigned long pteval;
+ unsigned long vpn;
+ struct page *page;
+ unsigned long pfn;
+
+ /* Ptrace may call this routine. */
+ if (vma && current->active_mm != vma->vm_mm)
+ return;
+
+ pfn = pte_pfn(pte);
+ if (pfn_valid(pfn)) {
+ page = pfn_to_page(pfn);
+ if (!test_bit(PG_mapped, &page->flags)) {
+ unsigned long phys = pte_val(pte) & PTE_PHYS_MASK;
+ __flush_wback_region((void *)P1SEGADDR(phys), PAGE_SIZE);
+ __set_bit(PG_mapped, &page->flags);
+ }
+ }
+
+ local_irq_save(flags);
+
+ /* Set PTEH register */
+ vpn = (address & MMU_VPN_MASK) | get_asid();
+ ctrl_outl(vpn, MMU_PTEH);
+
+ pteval = pte_val(pte);
+
+ /* Set PTEA register */
+ if (cpu_data->flags & CPU_HAS_PTEA)
+ /* TODO: make this look less hacky */
+ ctrl_outl(((pteval >> 28) & 0xe) | (pteval & 0x1), MMU_PTEA);
+
+ /* Set PTEL register */
+ pteval &= _PAGE_FLAGS_HARDWARE_MASK; /* drop software flags */
+#ifdef CONFIG_SH_WRITETHROUGH
+ pteval |= _PAGE_WT;
+#endif
+ /* conveniently, we want all the software flags to be 0 anyway */
+ ctrl_outl(pteval, MMU_PTEL);
+
+ /* Load the TLB */
+ asm volatile("ldtlb": /* no output */ : /* no input */ : "memory");
+ local_irq_restore(flags);
+}
void local_flush_tlb_one(unsigned long asid, unsigned long page)
{
@@ -28,3 +93,4 @@ void local_flush_tlb_one(unsigned long asid, unsigned long page)
ctrl_outl(data, addr);
back_to_P1();
}
+
diff --git a/arch/x86_64/kernel/smpboot.c b/arch/x86_64/kernel/smpboot.c
index 3544372..cd4643a 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)
*/
int __cpuinit __cpu_up(unsigned int cpu)
{
- int err;
int apicid = cpu_present_to_apicid(cpu);
+ unsigned long flags;
+ int err;
WARN_ON(irqs_disabled());
@@ -958,7 +959,9 @@ int __cpuinit __cpu_up(unsigned int cpu)
/*
* Make sure and check TSC sync:
*/
+ local_irq_save(flags);
check_tsc_sync_source(cpu);
+ local_irq_restore(flags);
while (!cpu_isset(cpu, cpu_online_map))
cpu_relax();