summaryrefslogtreecommitdiffstats
path: root/arch/sh/kernel/pm.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@g5.osdl.org>2006-09-27 08:49:07 -0700
committerLinus Torvalds <torvalds@g5.osdl.org>2006-09-27 08:49:07 -0700
commitb98adfccdf5f8dd34ae56a2d5adbe2c030bd4674 (patch)
tree1807a029520f550dd4f90c95ad0063bceb00d645 /arch/sh/kernel/pm.c
parentba21fe71725f94792330ebc3034ef2b35a36276f (diff)
parent33573c0e3243aaa38b6ad96942de85a1b713c2ff (diff)
downloadkernel-crypto-b98adfccdf5f8dd34ae56a2d5adbe2c030bd4674.tar.gz
kernel-crypto-b98adfccdf5f8dd34ae56a2d5adbe2c030bd4674.tar.xz
kernel-crypto-b98adfccdf5f8dd34ae56a2d5adbe2c030bd4674.zip
Merge master.kernel.org:/pub/scm/linux/kernel/git/lethal/sh-2.6
* master.kernel.org:/pub/scm/linux/kernel/git/lethal/sh-2.6: (108 commits) sh: Fix occasional flush_cache_4096() stack corruption. sh: Calculate shm alignment at runtime. sh: dma-mapping compile fixes. sh: Initial vsyscall page support. sh: Clean up PAGE_SIZE definition for assembly use. sh: Selective flush_cache_mm() flushing. sh: More intelligent entry_mask/way_size calculation. sh: Support for L2 cache on newer SH-4A CPUs. sh: Update kexec support for API changes. sh: Optimized readsl()/writesl() support. sh: Report movli.l/movco.l capabilities. sh: CPU flags in AT_HWCAP in ELF auxvt. sh: Add support for 4K stacks. sh: Enable /proc/kcore support. sh: stack debugging support. sh: select CONFIG_EMBEDDED. sh: machvec rework. sh: Solution Engine SH7343 board support. sh: SH7710VoIPGW board support. sh: Enable verbose BUG() support. ...
Diffstat (limited to 'arch/sh/kernel/pm.c')
-rw-r--r--arch/sh/kernel/pm.c88
1 files changed, 88 insertions, 0 deletions
diff --git a/arch/sh/kernel/pm.c b/arch/sh/kernel/pm.c
new file mode 100644
index 00000000000..10ab62c9aed
--- /dev/null
+++ b/arch/sh/kernel/pm.c
@@ -0,0 +1,88 @@
+/*
+ * Generic Power Management Routine
+ *
+ * Copyright (c) 2006 Andriy Skulysh <askulsyh@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License.
+ */
+#include <linux/suspend.h>
+#include <linux/delay.h>
+#include <linux/gfp.h>
+#include <asm/freq.h>
+#include <asm/io.h>
+#include <asm/watchdog.h>
+#include <asm/pm.h>
+
+#define INTR_OFFSET 0x600
+
+#define STBCR 0xffffff82
+#define STBCR2 0xffffff88
+
+#define STBCR_STBY 0x80
+#define STBCR_MSTP2 0x04
+
+#define MCR 0xffffff68
+#define RTCNT 0xffffff70
+
+#define MCR_RMODE 2
+#define MCR_RFSH 4
+
+void pm_enter(void)
+{
+ u8 stbcr, csr;
+ u16 frqcr, mcr;
+ u32 vbr_new, vbr_old;
+
+ set_bl_bit();
+
+ /* set wdt */
+ csr = sh_wdt_read_csr();
+ csr &= ~WTCSR_TME;
+ csr |= WTCSR_CKS_4096;
+ sh_wdt_write_csr(csr);
+ csr = sh_wdt_read_csr();
+ sh_wdt_write_cnt(0);
+
+ /* disable PLL1 */
+ frqcr = ctrl_inw(FRQCR);
+ frqcr &= ~(FRQCR_PLLEN | FRQCR_PSTBY);
+ ctrl_outw(frqcr, FRQCR);
+
+ /* enable standby */
+ stbcr = ctrl_inb(STBCR);
+ ctrl_outb(stbcr | STBCR_STBY | STBCR_MSTP2, STBCR);
+
+ /* set self-refresh */
+ mcr = ctrl_inw(MCR);
+ ctrl_outw(mcr & ~MCR_RFSH, MCR);
+
+ /* set interrupt handler */
+ asm volatile("stc vbr, %0" : "=r" (vbr_old));
+ vbr_new = get_zeroed_page(GFP_ATOMIC);
+ udelay(50);
+ memcpy((void*)(vbr_new + INTR_OFFSET),
+ &wakeup_start, &wakeup_end - &wakeup_start);
+ asm volatile("ldc %0, vbr" : : "r" (vbr_new));
+
+ ctrl_outw(0, RTCNT);
+ ctrl_outw(mcr | MCR_RFSH | MCR_RMODE, MCR);
+
+ cpu_sleep();
+
+ asm volatile("ldc %0, vbr" : : "r" (vbr_old));
+
+ free_page(vbr_new);
+
+ /* enable PLL1 */
+ frqcr = ctrl_inw(FRQCR);
+ frqcr |= FRQCR_PSTBY;
+ ctrl_outw(frqcr, FRQCR);
+ udelay(50);
+ frqcr |= FRQCR_PLLEN;
+ ctrl_outw(frqcr, FRQCR);
+
+ ctrl_outb(stbcr, STBCR);
+
+ clear_bl_bit();
+}