diff options
author | Paul Irofti <pirofti@cvs.openbsd.org> | 2010-08-31 10:24:47 +0000 |
---|---|---|
committer | Paul Irofti <pirofti@cvs.openbsd.org> | 2010-08-31 10:24:47 +0000 |
commit | 12ed26cb2111068191436c2c2d5ea96bfabc55c3 (patch) | |
tree | 22f3b4be2aefaef7b505f1c7d6b6335e6617c559 /sys | |
parent | fac9264a5a14dde04909fa5d6f9d716e54ff2f9c (diff) |
WIP suspend/resume support for loongson lemote. Okay miod@.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/arch/loongson/dev/apm.c | 53 | ||||
-rw-r--r-- | sys/arch/loongson/dev/bonito.c | 5 | ||||
-rw-r--r-- | sys/arch/loongson/dev/kb3310.c | 105 | ||||
-rw-r--r-- | sys/arch/loongson/dev/kb3310var.h | 24 | ||||
-rw-r--r-- | sys/arch/loongson/dev/mainbus.c | 5 | ||||
-rw-r--r-- | sys/arch/loongson/dev/smfb.c | 26 | ||||
-rw-r--r-- | sys/arch/loongson/include/autoconf.h | 4 | ||||
-rw-r--r-- | sys/arch/loongson/loongson/yeeloong_machdep.c | 7 |
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 }; /* |