Module Name: src
Committed By: isaki
Date: Sun Nov 27 09:00:33 UTC 2011
Modified Files:
src/distrib/sets/lists/man: mi
src/share/man/man4/man4.x68k: Makefile
src/sys/arch/x68k/conf: GENERIC files.x68k
Added Files:
src/share/man/man4/man4.x68k: powsw.4
src/sys/arch/x68k/dev: powsw.c
Log Message:
Add powsw(4) for x68k power switch. It substitutes for a part about
power switch handler of pow(4) deleted before.
Benefits than pow(4):
- separate a front switch (= powsw0) and an EXPWON line (= powsw1)
completely. Only powsw0 is enabled in GENERIC by default.
- prevent chattering in some hardware individuals.
thank you for a report and a test: Yasushi Oshima and Y.Sugahara.
To generate a diff of this commit:
cvs rdiff -u -r1.1358 -r1.1359 src/distrib/sets/lists/man/mi
cvs rdiff -u -r1.8 -r1.9 src/share/man/man4/man4.x68k/Makefile
cvs rdiff -u -r0 -r1.1 src/share/man/man4/man4.x68k/powsw.4
cvs rdiff -u -r1.157 -r1.158 src/sys/arch/x68k/conf/GENERIC
cvs rdiff -u -r1.76 -r1.77 src/sys/arch/x68k/conf/files.x68k
cvs rdiff -u -r0 -r1.1 src/sys/arch/x68k/dev/powsw.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/distrib/sets/lists/man/mi
diff -u src/distrib/sets/lists/man/mi:1.1358 src/distrib/sets/lists/man/mi:1.1359
--- src/distrib/sets/lists/man/mi:1.1358 Sat Nov 26 15:39:49 2011
+++ src/distrib/sets/lists/man/mi Sun Nov 27 09:00:32 2011
@@ -1,4 +1,4 @@
-# $NetBSD: mi,v 1.1358 2011/11/26 15:39:49 tsutsui Exp $
+# $NetBSD: mi,v 1.1359 2011/11/27 09:00:32 isaki Exp $
#
# Note: don't delete entries from here - mark them as "obsolete" instead.
#
@@ -1826,6 +1826,7 @@
./usr/share/man/cat4/x68k/mfp.0 man-sys-catman .cat
./usr/share/man/cat4/x68k/neptune.0 man-sys-catman .cat
./usr/share/man/cat4/x68k/pow.0 man-obsolete obsolete
+./usr/share/man/cat4/x68k/powsw.0 man-sys-catman .cat
./usr/share/man/cat4/x68k/vs.0 man-sys-catman .cat
./usr/share/man/cat4/x86/amdpcib.0 man-sys-catman .cat
./usr/share/man/cat4/x86/apic.0 man-sys-catman .cat
@@ -4592,6 +4593,7 @@
./usr/share/man/html4/x68k/mfp.html man-sys-htmlman html
./usr/share/man/html4/x68k/neptune.html man-sys-htmlman html
./usr/share/man/html4/x68k/pow.html man-obsolete obsolete
+./usr/share/man/html4/x68k/powsw.html man-sys-htmlman html
./usr/share/man/html4/x68k/vs.html man-sys-htmlman html
./usr/share/man/html4/x86/amdpcib.html man-sys-htmlman html
./usr/share/man/html4/x86/apic.html man-sys-htmlman html
@@ -7293,6 +7295,7 @@
./usr/share/man/man4/x68k/mfp.4 man-sys-man .man
./usr/share/man/man4/x68k/neptune.4 man-sys-man .man
./usr/share/man/man4/x68k/pow.4 man-obsolete obsolete
+./usr/share/man/man4/x68k/powsw.4 man-sys-man .man
./usr/share/man/man4/x68k/vs.4 man-sys-man .man
./usr/share/man/man4/x86/amdpcib.4 man-sys-man .man
./usr/share/man/man4/x86/apic.4 man-sys-man .man
Index: src/share/man/man4/man4.x68k/Makefile
diff -u src/share/man/man4/man4.x68k/Makefile:1.8 src/share/man/man4/man4.x68k/Makefile:1.9
--- src/share/man/man4/man4.x68k/Makefile:1.8 Sat Nov 19 12:27:43 2011
+++ src/share/man/man4/man4.x68k/Makefile Sun Nov 27 09:00:33 2011
@@ -1,6 +1,6 @@
-# $NetBSD: Makefile,v 1.8 2011/11/19 12:27:43 isaki Exp $
+# $NetBSD: Makefile,v 1.9 2011/11/27 09:00:33 isaki Exp $
-MAN= bmd.4 intio.4 intro.4 mfp.4 neptune.4 vs.4
+MAN= bmd.4 intio.4 intro.4 mfp.4 neptune.4 powsw.4 vs.4
MANSUBDIR=/x68k
.include <bsd.man.mk>
Index: src/sys/arch/x68k/conf/GENERIC
diff -u src/sys/arch/x68k/conf/GENERIC:1.157 src/sys/arch/x68k/conf/GENERIC:1.158
--- src/sys/arch/x68k/conf/GENERIC:1.157 Tue Nov 22 21:25:41 2011
+++ src/sys/arch/x68k/conf/GENERIC Sun Nov 27 09:00:32 2011
@@ -1,4 +1,4 @@
-# $NetBSD: GENERIC,v 1.157 2011/11/22 21:25:41 tls Exp $
+# $NetBSD: GENERIC,v 1.158 2011/11/27 09:00:32 isaki Exp $
#
# GENERIC machine description file
#
@@ -22,7 +22,7 @@ include "arch/x68k/conf/std.x68k"
options INCLUDE_CONFIG_FILE # embed config file in kernel binary
-#ident "GENERIC-$Revision: 1.157 $"
+#ident "GENERIC-$Revision: 1.158 $"
maxusers 8
@@ -288,6 +288,9 @@ par0 at intio0 addr 0xe8c000 # Builtin
sram0 at intio0 addr 0xed0000 # battery-backuped static RAM
pseudo-device bell # OPM bell
+powsw0 at mfp0 # Front switch
+#powsw1 at mfp0 # External power switch
+
xcom0 at mainbus0 # NS16550 fast serial
xcom1 at mainbus0
Index: src/sys/arch/x68k/conf/files.x68k
diff -u src/sys/arch/x68k/conf/files.x68k:1.76 src/sys/arch/x68k/conf/files.x68k:1.77
--- src/sys/arch/x68k/conf/files.x68k:1.76 Sat Nov 19 12:27:43 2011
+++ src/sys/arch/x68k/conf/files.x68k Sun Nov 27 09:00:32 2011
@@ -1,4 +1,4 @@
-# $NetBSD: files.x68k,v 1.76 2011/11/19 12:27:43 isaki Exp $
+# $NetBSD: files.x68k,v 1.77 2011/11/27 09:00:32 isaki Exp $
#
# new style config file for x68k architecture
#
@@ -96,6 +96,10 @@ device kbd: event
attach kbd at mfp
file arch/x68k/dev/kbd.c kbd needs-flag
+device powsw: sysmon_power, sysmon_taskq
+attach powsw at mfp
+file arch/x68k/dev/powsw.c powsw
+
device rtc
attach rtc at intio
file arch/x68k/dev/rtclock.c rtc
Added files:
Index: src/share/man/man4/man4.x68k/powsw.4
diff -u /dev/null src/share/man/man4/man4.x68k/powsw.4:1.1
--- /dev/null Sun Nov 27 09:00:33 2011
+++ src/share/man/man4/man4.x68k/powsw.4 Sun Nov 27 09:00:33 2011
@@ -0,0 +1,55 @@
+.\" $NetBSD: powsw.4,v 1.1 2011/11/27 09:00:33 isaki Exp $
+.\"
+.\" Copyright (c) 2011 Tetsuya Isaki. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+.\" BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+.\" AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+.\" OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.Dd November 27, 2011
+.Dt POWSW 4 x68k
+.Os
+.Sh NAME
+.Nm powsw
+.Nd x68k power switch handler
+.Sh SYNOPSIS
+.Cd powsw0 at mfp0
+.Cd powsw1 at mfp0
+.Sh DESCRIPTION
+The
+.Nm
+driver monitors x68k's power switch,
+and is made as interface to
+.Xr sysmon_pswitch 9 .
+.Pp
+.Nm powsw0
+monitors a front switch.
+.Nm powsw1
+monitors an external power switch (EXPWON signal in I/O slot).
+.Sh SEE ALSO
+.Xr powerd 8
+.Sh HISTORY
+.Nm
+appeared in
+.Nx 6.0 .
+.Sh BUGS
+I have no idea for
+.Nm powsw2
+(rtc alarm).
Index: src/sys/arch/x68k/dev/powsw.c
diff -u /dev/null src/sys/arch/x68k/dev/powsw.c:1.1
--- /dev/null Sun Nov 27 09:00:33 2011
+++ src/sys/arch/x68k/dev/powsw.c Sun Nov 27 09:00:32 2011
@@ -0,0 +1,290 @@
+/* $NetBSD: powsw.c,v 1.1 2011/11/27 09:00:32 isaki Exp $ */
+
+/*
+ * Copyright (c) 2011 Tetsuya Isaki. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Power switch monitor
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: powsw.c,v 1.1 2011/11/27 09:00:32 isaki Exp $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/conf.h>
+#include <sys/device.h>
+#include <sys/intr.h>
+#include <sys/callout.h>
+
+#include <machine/bus.h>
+#include <machine/cpu.h>
+
+#include <arch/x68k/dev/intiovar.h>
+#include <arch/x68k/dev/mfp.h>
+
+#include <dev/sysmon/sysmonvar.h>
+#include <dev/sysmon/sysmon_taskq.h>
+
+extern int power_switch_is_off; /* XXX should be in .h */
+
+//#define POWSW_DEBUG
+
+#if defined(POWSW_DEBUG)
+#define DPRINTF(fmt...) printf(fmt)
+#define DEBUG_LOG_ADD(c) sc->sc_log[sc->sc_loglen++] = (c)
+#define DEBUG_LOG_PRINT() do { \
+ sc->sc_log[sc->sc_loglen] = '\0'; \
+ printf("%s", sc->sc_log); \
+} while (0)
+#else
+#define DPRINTF(fmt...)
+#define DEBUG_LOG_ADD(c)
+#define DEBUG_LOG_PRINT()
+#endif
+
+/* mask */
+#define POWSW_ALARM (0x01)
+#define POWSW_EXTERNAL (0x02)
+#define POWSW_FRONT (0x04)
+
+/* parameter */
+#define POWSW_MAX_TICK (30)
+#define POWSW_THRESHOLD (10)
+
+struct powsw_softc {
+ device_t sc_dev;
+ struct sysmon_pswitch sc_smpsw;
+ callout_t sc_callout;
+ int sc_mask;
+ int sc_prev;
+ int sc_last_sw;
+ int sc_tick;
+ int sc_count;
+#if defined(POWSW_DEBUG)
+ char sc_log[100];
+ int sc_loglen;
+#endif
+};
+
+extern struct cfdriver powsw_cd;
+
+static int powsw_match(device_t, cfdata_t, void *);
+static void powsw_attach(device_t, device_t, void *);
+static int powsw_intr(void *);
+static void powsw_softintr(void *);
+static void powsw_pswitch_event(void *);
+static void powsw_shutdown_check(void *);
+static void powsw_reset_counter(struct powsw_softc *);
+static void powsw_set_aer(struct powsw_softc *, int);
+
+CFATTACH_DECL_NEW(powsw, sizeof(struct powsw_softc),
+ powsw_match, powsw_attach, NULL, NULL);
+
+
+typedef const struct {
+ int vector; /* interrupt vector */
+ int mask; /* mask bit for MFP GPIP */
+ const char *name;
+} powsw_desc_t;
+
+static powsw_desc_t powsw_desc[2] = {
+ { 66, POWSW_FRONT, "Front Switch", },
+ { 65, POWSW_EXTERNAL, "External Power Switch", },
+ /* XXX I'm not sure about alarm bit */
+};
+
+
+static int
+powsw_match(device_t parent, cfdata_t cf, void *aux)
+{
+ return 1;
+}
+
+static void
+powsw_attach(device_t parent, device_t self, void *aux)
+{
+ struct powsw_softc *sc = device_private(self);
+ powsw_desc_t *desc;
+ const char *xname;
+ int unit;
+ int sw;
+
+ unit = device_unit(self);
+ xname = device_xname(self);
+ desc = &powsw_desc[unit];
+
+ memset(sc, 0, sizeof(*sc));
+ sc->sc_dev = self;
+ sc->sc_mask = desc->mask;
+ sc->sc_prev = -1;
+ powsw_reset_counter(sc);
+
+ sysmon_task_queue_init();
+ sc->sc_smpsw.smpsw_name = xname;
+ sc->sc_smpsw.smpsw_type = PSWITCH_TYPE_POWER;
+ if (sysmon_pswitch_register(&sc->sc_smpsw) != 0)
+ panic("can't register with sysmon");
+
+ callout_init(&sc->sc_callout, 0);
+ callout_setfunc(&sc->sc_callout, powsw_softintr, sc);
+
+ if (shutdownhook_establish(powsw_shutdown_check, sc) == NULL)
+ panic("%s: can't establish shutdown hook", xname);
+
+ if (intio_intr_establish(desc->vector, xname, powsw_intr, sc) < 0)
+ panic("%s: can't establish interrupt", xname);
+
+ /* Set AER and enable interrupt */
+ sw = (mfp_get_gpip() & sc->sc_mask);
+ powsw_set_aer(sc, sw ? 0 : 1);
+ mfp_bit_set_ierb(sc->sc_mask);
+
+ aprint_normal(": %s\n", desc->name);
+}
+
+static int
+powsw_intr(void *arg)
+{
+ struct powsw_softc *sc = arg;
+
+ if (sc->sc_tick == 0) {
+ mfp_bit_clear_ierb(sc->sc_mask);
+ sc->sc_tick++;
+ DEBUG_LOG_ADD('i');
+ /*
+ * The button state seems unstable for few ticks,
+ * so wait a bit to settle.
+ */
+ callout_schedule(&sc->sc_callout, 1);
+ } else {
+ DEBUG_LOG_ADD('x');
+ }
+ return 0;
+}
+
+void
+powsw_softintr(void *arg)
+{
+ struct powsw_softc *sc = arg;
+ int sw;
+ int s;
+
+ s = spl6();
+
+ if (sc->sc_tick++ >= POWSW_MAX_TICK) {
+ /* tick is over, broken switch? */
+ printf("%s: unstable power switch?, ignored\n",
+ device_xname(sc->sc_dev));
+ powsw_reset_counter(sc);
+
+ mfp_bit_set_ierb(sc->sc_mask);
+ splx(s);
+ return;
+ }
+
+ sw = (mfp_get_gpip() & sc->sc_mask) ? 1 : 0;
+ DEBUG_LOG_ADD('0' + sw);
+
+ if (sw == sc->sc_last_sw) {
+ sc->sc_count++;
+ } else {
+ sc->sc_last_sw = sw;
+ sc->sc_count = 1;
+ }
+
+ if (sc->sc_count < POWSW_THRESHOLD) {
+ callout_schedule(&sc->sc_callout, 1);
+ } else {
+ /* switch seems stable */
+ DEBUG_LOG_PRINT();
+
+ if (sc->sc_last_sw == sc->sc_prev) {
+ /* switch state is not changed, it was a noise */
+ DPRINTF(" ignore(sw=%d,prev=%d)\n", sc->sc_last_sw, sc->sc_prev);
+ } else {
+ /* switch state has been changed */
+ sc->sc_prev = sc->sc_last_sw;
+ powsw_set_aer(sc, 1 - sc->sc_prev);
+ sysmon_task_queue_sched(0, powsw_pswitch_event, sc);
+ }
+ powsw_reset_counter(sc);
+ mfp_bit_set_ierb(sc->sc_mask); // enable interrupt
+ }
+
+ splx(s);
+}
+
+static void
+powsw_pswitch_event(void *arg)
+{
+ struct powsw_softc *sc = arg;
+ int poweroff;
+
+ poweroff = sc->sc_prev;
+
+ DPRINTF(" %s is %s\n", device_xname(sc->sc_dev),
+ poweroff ? "off(PRESS)" : "on(RELEASE)");
+
+ sysmon_pswitch_event(&sc->sc_smpsw,
+ poweroff ? PSWITCH_EVENT_PRESSED : PSWITCH_EVENT_RELEASED);
+}
+
+static void
+powsw_shutdown_check(void *arg)
+{
+ struct powsw_softc *sc = arg;
+ int poweroff;
+
+ poweroff = sc->sc_prev;
+ if (poweroff)
+ power_switch_is_off = 1;
+ DPRINTF("powsw_shutdown_check %s = %d\n",
+ device_xname(sc->sc_dev), power_switch_is_off);
+}
+
+static void
+powsw_reset_counter(struct powsw_softc *sc)
+{
+ sc->sc_last_sw = -1;
+ sc->sc_tick = 0;
+ sc->sc_count = 0;
+#if defined(POWSW_DEBUG)
+ sc->sc_loglen = 0;
+#endif
+}
+
+static void
+powsw_set_aer(struct powsw_softc *sc, int aer)
+{
+ KASSERT(aer == 0 || aer == 1);
+
+ if (aer == 0) {
+ mfp_bit_clear_aer(sc->sc_mask);
+ } else {
+ mfp_bit_set_aer(sc->sc_mask);
+ }
+ DPRINTF(" SetAER=%d", aer);
+}