aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorPaul Mundt <lethal@linux-sh.org>2009-08-19 09:12:00 +0900
committerPaul Mundt <lethal@linux-sh.org>2009-08-19 09:12:00 +0900
commitee8365f23355cdb66e7a6c5c9364e8d3ba4de32f (patch)
treee77b5ff0d17eb583312fe710de569081a3ec8f8d /arch
parentsh: Merge the _32/_64 variants of arch/sh/mm/Makefile. (diff)
parentsh: Prevent heartbeat from scribbling over non-LED bits. (diff)
downloadlinux-dev-ee8365f23355cdb66e7a6c5c9364e8d3ba4de32f.tar.xz
linux-dev-ee8365f23355cdb66e7a6c5c9364e8d3ba4de32f.zip
Merge branch 'master' into sh/cachetlb
Conflicts: arch/sh/kernel/Makefile_64
Diffstat (limited to 'arch')
-rw-r--r--arch/sh/boards/mach-se/7724/setup.c9
-rw-r--r--arch/sh/drivers/heartbeat.c10
-rw-r--r--arch/sh/include/asm/dwarf.h4
-rw-r--r--arch/sh/include/asm/heartbeat.h1
-rw-r--r--arch/sh/include/mach-kfr2r09/mach/partner-jet-setup.txt1
-rw-r--r--arch/sh/kernel/Makefile43
-rw-r--r--arch/sh/kernel/Makefile_3240
-rw-r--r--arch/sh/kernel/Makefile_6421
-rw-r--r--arch/sh/kernel/cpu/init.c34
-rw-r--r--arch/sh/kernel/cpu/sh2/entry.S3
-rw-r--r--arch/sh/kernel/cpu/sh2a/entry.S3
-rw-r--r--arch/sh/kernel/cpu/sh3/entry.S8
-rw-r--r--arch/sh/kernel/cpu/sh4a/clock-sh7724.c2
-rw-r--r--arch/sh/kernel/cpu/shmobile/cpuidle.c11
-rw-r--r--arch/sh/kernel/cpu/shmobile/pm.c16
-rw-r--r--arch/sh/kernel/cpu/shmobile/sleep.S187
-rw-r--r--arch/sh/kernel/dwarf.c54
-rw-r--r--arch/sh/kernel/entry-common.S27
-rw-r--r--arch/x86/Kconfig2
-rw-r--r--arch/x86/kernel/cpu/amd.c7
-rw-r--r--arch/x86/kernel/cpu/common.c48
-rw-r--r--arch/x86/kernel/cpu/mcheck/therm_throt.c18
-rw-r--r--arch/x86/kernel/cpu/perf_counter.c40
-rw-r--r--arch/x86/kernel/reboot.c12
24 files changed, 390 insertions, 211 deletions
diff --git a/arch/sh/boards/mach-se/7724/setup.c b/arch/sh/boards/mach-se/7724/setup.c
index 36a4ca3a9000..9162081504ef 100644
--- a/arch/sh/boards/mach-se/7724/setup.c
+++ b/arch/sh/boards/mach-se/7724/setup.c
@@ -246,7 +246,7 @@ static struct platform_device ceu1_device = {
},
};
-/* KEYSC */
+/* KEYSC in SoC (Needs SW33-2 set to ON) */
static struct sh_keysc_info keysc_info = {
.mode = SH_KEYSC_MODE_1,
.scan_timing = 10,
@@ -263,12 +263,13 @@ static struct sh_keysc_info keysc_info = {
static struct resource keysc_resources[] = {
[0] = {
- .start = 0x1a204000,
- .end = 0x1a20400f,
+ .name = "KEYSC",
+ .start = 0x044b0000,
+ .end = 0x044b000f,
.flags = IORESOURCE_MEM,
},
[1] = {
- .start = IRQ0_KEY,
+ .start = 79,
.flags = IORESOURCE_IRQ,
},
};
diff --git a/arch/sh/drivers/heartbeat.c b/arch/sh/drivers/heartbeat.c
index 938817e34e2b..a9339a6174fc 100644
--- a/arch/sh/drivers/heartbeat.c
+++ b/arch/sh/drivers/heartbeat.c
@@ -40,14 +40,19 @@ static inline void heartbeat_toggle_bit(struct heartbeat_data *hd,
if (inverted)
new = ~new;
+ new &= hd->mask;
+
switch (hd->regsize) {
case 32:
+ new |= ioread32(hd->base) & ~hd->mask;
iowrite32(new, hd->base);
break;
case 16:
+ new |= ioread16(hd->base) & ~hd->mask;
iowrite16(new, hd->base);
break;
default:
+ new |= ioread8(hd->base) & ~hd->mask;
iowrite8(new, hd->base);
break;
}
@@ -72,6 +77,7 @@ static int heartbeat_drv_probe(struct platform_device *pdev)
{
struct resource *res;
struct heartbeat_data *hd;
+ int i;
if (unlikely(pdev->num_resources != 1)) {
dev_err(&pdev->dev, "invalid number of resources\n");
@@ -107,6 +113,10 @@ static int heartbeat_drv_probe(struct platform_device *pdev)
hd->nr_bits = ARRAY_SIZE(default_bit_pos);
}
+ hd->mask = 0;
+ for (i = 0; i < hd->nr_bits; i++)
+ hd->mask |= (1 << hd->bit_pos[i]);
+
if (!hd->regsize)
hd->regsize = 8; /* default access size */
diff --git a/arch/sh/include/asm/dwarf.h b/arch/sh/include/asm/dwarf.h
index 60b180728d8d..d3d3837c5e1b 100644
--- a/arch/sh/include/asm/dwarf.h
+++ b/arch/sh/include/asm/dwarf.h
@@ -340,6 +340,10 @@ struct dwarf_stack {
#define DW_CFA_lo_user 0x1c
#define DW_CFA_hi_user 0x3f
+/* GNU extension opcodes */
+#define DW_CFA_GNU_args_size 0x2e
+#define DW_CFA_GNU_negative_offset_extended 0x2f
+
/*
* Some call frame instructions encode their operands in the opcode. We
* need some helper functions to extract both the opcode and operands
diff --git a/arch/sh/include/asm/heartbeat.h b/arch/sh/include/asm/heartbeat.h
index 724a43ed245e..caaafe5a3ef1 100644
--- a/arch/sh/include/asm/heartbeat.h
+++ b/arch/sh/include/asm/heartbeat.h
@@ -11,6 +11,7 @@ struct heartbeat_data {
unsigned int nr_bits;
struct timer_list timer;
unsigned int regsize;
+ unsigned int mask;
unsigned long flags;
};
diff --git a/arch/sh/include/mach-kfr2r09/mach/partner-jet-setup.txt b/arch/sh/include/mach-kfr2r09/mach/partner-jet-setup.txt
index 9c85088728a7..25801d495c5f 100644
--- a/arch/sh/include/mach-kfr2r09/mach/partner-jet-setup.txt
+++ b/arch/sh/include/mach-kfr2r09/mach/partner-jet-setup.txt
@@ -24,6 +24,7 @@ LIST "setup clocks"
ED 0xa4150004, 0x00000050
ED 0xa4150000, 0x91053508
WAIT 1
+ED 0xa4150050, 0x00000340
ED 0xa4150024, 0x00005000
LIST "setup pins"
diff --git a/arch/sh/kernel/Makefile b/arch/sh/kernel/Makefile
index 349d833deab5..f37cf02ad9be 100644
--- a/arch/sh/kernel/Makefile
+++ b/arch/sh/kernel/Makefile
@@ -1,5 +1,40 @@
-ifeq ($(CONFIG_SUPERH32),y)
-include ${srctree}/arch/sh/kernel/Makefile_32
-else
-include ${srctree}/arch/sh/kernel/Makefile_64
+#
+# Makefile for the Linux/SuperH kernel.
+#
+
+extra-y := head_$(BITS).o init_task.o vmlinux.lds
+
+ifdef CONFIG_FUNCTION_TRACER
+# Do not profile debug and lowlevel utilities
+CFLAGS_REMOVE_ftrace.o = -pg
endif
+
+obj-y := debugtraps.o dumpstack.o idle.o io.o io_generic.o irq.o \
+ machvec.o process_$(BITS).o ptrace_$(BITS).o setup.o \
+ signal_$(BITS).o sys_sh.o sys_sh$(BITS).o syscalls_$(BITS).o \
+ time.o topology.o traps.o traps_$(BITS).o unwinder.o
+
+obj-y += cpu/
+obj-$(CONFIG_VSYSCALL) += vsyscall/
+obj-$(CONFIG_SMP) += smp.o
+obj-$(CONFIG_SH_STANDARD_BIOS) += sh_bios.o
+obj-$(CONFIG_KGDB) += kgdb.o
+obj-$(CONFIG_SH_CPU_FREQ) += cpufreq.o
+obj-$(CONFIG_MODULES) += sh_ksyms_$(BITS).o module.o
+obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
+obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o
+obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
+obj-$(CONFIG_STACKTRACE) += stacktrace.o
+obj-$(CONFIG_IO_TRAPPED) += io_trapped.o
+obj-$(CONFIG_KPROBES) += kprobes.o
+obj-$(CONFIG_GENERIC_GPIO) += gpio.o
+obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o
+obj-$(CONFIG_FTRACE_SYSCALLS) += ftrace.o
+obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o
+obj-$(CONFIG_DUMP_CODE) += disassemble.o
+obj-$(CONFIG_HIBERNATION) += swsusp.o
+obj-$(CONFIG_DWARF_UNWINDER) += dwarf.o
+
+obj-$(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST) += localtimer.o
+
+EXTRA_CFLAGS += -Werror
diff --git a/arch/sh/kernel/Makefile_32 b/arch/sh/kernel/Makefile_32
deleted file mode 100644
index f2245ebf0b31..000000000000
--- a/arch/sh/kernel/Makefile_32
+++ /dev/null
@@ -1,40 +0,0 @@
-#
-# Makefile for the Linux/SuperH kernel.
-#
-
-extra-y := head_32.o init_task.o vmlinux.lds
-
-ifdef CONFIG_FUNCTION_TRACER
-# Do not profile debug and lowlevel utilities
-CFLAGS_REMOVE_ftrace.o = -pg
-endif
-
-obj-y := debugtraps.o dumpstack.o idle.o io.o io_generic.o irq.o \
- machvec.o process_32.o ptrace_32.o setup.o signal_32.o \
- sys_sh.o sys_sh32.o syscalls_32.o time.o topology.o \
- traps.o traps_32.o unwinder.o
-
-obj-y += cpu/
-obj-$(CONFIG_VSYSCALL) += vsyscall/
-obj-$(CONFIG_SMP) += smp.o
-obj-$(CONFIG_SH_STANDARD_BIOS) += sh_bios.o
-obj-$(CONFIG_KGDB) += kgdb.o
-obj-$(CONFIG_SH_CPU_FREQ) += cpufreq.o
-obj-$(CONFIG_MODULES) += sh_ksyms_32.o module.o
-obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
-obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o
-obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
-obj-$(CONFIG_STACKTRACE) += stacktrace.o
-obj-$(CONFIG_IO_TRAPPED) += io_trapped.o
-obj-$(CONFIG_KPROBES) += kprobes.o
-obj-$(CONFIG_GENERIC_GPIO) += gpio.o
-obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o
-obj-$(CONFIG_FTRACE_SYSCALLS) += ftrace.o
-obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o
-obj-$(CONFIG_DUMP_CODE) += disassemble.o
-obj-$(CONFIG_HIBERNATION) += swsusp.o
-obj-$(CONFIG_DWARF_UNWINDER) += dwarf.o
-
-obj-$(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST) += localtimer.o
-
-EXTRA_CFLAGS += -Werror
diff --git a/arch/sh/kernel/Makefile_64 b/arch/sh/kernel/Makefile_64
deleted file mode 100644
index cdfec1e499a0..000000000000
--- a/arch/sh/kernel/Makefile_64
+++ /dev/null
@@ -1,21 +0,0 @@
-extra-y := head_64.o init_task.o vmlinux.lds
-
-obj-y := debugtraps.o dumpstack.o idle.o io.o io_generic.o irq.o \
- machvec.o process_64.o ptrace_64.o setup.o signal_64.o \
- sys_sh.o sys_sh64.o syscalls_64.o time.o topology.o \
- traps.o traps_64.o unwinder.o
-
-obj-y += cpu/
-obj-$(CONFIG_SMP) += smp.o
-obj-$(CONFIG_SH_CPU_FREQ) += cpufreq.o
-obj-$(CONFIG_MODULES) += sh_ksyms_64.o module.o
-obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
-obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
-obj-$(CONFIG_STACKTRACE) += stacktrace.o
-obj-$(CONFIG_IO_TRAPPED) += io_trapped.o
-obj-$(CONFIG_GENERIC_GPIO) += gpio.o
-obj-$(CONFIG_DWARF_UNWINDER) += dwarf.o
-
-obj-$(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST) += localtimer.o
-
-EXTRA_CFLAGS += -Werror
diff --git a/arch/sh/kernel/cpu/init.c b/arch/sh/kernel/cpu/init.c
index c832fa4cf8ed..e932ebef4738 100644
--- a/arch/sh/kernel/cpu/init.c
+++ b/arch/sh/kernel/cpu/init.c
@@ -3,7 +3,7 @@
*
* CPU init code
*
- * Copyright (C) 2002 - 2007 Paul Mundt
+ * Copyright (C) 2002 - 2009 Paul Mundt
* Copyright (C) 2003 Richard Curnow
*
* This file is subject to the terms and conditions of the GNU General Public
@@ -62,6 +62,37 @@ static void __init speculative_execution_init(void)
#define speculative_execution_init() do { } while (0)
#endif
+#ifdef CONFIG_CPU_SH4A
+#define EXPMASK 0xff2f0004
+#define EXPMASK_RTEDS (1 << 0)
+#define EXPMASK_BRDSSLP (1 << 1)
+#define EXPMASK_MMCAW (1 << 4)
+
+static void __init expmask_init(void)
+{
+ unsigned long expmask = __raw_readl(EXPMASK);
+
+ /*
+ * Future proofing.
+ *
+ * Disable support for slottable sleep instruction
+ * and non-nop instructions in the rte delay slot.
+ */
+ expmask &= ~(EXPMASK_RTEDS | EXPMASK_BRDSSLP);
+
+ /*
+ * Enable associative writes to the memory-mapped cache array
+ * until the cache flush ops have been rewritten.
+ */
+ expmask |= EXPMASK_MMCAW;
+
+ __raw_writel(expmask, EXPMASK);
+ ctrl_barrier();
+}
+#else
+#define expmask_init() do { } while (0)
+#endif
+
/* 2nd-level cache init */
void __uses_jump_to_uncached __attribute__ ((weak)) l2_cache_init(void)
{
@@ -319,4 +350,5 @@ asmlinkage void __init sh_cpu_init(void)
#endif
speculative_execution_init();
+ expmask_init();
}
diff --git a/arch/sh/kernel/cpu/sh2/entry.S b/arch/sh/kernel/cpu/sh2/entry.S
index becc54c45692..c8a4331d9b8d 100644
--- a/arch/sh/kernel/cpu/sh2/entry.S
+++ b/arch/sh/kernel/cpu/sh2/entry.S
@@ -227,8 +227,9 @@ ENTRY(sh_bios_handler)
mov.l @r15+, r14
add #8,r15
lds.l @r15+, pr
+ mov.l @r15+,r15
rte
- mov.l @r15+,r15
+ nop
.align 2
1: .long gdb_vbr_vector
#endif /* CONFIG_SH_STANDARD_BIOS */
diff --git a/arch/sh/kernel/cpu/sh2a/entry.S b/arch/sh/kernel/cpu/sh2a/entry.S
index ab3903eeda5c..222742ddc0d6 100644
--- a/arch/sh/kernel/cpu/sh2a/entry.S
+++ b/arch/sh/kernel/cpu/sh2a/entry.S
@@ -176,8 +176,9 @@ ENTRY(sh_bios_handler)
movml.l @r15+,r14
add #8,r15
lds.l @r15+, pr
+ mov.l @r15+,r15
rte
- mov.l @r15+,r15
+ nop
.align 2
1: .long gdb_vbr_vector
#endif /* CONFIG_SH_STANDARD_BIOS */
diff --git a/arch/sh/kernel/cpu/sh3/entry.S b/arch/sh/kernel/cpu/sh3/entry.S
index 854921c6f45b..f94f25e666cc 100644
--- a/arch/sh/kernel/cpu/sh3/entry.S
+++ b/arch/sh/kernel/cpu/sh3/entry.S
@@ -516,6 +516,14 @@ ENTRY(handle_interrupt)
bsr save_regs ! needs original pr value in k3
mov #-1, k2 ! default vector kept in k2
+ stc sr, r0 ! get status register
+ shlr2 r0
+ and #0x3c, r0
+ cmp/eq #0x3c, r0
+ bf 9f
+ TRACE_IRQS_OFF
+9:
+
! Setup return address and jump to do_IRQ
mov.l 4f, r9 ! fetch return address
lds r9, pr ! put return address in pr
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7724.c b/arch/sh/kernel/cpu/sh4a/clock-sh7724.c
index 34611d97378e..627588dfddf0 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-sh7724.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7724.c
@@ -127,7 +127,7 @@ struct clk *main_clks[] = {
&div3_clk,
};
-static int divisors[] = { 2, 0, 4, 6, 8, 12, 16, 0, 24, 32, 36, 48, 0, 72 };
+static int divisors[] = { 2, 3, 4, 6, 8, 12, 16, 0, 24, 32, 36, 48, 0, 72 };
static struct clk_div_mult_table div4_table = {
.divisors = divisors,
diff --git a/arch/sh/kernel/cpu/shmobile/cpuidle.c b/arch/sh/kernel/cpu/shmobile/cpuidle.c
index 4afdd975cc66..1c504bd972c3 100644
--- a/arch/sh/kernel/cpu/shmobile/cpuidle.c
+++ b/arch/sh/kernel/cpu/shmobile/cpuidle.c
@@ -21,6 +21,7 @@
static unsigned long cpuidle_mode[] = {
SUSP_SH_SLEEP, /* regular sleep mode */
SUSP_SH_SLEEP | SUSP_SH_SF, /* sleep mode + self refresh */
+ SUSP_SH_STANDBY | SUSP_SH_SF, /* software standby mode + self refresh */
};
static int cpuidle_sleep_enter(struct cpuidle_device *dev,
@@ -96,6 +97,16 @@ void sh_mobile_setup_cpuidle(void)
state->flags |= CPUIDLE_FLAG_TIME_VALID;
state->enter = cpuidle_sleep_enter;
+ state = &dev->states[i++];
+ snprintf(state->name, CPUIDLE_NAME_LEN, "C2");
+ strncpy(state->desc, "SuperH Mobile Standby Mode [SF]", CPUIDLE_DESC_LEN);
+ state->exit_latency = 2300;
+ state->target_residency = 1 * 2;
+ state->power_usage = 1;
+ state->flags = 0;
+ state->flags |= CPUIDLE_FLAG_TIME_VALID;
+ state->enter = cpuidle_sleep_enter;
+
dev->state_count = i;
cpuidle_register_device(dev);
diff --git a/arch/sh/kernel/cpu/shmobile/pm.c b/arch/sh/kernel/cpu/shmobile/pm.c
index de078d24ce56..ee3c2aaf66fb 100644
--- a/arch/sh/kernel/cpu/shmobile/pm.c
+++ b/arch/sh/kernel/cpu/shmobile/pm.c
@@ -41,23 +41,11 @@ extern const unsigned int sh_mobile_standby_size;
void sh_mobile_call_standby(unsigned long mode)
{
- extern void *vbr_base;
void *onchip_mem = (void *)ILRAM_BASE;
- void (*standby_onchip_mem)(unsigned long) = onchip_mem;
-
- /* Note: Wake up from sleep may generate exceptions!
- * Setup VBR to point to on-chip ram if self-refresh is
- * going to be used.
- */
- if (mode & SUSP_SH_SF)
- asm volatile("ldc %0, vbr" : : "r" (onchip_mem) : "memory");
+ void (*standby_onchip_mem)(unsigned long, unsigned long) = onchip_mem;
/* Let assembly snippet in on-chip memory handle the rest */
- standby_onchip_mem(mode);
-
- /* Put VBR back in System RAM again */
- if (mode & SUSP_SH_SF)
- asm volatile("ldc %0, vbr" : : "r" (&vbr_base) : "memory");
+ standby_onchip_mem(mode, ILRAM_BASE);
}
static int sh_pm_enter(suspend_state_t state)
diff --git a/arch/sh/kernel/cpu/shmobile/sleep.S b/arch/sh/kernel/cpu/shmobile/sleep.S
index 5d888ef53d82..a439e6c7824f 100644
--- a/arch/sh/kernel/cpu/shmobile/sleep.S
+++ b/arch/sh/kernel/cpu/shmobile/sleep.S
@@ -16,18 +16,73 @@
#include <asm/asm-offsets.h>
#include <asm/suspend.h>
+/*
+ * Kernel mode register usage, see entry.S:
+ * k0 scratch
+ * k1 scratch
+ * k4 scratch
+ */
+#define k0 r0
+#define k1 r1
+#define k4 r4
+
/* manage self-refresh and enter standby mode.
* this code will be copied to on-chip memory and executed from there.
*/
.balign 4096,0,4096
ENTRY(sh_mobile_standby)
+
+ /* save original vbr */
+ stc vbr, r1
+ mova saved_vbr, r0
+ mov.l r1, @r0
+
+ /* point vbr to our on-chip memory page */
+ ldc r5, vbr
+
+ /* save return address */
+ mova saved_spc, r0
+ sts pr, r5
+ mov.l r5, @r0
+
+ /* save sr */
+ mova saved_sr, r0
+ stc sr, r5
+ mov.l r5, @r0
+
+ /* save mode flags */
+ mova saved_mode, r0
+ mov.l r4, @r0
+
+ /* put mode flags in r0 */
mov r4, r0
tst #SUSP_SH_SF, r0
bt skip_set_sf
+#ifdef CONFIG_CPU_SUBTYPE_SH7724
+ /* DBSC: put memory in self-refresh mode */
+ mov.l dben_reg, r4
+ mov.l dben_data0, r1
+ mov.l r1, @r4
- /* SDRAM: disable power down and put in self-refresh mode */
+ mov.l dbrfpdn0_reg, r4
+ mov.l dbrfpdn0_data0, r1
+ mov.l r1, @r4
+
+ mov.l dbcmdcnt_reg, r4
+ mov.l dbcmdcnt_data0, r1
+ mov.l r1, @r4
+
+ mov.l dbcmdcnt_reg, r4
+ mov.l dbcmdcnt_data1, r1
+ mov.l r1, @r4
+
+ mov.l dbrfpdn0_reg, r4
+ mov.l dbrfpdn0_data1, r1
+ mov.l r1, @r4
+#else
+ /* SBSC: disable power down and put in self-refresh mode */
mov.l 1f, r4
mov.l 2f, r1
mov.l @r4, r2
@@ -35,16 +90,9 @@ ENTRY(sh_mobile_standby)
mov.l 3f, r3
and r3, r2
mov.l r2, @r4
+#endif
skip_set_sf:
- tst #SUSP_SH_SLEEP, r0
- bt test_standby
-
- /* set mode to "sleep mode" */
- bra do_sleep
- mov #0x00, r1
-
-test_standby:
tst #SUSP_SH_STANDBY, r0
bt test_rstandby
@@ -62,62 +110,135 @@ test_rstandby:
test_ustandby:
tst #SUSP_SH_USTANDBY, r0
- bt done_sleep
+ bt force_sleep
/* set mode to "u-standby mode" */
- mov #0x10, r1
+ bra do_sleep
+ mov #0x10, r1
+
+force_sleep:
- /* fall-through */
+ /* set mode to "sleep mode" */
+ mov #0x00, r1
do_sleep:
/* setup and enter selected standby mode */
mov.l 5f, r4
mov.l r1, @r4
+again:
sleep
+ bra again
+ nop
+
+restore_jump_vbr:
+ /* setup spc with return address to c code */
+ mov.l saved_spc, k0
+ ldc k0, spc
+
+ /* restore vbr */
+ mov.l saved_vbr, k0
+ ldc k0, vbr
+
+ /* setup ssr with saved sr */
+ mov.l saved_sr, k0
+ ldc k0, ssr
+
+ /* get mode flags */
+ mov.l saved_mode, k0
done_sleep:
/* reset standby mode to sleep mode */
- mov.l 5f, r4
- mov #0x00, r1
- mov.l r1, @r4
+ mov.l 5f, k4
+ mov #0x00, k1
+ mov.l k1, @k4
- tst #SUSP_SH_SF, r0
+ tst #SUSP_SH_SF, k0
bt skip_restore_sf
- /* SDRAM: set auto-refresh mode */
- mov.l 1f, r4
- mov.l @r4, r2
- mov.l 4f, r3
- and r3, r2
- mov.l r2, @r4
- mov.l 6f, r4
- mov.l 7f, r1
- mov.l 8f, r2
- mov.l @r4, r3
- mov #-1, r4
- add r4, r3
- or r2, r3
- mov.l r3, @r1
+#ifdef CONFIG_CPU_SUBTYPE_SH7724
+ /* DBSC: put memory in auto-refresh mode */
+ mov.l dbrfpdn0_reg, k4
+ mov.l dbrfpdn0_data0, k1
+ mov.l k1, @k4
+
+ nop /* sleep 140 ns */
+ nop
+ nop
+ nop
+
+ mov.l dbcmdcnt_reg, k4
+ mov.l dbcmdcnt_data0, k1
+ mov.l k1, @k4
+
+ mov.l dbcmdcnt_reg, k4
+ mov.l dbcmdcnt_data1, k1
+ mov.l k1, @k4
+
+ mov.l dben_reg, k4
+ mov.l dben_data1, k1
+ mov.l k1, @k4
+
+ mov.l dbrfpdn0_reg, k4
+ mov.l dbrfpdn0_data2, k1
+ mov.l k1, @k4
+#else
+ /* SBSC: set auto-refresh mode */
+ mov.l 1f, k4
+ mov.l @k4, k0
+ mov.l 4f, k1
+ and k1, k0
+ mov.l k0, @k4
+ mov.l 6f, k4
+ mov.l 8f, k0
+ mov.l @k4, k1
+ mov #-1, k4
+ add k4, k1
+ or k1, k0
+ mov.l 7f, k1
+ mov.l k0, @k1
+#endif
skip_restore_sf:
- rts
+ /* jump to vbr vector */
+ mov.l saved_vbr, k0
+ mov.l offset_vbr, k4
+ add k4, k0
+ jmp @k0
nop
.balign 4
+saved_mode: .long 0
+saved_spc: .long 0
+saved_sr: .long 0
+saved_vbr: .long 0
+offset_vbr: .long 0x600
+#ifdef CONFIG_CPU_SUBTYPE_SH7724
+dben_reg: .long 0xfd000010 /* DBEN */
+dben_data0: .long 0
+dben_data1: .long 1
+dbrfpdn0_reg: .long 0xfd000040 /* DBRFPDN0 */
+dbrfpdn0_data0: .long 0
+dbrfpdn0_data1: .long 1
+dbrfpdn0_data2: .long 0x00010000
+dbcmdcnt_reg: .long 0xfd000014 /* DBCMDCNT */
+dbcmdcnt_data0: .long 2
+dbcmdcnt_data1: .long 4
+#else
1: .long 0xfe400008 /* SDCR0 */
2: .long 0x00000400
3: .long 0xffff7fff
4: .long 0xfffffbff
+#endif
5: .long 0xa4150020 /* STBCR */
6: .long 0xfe40001c /* RTCOR */
7: .long 0xfe400018 /* RTCNT */
8: .long 0xa55a0000
+
/* interrupt vector @ 0x600 */
.balign 0x400,0,0x400
.long 0xdeadbeef
.balign 0x200,0,0x200
- /* sh7722 will end up here in sleep mode */
- rte
+ bra restore_jump_vbr
nop
sh_mobile_standby_end:
diff --git a/arch/sh/kernel/dwarf.c b/arch/sh/kernel/dwarf.c
index db021361b161..5fd6e604816d 100644
--- a/arch/sh/kernel/dwarf.c
+++ b/arch/sh/kernel/dwarf.c
@@ -330,7 +330,6 @@ struct dwarf_fde *dwarf_lookup_fde(unsigned long pc)
* @fde: the FDE for this function
* @frame: the instructions calculate the CFA for this frame
* @pc: the program counter of the address we're interested in
- * @define_ra: keep executing insns until the return addr reg is defined?
*
* Execute the Call Frame instruction sequence starting at
* @insn_start and ending at @insn_end. The instructions describe
@@ -342,36 +341,17 @@ static int dwarf_cfa_execute_insns(unsigned char *insn_start,
struct dwarf_cie *cie,
struct dwarf_fde *fde,
struct dwarf_frame *frame,
- unsigned long pc,
- bool define_ra)
+ unsigned long pc)
{
unsigned char insn;
unsigned char *current_insn;
unsigned int count, delta, reg, expr_len, offset;
- bool seen_ra_reg;
current_insn = insn_start;
- /*
- * If we're executing instructions for the dwarf_unwind_stack()
- * FDE we need to keep executing instructions until the value of
- * DWARF_ARCH_RA_REG is defined. See the comment in
- * dwarf_unwind_stack() for more details.
- */
- if (define_ra)
- seen_ra_reg = false;
- else
- seen_ra_reg = true;
-
- while (current_insn < insn_end && (frame->pc <= pc || !seen_ra_reg) ) {
+ while (current_insn < insn_end && frame->pc <= pc) {
insn = __raw_readb(current_insn++);
- if (!seen_ra_reg) {
- if (frame->num_regs >= DWARF_ARCH_RA_REG &&
- frame->regs[DWARF_ARCH_RA_REG].flags)
- seen_ra_reg = true;
- }
-
/*
* Firstly, handle the opcodes that embed their operands
* in the instructions.
@@ -484,6 +464,19 @@ static int dwarf_cfa_execute_insns(unsigned char *insn_start,
frame->regs[reg].flags |= DWARF_REG_OFFSET;
frame->regs[reg].addr = offset;
break;
+ case DW_CFA_GNU_args_size:
+ count = dwarf_read_uleb128(current_insn, &offset);
+ current_insn += count;
+ break;
+ case DW_CFA_GNU_negative_offset_extended:
+ count = dwarf_read_uleb128(current_insn, &reg);
+ current_insn += count;
+ count = dwarf_read_uleb128(current_insn, &offset);
+ offset *= cie->data_alignment_factor;
+ dwarf_frame_alloc_regs(frame, reg);
+ frame->regs[reg].flags |= DWARF_REG_OFFSET;
+ frame->regs[reg].addr = -offset;
+ break;
default:
pr_debug("unhandled DWARF instruction 0x%x\n", insn);
break;
@@ -510,26 +503,17 @@ struct dwarf_frame *dwarf_unwind_stack(unsigned long pc,
struct dwarf_fde *fde;
unsigned long addr;
int i, offset;
- bool define_ra = false;
/*
* If this is the first invocation of this recursive function we
* need get the contents of a physical register to get the CFA
* in order to begin the virtual unwinding of the stack.
*
- * Setting "define_ra" to true indictates that we want
- * dwarf_cfa_execute_insns() to continue executing instructions
- * until we know how to calculate the value of DWARF_ARCH_RA_REG
- * (which we need in order to kick off the whole unwinding
- * process).
- *
* NOTE: the return address is guaranteed to be setup by the
* time this function makes its first function call.
*/
- if (!pc && !prev) {
- pc = (unsigned long)&dwarf_unwind_stack;
- define_ra = true;
- }
+ if (!pc && !prev)
+ pc = (unsigned long)current_text_addr();
frame = kzalloc(sizeof(*frame), GFP_ATOMIC);
if (!frame)
@@ -565,11 +549,11 @@ struct dwarf_frame *dwarf_unwind_stack(unsigned long pc,
/* CIE initial instructions */
dwarf_cfa_execute_insns(cie->initial_instructions,
cie->instructions_end, cie, fde,
- frame, pc, false);
+ frame, pc);
/* FDE instructions */
dwarf_cfa_execute_insns(fde->instructions, fde->end, cie,
- fde, frame, pc, define_ra);
+ fde, frame, pc);
/* Calculate the CFA */
switch (frame->flags) {
diff --git a/arch/sh/kernel/entry-common.S b/arch/sh/kernel/entry-common.S
index e63178fefb9b..700477601c6f 100644
--- a/arch/sh/kernel/entry-common.S
+++ b/arch/sh/kernel/entry-common.S
@@ -77,15 +77,6 @@ ENTRY(ret_from_irq)
!
mov #OFF_SR, r0
mov.l @(r0,r15), r0 ! get status register
-
- shlr2 r0
- and #0x3c, r0
- cmp/eq #0x3c, r0
- bt 9f
- TRACE_IRQS_ON
-9:
- mov #OFF_SR, r0
- mov.l @(r0,r15), r0 ! get status register
shll r0
shll r0 ! kernel space?
get_current_thread_info r8, r0
@@ -96,6 +87,7 @@ ENTRY(ret_from_irq)
nop
ENTRY(resume_kernel)
cli
+ TRACE_IRQS_OFF
mov.l @(TI_PRE_COUNT,r8), r0 ! current_thread_info->preempt_count
tst r0, r0
bf noresched
@@ -213,12 +205,25 @@ syscall_trace_entry:
mov.l r0, @(OFF_R0,r15) ! Return value
__restore_all:
- mov.l 1f, r0
+ mov #OFF_SR, r0
+ mov.l @(r0,r15), r0 ! get status register
+
+ shlr2 r0
+ and #0x3c, r0
+ cmp/eq #0x3c, r0
+ bt 1f
+ TRACE_IRQS_ON
+ bra 2f
+ nop
+1:
+ TRACE_IRQS_OFF
+2:
+ mov.l 3f, r0
jmp @r0
nop
.align 2
-1: .long restore_all
+3: .long restore_all
.align 2
syscall_badsys: ! Bad syscall number
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 738bdc6b0f8b..13ffa5df37d7 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -24,6 +24,7 @@ config X86
select HAVE_UNSTABLE_SCHED_CLOCK
select HAVE_IDE
select HAVE_OPROFILE
+ select HAVE_PERF_COUNTERS if (!M386 && !M486)
select HAVE_IOREMAP_PROT
select HAVE_KPROBES
select ARCH_WANT_OPTIONAL_GPIOLIB
@@ -742,7 +743,6 @@ config X86_UP_IOAPIC
config X86_LOCAL_APIC
def_bool y
depends on X86_64 || SMP || X86_32_NON_STANDARD || X86_UP_APIC
- select HAVE_PERF_COUNTERS if (!M386 && !M486)
config X86_IO_APIC
def_bool y
diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c
index e2485b03f1cf..63fddcd082cd 100644
--- a/arch/x86/kernel/cpu/amd.c
+++ b/arch/x86/kernel/cpu/amd.c
@@ -400,6 +400,13 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c)
level = cpuid_eax(1);
if((level >= 0x0f48 && level < 0x0f50) || level >= 0x0f58)
set_cpu_cap(c, X86_FEATURE_REP_GOOD);
+
+ /*
+ * Some BIOSes incorrectly force this feature, but only K8
+ * revision D (model = 0x14) and later actually support it.
+ */
+ if (c->x86_model < 0x14)
+ clear_cpu_cap(c, X86_FEATURE_LAHF_LM);
}
if (c->x86 == 0x10 || c->x86 == 0x11)
set_cpu_cap(c, X86_FEATURE_REP_GOOD);
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index f1961c07af9a..5ce60a88027b 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -59,7 +59,30 @@ void __init setup_cpu_local_masks(void)
alloc_bootmem_cpumask_var(&cpu_sibling_setup_mask);
}
-static const struct cpu_dev *this_cpu __cpuinitdata;
+static void __cpuinit default_init(struct cpuinfo_x86 *c)
+{
+#ifdef CONFIG_X86_64
+ display_cacheinfo(c);
+#else
+ /* Not much we can do here... */
+ /* Check if at least it has cpuid */
+ if (c->cpuid_level == -1) {
+ /* No cpuid. It must be an ancient CPU */
+ if (c->x86 == 4)
+ strcpy(c->x86_model_id, "486");
+ else if (c->x86 == 3)
+ strcpy(c->x86_model_id, "386");
+ }
+#endif
+}
+
+static const struct cpu_dev __cpuinitconst default_cpu = {
+ .c_init = default_init,
+ .c_vendor = "Unknown",
+ .c_x86_vendor = X86_VENDOR_UNKNOWN,
+};
+
+static const struct cpu_dev *this_cpu __cpuinitdata = &default_cpu;
DEFINE_PER_CPU_PAGE_ALIGNED(struct gdt_page, gdt_page) = { .gdt = {
#ifdef CONFIG_X86_64
@@ -332,29 +355,6 @@ void switch_to_new_gdt(int cpu)
static const struct cpu_dev *__cpuinitdata cpu_devs[X86_VENDOR_NUM] = {};
-static void __cpuinit default_init(struct cpuinfo_x86 *c)
-{
-#ifdef CONFIG_X86_64
- display_cacheinfo(c);
-#else
- /* Not much we can do here... */
- /* Check if at least it has cpuid */
- if (c->cpuid_level == -1) {
- /* No cpuid. It must be an ancient CPU */
- if (c->x86 == 4)
- strcpy(c->x86_model_id, "486");
- else if (c->x86 == 3)
- strcpy(c->x86_model_id, "386");
- }
-#endif
-}
-
-static const struct cpu_dev __cpuinitconst default_cpu = {
- .c_init = default_init,
- .c_vendor = "Unknown",
- .c_x86_vendor = X86_VENDOR_UNKNOWN,
-};
-
static void __cpuinit get_model_name(struct cpuinfo_x86 *c)
{
unsigned int *v;
diff --git a/arch/x86/kernel/cpu/mcheck/therm_throt.c b/arch/x86/kernel/cpu/mcheck/therm_throt.c
index bff8dd191dd5..8bc64cfbe936 100644
--- a/arch/x86/kernel/cpu/mcheck/therm_throt.c
+++ b/arch/x86/kernel/cpu/mcheck/therm_throt.c
@@ -36,6 +36,7 @@
static DEFINE_PER_CPU(__u64, next_check) = INITIAL_JIFFIES;
static DEFINE_PER_CPU(unsigned long, thermal_throttle_count);
+static DEFINE_PER_CPU(bool, thermal_throttle_active);
static atomic_t therm_throt_en = ATOMIC_INIT(0);
@@ -96,24 +97,27 @@ static int therm_throt_process(int curr)
{
unsigned int cpu = smp_processor_id();
__u64 tmp_jiffs = get_jiffies_64();
+ bool was_throttled = __get_cpu_var(thermal_throttle_active);
+ bool is_throttled = __get_cpu_var(thermal_throttle_active) = curr;
- if (curr)
+ if (is_throttled)
__get_cpu_var(thermal_throttle_count)++;
- if (time_before64(tmp_jiffs, __get_cpu_var(next_check)))
+ if (!(was_throttled ^ is_throttled) &&
+ time_before64(tmp_jiffs, __get_cpu_var(next_check)))
return 0;
__get_cpu_var(next_check) = tmp_jiffs + CHECK_INTERVAL;
/* if we just entered the thermal event */
- if (curr) {
+ if (is_throttled) {
printk(KERN_CRIT "CPU%d: Temperature above threshold, "
- "cpu clock throttled (total events = %lu)\n", cpu,
- __get_cpu_var(thermal_throttle_count));
+ "cpu clock throttled (total events = %lu)\n",
+ cpu, __get_cpu_var(thermal_throttle_count));
add_taint(TAINT_MACHINE_CHECK);
- } else {
- printk(KERN_CRIT "CPU%d: Temperature/speed normal\n", cpu);
+ } else if (was_throttled) {
+ printk(KERN_INFO "CPU%d: Temperature/speed normal\n", cpu);
}
return 1;
diff --git a/arch/x86/kernel/cpu/perf_counter.c b/arch/x86/kernel/cpu/perf_counter.c
index a7aa8f900954..900332b800f8 100644
--- a/arch/x86/kernel/cpu/perf_counter.c
+++ b/arch/x86/kernel/cpu/perf_counter.c
@@ -55,6 +55,7 @@ struct x86_pmu {
int num_counters_fixed;
int counter_bits;
u64 counter_mask;
+ int apic;
u64 max_period;
u64 intel_ctrl;
};
@@ -72,8 +73,8 @@ static const u64 p6_perfmon_event_map[] =
{
[PERF_COUNT_HW_CPU_CYCLES] = 0x0079,
[PERF_COUNT_HW_INSTRUCTIONS] = 0x00c0,
- [PERF_COUNT_HW_CACHE_REFERENCES] = 0x0000,
- [PERF_COUNT_HW_CACHE_MISSES] = 0x0000,
+ [PERF_COUNT_HW_CACHE_REFERENCES] = 0x0f2e,
+ [PERF_COUNT_HW_CACHE_MISSES] = 0x012e,
[PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = 0x00c4,
[PERF_COUNT_HW_BRANCH_MISSES] = 0x00c5,
[PERF_COUNT_HW_BUS_CYCLES] = 0x0062,
@@ -613,6 +614,7 @@ static DEFINE_MUTEX(pmc_reserve_mutex);
static bool reserve_pmc_hardware(void)
{
+#ifdef CONFIG_X86_LOCAL_APIC
int i;
if (nmi_watchdog == NMI_LOCAL_APIC)
@@ -627,9 +629,11 @@ static bool reserve_pmc_hardware(void)
if (!reserve_evntsel_nmi(x86_pmu.eventsel + i))
goto eventsel_fail;
}
+#endif
return true;
+#ifdef CONFIG_X86_LOCAL_APIC
eventsel_fail:
for (i--; i >= 0; i--)
release_evntsel_nmi(x86_pmu.eventsel + i);
@@ -644,10 +648,12 @@ perfctr_fail:
enable_lapic_nmi_watchdog();
return false;
+#endif
}
static void release_pmc_hardware(void)
{
+#ifdef CONFIG_X86_LOCAL_APIC
int i;
for (i = 0; i < x86_pmu.num_counters; i++) {
@@ -657,6 +663,7 @@ static void release_pmc_hardware(void)
if (nmi_watchdog == NMI_LOCAL_APIC)
enable_lapic_nmi_watchdog();
+#endif
}
static void hw_perf_counter_destroy(struct perf_counter *counter)
@@ -748,6 +755,15 @@ static int __hw_perf_counter_init(struct perf_counter *counter)
hwc->sample_period = x86_pmu.max_period;
hwc->last_period = hwc->sample_period;
atomic64_set(&hwc->period_left, hwc->sample_period);
+ } else {
+ /*
+ * If we have a PMU initialized but no APIC
+ * interrupts, we cannot sample hardware
+ * counters (user-space has to fall back and
+ * sample via a hrtimer based software counter):
+ */
+ if (!x86_pmu.apic)
+ return -EOPNOTSUPP;
}
counter->destroy = hw_perf_counter_destroy;
@@ -1449,18 +1465,22 @@ void smp_perf_pending_interrupt(struct pt_regs *regs)
void set_perf_counter_pending(void)
{
+#ifdef CONFIG_X86_LOCAL_APIC
apic->send_IPI_self(LOCAL_PENDING_VECTOR);
+#endif
}
void perf_counters_lapic_init(void)
{
- if (!x86_pmu_initialized())
+#ifdef CONFIG_X86_LOCAL_APIC
+ if (!x86_pmu.apic || !x86_pmu_initialized())
return;
/*
* Always use NMI for PMU
*/
apic_write(APIC_LVTPC, APIC_DM_NMI);
+#endif
}
static int __kprobes
@@ -1484,7 +1504,9 @@ perf_counter_nmi_handler(struct notifier_block *self,
regs = args->regs;
+#ifdef CONFIG_X86_LOCAL_APIC
apic_write(APIC_LVTPC, APIC_DM_NMI);
+#endif
/*
* Can't rely on the handled return value to say it was our NMI, two
* counters could trigger 'simultaneously' raising two back-to-back NMIs.
@@ -1515,6 +1537,7 @@ static struct x86_pmu p6_pmu = {
.event_map = p6_pmu_event_map,
.raw_event = p6_pmu_raw_event,
.max_events = ARRAY_SIZE(p6_perfmon_event_map),
+ .apic = 1,
.max_period = (1ULL << 31) - 1,
.version = 0,
.num_counters = 2,
@@ -1541,6 +1564,7 @@ static struct x86_pmu intel_pmu = {
.event_map = intel_pmu_event_map,
.raw_event = intel_pmu_raw_event,
.max_events = ARRAY_SIZE(intel_perfmon_event_map),
+ .apic = 1,
/*
* Intel PMCs cannot be accessed sanely above 32 bit width,
* so we install an artificial 1<<31 period regardless of
@@ -1564,6 +1588,7 @@ static struct x86_pmu amd_pmu = {
.num_counters = 4,
.counter_bits = 48,
.counter_mask = (1ULL << 48) - 1,
+ .apic = 1,
/* use highest bit to detect overflow */
.max_period = (1ULL << 47) - 1,
};
@@ -1589,13 +1614,14 @@ static int p6_pmu_init(void)
return -ENODEV;
}
+ x86_pmu = p6_pmu;
+
if (!cpu_has_apic) {
- pr_info("no Local APIC, try rebooting with lapic");
- return -ENODEV;
+ pr_info("no APIC, boot with the \"lapic\" boot parameter to force-enable it.\n");
+ pr_info("no hardware sampling interrupt available.\n");
+ x86_pmu.apic = 0;
}
- x86_pmu = p6_pmu;
-
return 0;
}
diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c
index 9eb897603705..a06e8d101844 100644
--- a/arch/x86/kernel/reboot.c
+++ b/arch/x86/kernel/reboot.c
@@ -418,20 +418,20 @@ static int __init set_pci_reboot(const struct dmi_system_id *d)
}
static struct dmi_system_id __initdata pci_reboot_dmi_table[] = {
- { /* Handle problems with rebooting on Apple MacBook5,2 */
+ { /* Handle problems with rebooting on Apple MacBook5 */
.callback = set_pci_reboot,
- .ident = "Apple MacBook",
+ .ident = "Apple MacBook5",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
- DMI_MATCH(DMI_PRODUCT_NAME, "MacBook5,2"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "MacBook5"),
},
},
- { /* Handle problems with rebooting on Apple MacBookPro5,1 */
+ { /* Handle problems with rebooting on Apple MacBookPro5 */
.callback = set_pci_reboot,
- .ident = "Apple MacBookPro5,1",
+ .ident = "Apple MacBookPro5",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
- DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro5,1"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro5"),
},
},
{ }