sh: APM/PM support.

This adds some simple PM stubs and the basic APM interfaces,
primarily for use by hp6xx, where the existing userland
expects it.

Signed-off-by: Andriy Skulysh <askulysh@gmail.com>
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
diff --git a/arch/sh/boards/hp6xx/pm.c b/arch/sh/boards/hp6xx/pm.c
new file mode 100644
index 0000000..0e501bc
--- /dev/null
+++ b/arch/sh/boards/hp6xx/pm.c
@@ -0,0 +1,88 @@
+/*
+ * hp6x0 Power Management Routines
+ *
+ * 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/config.h>
+#include <linux/init.h>
+#include <linux/suspend.h>
+#include <linux/errno.h>
+#include <linux/time.h>
+#include <asm/io.h>
+#include <asm/hd64461.h>
+#include <asm/hp6xx/hp6xx.h>
+#include <asm/cpu/dac.h>
+#include <asm/pm.h>
+
+#define STBCR		0xffffff82
+#define STBCR2		0xffffff88
+
+static int hp6x0_pm_enter(suspend_state_t state)
+{
+	u8 stbcr, stbcr2;
+#ifdef CONFIG_HD64461_ENABLER
+	u8 scr;
+	u16 hd64461_stbcr;
+#endif
+
+	if (state != PM_SUSPEND_MEM)
+		return -EINVAL;
+
+#ifdef CONFIG_HD64461_ENABLER
+	outb(0, HD64461_PCC1CSCIER);
+
+	scr = inb(HD64461_PCC1SCR);
+	scr |= HD64461_PCCSCR_VCC1;
+	outb(scr, HD64461_PCC1SCR);
+
+	hd64461_stbcr = inw(HD64461_STBCR);
+	hd64461_stbcr |= HD64461_STBCR_SPC1ST;
+	outw(hd64461_stbcr, HD64461_STBCR);
+#endif
+
+	ctrl_outb(0x1f, DACR);
+
+	stbcr = ctrl_inb(STBCR);
+	ctrl_outb(0x01, STBCR);
+
+	stbcr2 = ctrl_inb(STBCR2);
+	ctrl_outb(0x7f , STBCR2);
+
+	outw(0xf07f, HD64461_SCPUCR);
+
+	pm_enter();
+
+	outw(0, HD64461_SCPUCR);
+	ctrl_outb(stbcr, STBCR);
+	ctrl_outb(stbcr2, STBCR2);
+
+#ifdef CONFIG_HD64461_ENABLER
+	hd64461_stbcr = inw(HD64461_STBCR);
+	hd64461_stbcr &= ~HD64461_STBCR_SPC1ST;
+	outw(hd64461_stbcr, HD64461_STBCR);
+
+	outb(0x4c, HD64461_PCC1CSCIER);
+	outb(0x00, HD64461_PCC1CSCR);
+#endif
+
+	return 0;
+}
+
+/*
+ * Set to PM_DISK_FIRMWARE so we can quickly veto suspend-to-disk.
+ */
+static struct pm_ops hp6x0_pm_ops = {
+	.pm_disk_mode	= PM_DISK_FIRMWARE,
+	.enter		= hp6x0_pm_enter,
+};
+
+static int __init hp6x0_pm_init(void)
+{
+	pm_set_ops(&hp6x0_pm_ops);
+	return 0;
+}
+
+late_initcall(hp6x0_pm_init);