summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorPaul Irofti <pirofti@cvs.openbsd.org>2010-08-31 10:24:47 +0000
committerPaul Irofti <pirofti@cvs.openbsd.org>2010-08-31 10:24:47 +0000
commit12ed26cb2111068191436c2c2d5ea96bfabc55c3 (patch)
tree22f3b4be2aefaef7b505f1c7d6b6335e6617c559 /sys
parentfac9264a5a14dde04909fa5d6f9d716e54ff2f9c (diff)
WIP suspend/resume support for loongson lemote. Okay miod@.
Diffstat (limited to 'sys')
-rw-r--r--sys/arch/loongson/dev/apm.c53
-rw-r--r--sys/arch/loongson/dev/bonito.c5
-rw-r--r--sys/arch/loongson/dev/kb3310.c105
-rw-r--r--sys/arch/loongson/dev/kb3310var.h24
-rw-r--r--sys/arch/loongson/dev/mainbus.c5
-rw-r--r--sys/arch/loongson/dev/smfb.c26
-rw-r--r--sys/arch/loongson/include/autoconf.h4
-rw-r--r--sys/arch/loongson/loongson/yeeloong_machdep.c7
8 files changed, 212 insertions, 17 deletions
diff --git a/sys/arch/loongson/dev/apm.c b/sys/arch/loongson/dev/apm.c
index e5822bf861e..64412d8587e 100644
--- a/sys/arch/loongson/dev/apm.c
+++ b/sys/arch/loongson/dev/apm.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: apm.c,v 1.3 2010/05/08 21:59:56 miod Exp $ */
+/* $OpenBSD: apm.c,v 1.4 2010/08/31 10:24:46 pirofti Exp $ */
/*-
* Copyright (c) 2001 Alexander Guy. All rights reserved.
@@ -41,13 +41,14 @@
#include <sys/fcntl.h>
#include <sys/ioctl.h>
#include <sys/event.h>
+#include <sys/mount.h>
#include <machine/autoconf.h>
#include <machine/conf.h>
#include <machine/cpu.h>
#include <machine/apmvar.h>
-
+#include <loongson/dev/kb3310var.h>
#if defined(APMDEBUG)
#define DPRINTF(x) printf x
@@ -82,6 +83,9 @@ int filt_apmread(struct knote *kn, long hint);
int apmkqfilter(dev_t dev, struct knote *kn);
int apm_getdefaultinfo(struct apm_power_info *);
+int apm_suspend(void);
+int apm_resume(void);
+
struct filterops apmread_filtops =
{ 1, NULL, filt_apmrdetach, filt_apmread};
@@ -213,8 +217,13 @@ apmioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
case APM_IOC_SUSPEND:
if ((flag & FWRITE) == 0)
error = EBADF;
- else
- error = EOPNOTSUPP; /* XXX */
+ else if (sys_platform->suspend == NULL ||
+ sys_platform->resume == NULL)
+ error = EOPNOTSUPP;
+ else {
+ if (!(error = apm_suspend()))
+ error = apm_resume();
+ }
break;
case APM_IOC_PRN_CTL:
if ((flag & FWRITE) == 0)
@@ -259,8 +268,13 @@ apmioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
case APM_IOC_SUSPEND_REQ:
if ((flag & FWRITE) == 0)
error = EBADF;
- else
- error = EOPNOTSUPP; /* XXX */
+ else if (sys_platform->suspend == NULL ||
+ sys_platform->resume == NULL)
+ error = EOPNOTSUPP;
+ else {
+ if (!(error = apm_suspend()))
+ error = apm_resume();
+ }
break;
default:
error = ENOTTY;
@@ -349,3 +363,30 @@ apm_record_event(u_int event, const char *src, const char *msg)
return (0);
}
+
+int
+apm_suspend()
+{
+ int s;
+
+ s = splhigh();
+ config_suspend(TAILQ_FIRST(&alldevs), DVACT_SUSPEND);
+ splx(s);
+
+ if (cold)
+ vfs_syncwait(0);
+
+ return sys_platform->suspend();
+}
+
+int
+apm_resume()
+{
+ int s;
+
+ s = splhigh();
+ config_suspend(TAILQ_FIRST(&alldevs), DVACT_RESUME);
+ splx(s);
+
+ return sys_platform->resume();
+}
diff --git a/sys/arch/loongson/dev/bonito.c b/sys/arch/loongson/dev/bonito.c
index 884d2019002..52ff0593f7c 100644
--- a/sys/arch/loongson/dev/bonito.c
+++ b/sys/arch/loongson/dev/bonito.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: bonito.c,v 1.15 2010/07/18 13:36:13 miod Exp $ */
+/* $OpenBSD: bonito.c,v 1.16 2010/08/31 10:24:46 pirofti Exp $ */
/* $NetBSD: bonito_mainbus.c,v 1.11 2008/04/28 20:23:10 martin Exp $ */
/* $NetBSD: bonito_pci.c,v 1.5 2008/04/28 20:23:28 martin Exp $ */
@@ -80,7 +80,8 @@ int bonito_match(struct device *, void *, void *);
void bonito_attach(struct device *, struct device *, void *);
const struct cfattach bonito_ca = {
- sizeof(struct bonito_softc), bonito_match, bonito_attach
+ sizeof(struct bonito_softc), bonito_match, bonito_attach,
+ NULL, config_activate_children
};
struct cfdriver bonito_cd = {
diff --git a/sys/arch/loongson/dev/kb3310.c b/sys/arch/loongson/dev/kb3310.c
index ab9a4634b90..2cf28c8d6d7 100644
--- a/sys/arch/loongson/dev/kb3310.c
+++ b/sys/arch/loongson/dev/kb3310.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kb3310.c,v 1.11 2010/07/31 16:04:46 miod Exp $ */
+/* $OpenBSD: kb3310.c,v 1.12 2010/08/31 10:24:46 pirofti Exp $ */
/*
* Copyright (c) 2010 Otto Moerbeek <otto@drijf.net>
*
@@ -28,6 +28,10 @@
#include <machine/bus.h>
#include <dev/isa/isavar.h>
+#include <loongson/dev/bonitoreg.h>
+#include <loongson/dev/kb3310var.h>
+#include <loongson/dev/glxreg.h>
+
#include "apm.h"
#include "pckbd.h"
#include "hidkbd.h"
@@ -42,6 +46,12 @@ struct cfdriver ykbec_cd = {
NULL, "ykbec", DV_DULL,
};
+#ifdef KB3310_DEBUG
+#define DPRINTF(x) printf x
+#else
+#define DPRINTF(x)
+#endif
+
#define IO_YKBEC 0x381
#define IO_YKBECSIZE 0x3
@@ -81,6 +91,12 @@ struct ykbec_softc {
#endif
};
+static struct ykbec_softc *ykbec_sc;
+static int ykbec_chip_config;
+static int ykbec_apmspl;
+
+extern void loongson_set_isa_imr(uint);
+
int ykbec_match(struct device *, void *, void *);
void ykbec_attach(struct device *, struct device *, void *);
@@ -187,6 +203,7 @@ ykbec_attach(struct device *parent, struct device *self, void *aux)
hidkbd_hookup_bell(ykbec_bell, sc);
#endif
#endif
+ ykbec_sc = sc;
}
void
@@ -273,6 +290,28 @@ ykbec_read16(struct ykbec_softc *mcsc, u_int reg)
#define REG_BEEP_CONTROL 0xf4d0
#define BEEP_ENABLE (1<<0)
+#define REG_PMUCFG 0xff0c
+#define PMUCFG_STOP_MODE (1<<7)
+#define PMUCFG_IDLE_MODE (1<<6)
+#define PMUCFG_LPC_WAKEUP (1<<5)
+#define PMUCFG_RESET_8051 (1<<4)
+#define PMUCFG_SCI_WAKEUP (1<<3)
+#define PMUCFG_WDT_WAKEUP (1<<2)
+#define PMUCFG_GPWU_WAKEUP (1<<1)
+#define PMUCFG_IRQ_IDLE (1<<0)
+
+#define REG_USB0 0xf461
+#define REG_USB1 0xf462
+#define REG_USB2 0xf463
+#define USB_FLAG_ON 1
+#define USB_FLAG_OFF 0
+
+#define REG_FAN_CONTROL 0xf4d2
+#define REG_FAN_ON 1
+#define REG_FAN_OFF 0
+
+#define YKBEC_SCI_IRQ 0xa
+
#ifdef DEBUG
void
ykbec_print_bat_info(struct ykbec_softc *sc)
@@ -400,6 +439,70 @@ ykbec_apminfo(struct apm_power_info *info)
bcopy(&ykbec_apmdata, info, sizeof(struct apm_power_info));
return 0;
}
+
+int
+ykbec_suspend()
+{
+ struct ykbec_softc *sc = ykbec_sc;
+ int ctrl;
+
+ /* IRQ */
+ DPRINTF(("IRQ\n"));
+ ykbec_apmspl = splhigh();
+ /* enable isa irq 1 and 12 (PS/2 input devices) */
+ loongson_set_isa_imr(0xffff & ~(1 << 1) & ~(1 << 12));
+
+ /* USB */
+ DPRINTF(("USB\n"));
+ ykbec_write(sc, REG_USB0, USB_FLAG_OFF);
+ ykbec_write(sc, REG_USB1, USB_FLAG_OFF);
+ ykbec_write(sc, REG_USB2, USB_FLAG_OFF);
+
+ /* EC */
+ DPRINTF(("REG_PMUCFG\n"));
+ ctrl = PMUCFG_SCI_WAKEUP | PMUCFG_WDT_WAKEUP | PMUCFG_GPWU_WAKEUP |
+ PMUCFG_LPC_WAKEUP | PMUCFG_STOP_MODE | PMUCFG_RESET_8051;
+ ykbec_write(sc, REG_PMUCFG, ctrl);
+
+ /* FAN */
+ DPRINTF(("FAN\n"));
+ ykbec_write(sc, REG_FAN_CONTROL, REG_FAN_OFF);
+
+ /* CPU */
+ DPRINTF(("CPU\n"));
+ ykbec_chip_config = REGVAL(LOONGSON_CHIP_CONFIG0);
+ REGVAL(LOONGSON_CHIP_CONFIG0) = ykbec_chip_config & ~0x7;
+ (void)REGVAL(LOONGSON_CHIP_CONFIG0);
+
+ return 0;
+}
+
+int
+ykbec_resume()
+{
+ struct ykbec_softc *sc = ykbec_sc;
+
+ /* IRQ */
+ DPRINTF(("IRQ\n"));
+ splx(ykbec_apmspl);
+
+ /* CPU */
+ DPRINTF(("CPU\n"));
+ REGVAL(LOONGSON_CHIP_CONFIG0) = ykbec_chip_config;
+ (void)REGVAL(LOONGSON_CHIP_CONFIG0);
+
+ /* FAN */
+ DPRINTF(("FAN\n"));
+ ykbec_write(sc, REG_FAN_CONTROL, REG_FAN_ON);
+
+ /* USB */
+ DPRINTF(("USB\n"));
+ ykbec_write(sc, REG_USB0, USB_FLAG_ON);
+ ykbec_write(sc, REG_USB1, USB_FLAG_ON);
+ ykbec_write(sc, REG_USB2, USB_FLAG_ON);
+
+ return 0;
+}
#endif
#if NPCKBD > 0 || NHIDKBD > 0
diff --git a/sys/arch/loongson/dev/kb3310var.h b/sys/arch/loongson/dev/kb3310var.h
new file mode 100644
index 00000000000..fde2a616290
--- /dev/null
+++ b/sys/arch/loongson/dev/kb3310var.h
@@ -0,0 +1,24 @@
+/* $OpenBSD: kb3310var.h,v 1.1 2010/08/31 10:24:46 pirofti Exp $ */
+/*
+ * Copyright (c) 2009 Paul Irofti <pirofti@openbsd.org>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _LOONGSON_DEV_YKBECVAR_H_
+#define _LOONGSON_DEV_YKBECVAR_H_
+
+int ykbec_suspend(void);
+int ykbec_resume(void);
+
+#endif
diff --git a/sys/arch/loongson/dev/mainbus.c b/sys/arch/loongson/dev/mainbus.c
index 2dd88cf99e4..d1425d15846 100644
--- a/sys/arch/loongson/dev/mainbus.c
+++ b/sys/arch/loongson/dev/mainbus.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mainbus.c,v 1.4 2010/02/28 08:30:27 otto Exp $ */
+/* $OpenBSD: mainbus.c,v 1.5 2010/08/31 10:24:46 pirofti Exp $ */
/*
* Copyright (c) 2001-2003 Opsycon AB (www.opsycon.se / www.opsycon.com)
@@ -37,7 +37,8 @@ void mainbus_attach(struct device *, struct device *, void *);
int mainbus_print(void *, const char *);
const struct cfattach mainbus_ca = {
- sizeof(struct device), mainbus_match, mainbus_attach
+ sizeof(struct device), mainbus_match, mainbus_attach,
+ NULL, config_activate_children
};
struct cfdriver mainbus_cd = {
diff --git a/sys/arch/loongson/dev/smfb.c b/sys/arch/loongson/dev/smfb.c
index 1547bd4483d..745f4d4846a 100644
--- a/sys/arch/loongson/dev/smfb.c
+++ b/sys/arch/loongson/dev/smfb.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: smfb.c,v 1.9 2010/08/27 12:48:54 miod Exp $ */
+/* $OpenBSD: smfb.c,v 1.10 2010/08/31 10:24:46 pirofti Exp $ */
/*
* Copyright (c) 2009, 2010 Miodrag Vallat.
@@ -90,13 +90,16 @@ int smfb_pci_match(struct device *, void *, void *);
void smfb_pci_attach(struct device *, struct device *, void *);
int smfb_voyager_match(struct device *, void *, void *);
void smfb_voyager_attach(struct device *, struct device *, void *);
+int smfb_activate(struct device *, int);
const struct cfattach smfb_pci_ca = {
- sizeof(struct smfb_softc), smfb_pci_match, smfb_pci_attach
+ sizeof(struct smfb_softc), smfb_pci_match, smfb_pci_attach,
+ NULL, smfb_activate
};
const struct cfattach smfb_voyager_ca = {
- sizeof(struct smfb_softc), smfb_voyager_match, smfb_voyager_attach
+ sizeof(struct smfb_softc), smfb_voyager_match, smfb_voyager_attach,
+ smfb_activate
};
struct cfdriver smfb_cd = {
@@ -694,3 +697,20 @@ smfb_cnattach(bus_space_tag_t memt, bus_space_tag_t iot, pcitag_t tag,
return 0;
}
+
+int
+smfb_activate(struct device *self, int act)
+{
+ struct smfb_softc *sc = (struct smfb_softc *)self;
+
+ switch (act) {
+ case DVACT_SUSPEND:
+ smfb_burner(sc, 0, 0);
+ break;
+ case DVACT_RESUME:
+ smfb_burner(sc, 1, 0);
+ break;
+ }
+
+ return 0;
+}
diff --git a/sys/arch/loongson/include/autoconf.h b/sys/arch/loongson/include/autoconf.h
index 0a347e49020..ef6f1327dee 100644
--- a/sys/arch/loongson/include/autoconf.h
+++ b/sys/arch/loongson/include/autoconf.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: autoconf.h,v 1.7 2010/05/08 21:59:56 miod Exp $ */
+/* $OpenBSD: autoconf.h,v 1.8 2010/08/31 10:24:46 pirofti Exp $ */
/*
* Copyright (c) 2001-2003 Opsycon AB (www.opsycon.se / www.opsycon.com)
@@ -64,6 +64,8 @@ struct platform {
void (*powerdown)(void);
void (*reset)(void);
+ int (*suspend)(void);
+ int (*resume)(void);
};
extern const struct platform *sys_platform;
diff --git a/sys/arch/loongson/loongson/yeeloong_machdep.c b/sys/arch/loongson/loongson/yeeloong_machdep.c
index cf99f774400..67ef1769e62 100644
--- a/sys/arch/loongson/loongson/yeeloong_machdep.c
+++ b/sys/arch/loongson/loongson/yeeloong_machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: yeeloong_machdep.c,v 1.12 2010/05/08 21:59:56 miod Exp $ */
+/* $OpenBSD: yeeloong_machdep.c,v 1.13 2010/08/31 10:24:46 pirofti Exp $ */
/*
* Copyright (c) 2009, 2010 Miodrag Vallat.
@@ -41,6 +41,7 @@
#include <loongson/dev/bonito_irq.h>
#include <loongson/dev/glxreg.h>
#include <loongson/dev/glxvar.h>
+#include <loongson/dev/kb3310var.h>
#include "com.h"
@@ -193,7 +194,9 @@ const struct platform yeeloong_platform = {
.device_register = lemote_device_register,
.powerdown = yeeloong_powerdown,
- .reset = lemote_reset
+ .reset = lemote_reset,
+ .suspend = ykbec_suspend,
+ .resume = ykbec_resume
};
/*