split pow(4)
Tetsuya Isaki <[email protected]> Sun, 06 Nov 2011 19:09:53 +0900
| Newsgroups | gmane.os.netbsd.ports.x68k |
|---|---|
| Message-ID | <x7vcqxzhn2.wl%[email protected]> |
I have a plan to split a complex pow(4) device into two devices: o pow(4): return to pseudo-device. It is for ioctl for rtcalarm(1). No power switch monitoring part. o powsw(4): added newly. It is for power switch monitoring. No (rtcalarm-related) ioctl part. This makes each device simple. At this time, just split into two devices (two files), no feature changes (= there is no improvement and no demerit, I think..) and no user visible changes. See attached patch. As the next step, I'm going to improve them: o powsw(4): split into front switch and external switch. o powsw(4): avoid chattering on power switch. o powsw(4): support not only PSWITCH_EVENT_PRESSED but also PSWITCH_EVENT_RELEASED. o make pow(4) and rtcalarm(1) ioctl work again. Any comments? I'll commit it next weekend if no (negative) comments. --- Tetsuya Isaki <[email protected] / [email protected]> Index: sys/arch/x68k/dev/pow.c =================================================================== RCS file: /cvsroot/src/sys/arch/x68k/dev/pow.c,v retrieving revision 1.23 diff -u -u -r1.23 pow.c --- sys/arch/x68k/dev/pow.c 18 Jan 2009 04:48:53 -0000 1.23 +++ sys/arch/x68k/dev/pow.c 6 Nov 2011 06:40:42 -0000 @@ -32,9 +32,7 @@ /* * Power switch device driver. - * Useful for - * 1. accessing boot information. - * 2. looking at the front or external power switch. + * Useful for accessing boot information. */ #include <sys/cdefs.h> @@ -42,18 +40,11 @@ #include <sys/param.h> #include <sys/systm.h> -#include <sys/device.h> #include <sys/ioctl.h> -#include <sys/time.h> #include <sys/kernel.h> #include <sys/fcntl.h> -#include <sys/signalvar.h> #include <sys/conf.h> #include <sys/bus.h> -#include <sys/device.h> - -#include <dev/sysmon/sysmonvar.h> -#include <dev/sysmon/sysmon_taskq.h> #include <machine/cpu.h> #include <machine/powioctl.h> @@ -61,23 +52,15 @@ #include <x68k/dev/mfp.h> #include <x68k/dev/powvar.h> #include <x68k/x68k/iodevice.h> +#include "pow.h" #define sramtop (IODEVbase->io_sram) #define rtc (IODEVbase->io_rtc) -extern struct cfdriver pow_cd; +struct pow_softc pows[NPOW]; -static int pow_match(device_t, cfdata_t, void *); -static void pow_attach(device_t, device_t, void *); -static int powintr(void *); +void powattach(int); static int setalarm(struct x68k_alarminfo *); -static void pow_pressed_event(void *); -static void pow_check_switch(void *); - -CFATTACH_DECL_NEW(pow, sizeof(struct pow_softc), - pow_match, pow_attach, NULL, NULL); - -static int pow_attached; dev_type_open(powopen); dev_type_close(powclose); @@ -88,56 +71,27 @@ nostop, notty, nopoll, nommap, nokqfilter, }; -static int -pow_match(device_t parent, cfdata_t cf, void *aux) +void +powattach(int num) { - if (pow_attached) - return 0; - - return 1; -} + int minor; + int sw; -static void -pow_attach(device_t parent, device_t self, void *aux) -{ - struct pow_softc *sc = device_private(self); - struct mfp_softc *mfp = device_private(parent); + sw = ~mfp_get_gpip() & 7; - sc->sw = ~mfp_get_gpip() & 7; - /* disable mfp power switch interrupt */ - mfp_bit_clear_ierb(7); - mfp_bit_clear_aer(7); - - sc->status = POW_FREE; - - if (sc->sw) { - mfp_bit_set_aer(sc->sw); - mfp_bit_set_ierb(sc->sw); + for (minor = 0; minor < num; minor++) { + pows[minor].status = POW_FREE; + pows[minor].sw = sw; } - sysmon_task_queue_init(); - sc->smpsw.smpsw_name = device_xname(self); - sc->smpsw.smpsw_type = PSWITCH_TYPE_POWER; - if (sysmon_pswitch_register(&sc->smpsw) != 0) - panic("can't register with sysmon"); - - /* MFP interrupt #1 for ext, #2 for front power switch */ - if (intio_intr_establish(mfp->sc_intr + 1, "powext", powintr, sc) < 0) - panic("%s: can't establish interrupt", device_xname(self)); - if (intio_intr_establish(mfp->sc_intr + 2, "powfrt", powintr, sc) < 0) - panic("%s: can't establish interrupt", device_xname(self)); - - shutdownhook_establish(pow_check_switch, 0); - - printf("\n"); - printf("%s: started by ", device_xname(self)); - if (sc->sw & POW_EXTERNALSW) + printf("pow: started by "); + if (sw & POW_EXTERNALSW) printf("external power switch.\n"); - else if (sc->sw & POW_FRONTSW) + else if (sw & POW_FRONTSW) printf("front power switch.\n"); /* XXX: I don't know why POW_ALARMSW should not be checked */ #if 0 - else if ((sc->sw & POW_ALARMSW) && sramtop[0x26] == 0) + else if ((sw & POW_ALARMSW) && sramtop[0x26] == 0) printf("RTC alarm.\n"); else printf("???.\n"); @@ -145,8 +99,6 @@ else printf("RTC alarm.\n"); #endif - - pow_attached = 1; } @@ -154,10 +106,9 @@ int powopen(dev_t dev, int flags, int mode, struct lwp *l) { - struct pow_softc *sc; + struct pow_softc *sc = &pows[minor(dev)]; - sc = device_lookup_private(&pow_cd, minor(dev)); - if (sc == NULL) + if (minor(dev) >= NPOW) return ENXIO; if (sc->status == POW_BUSY) @@ -175,11 +126,7 @@ int powclose(dev_t dev, int flags, int mode, struct lwp *l) { - struct pow_softc *sc; - - sc = device_lookup_private(&pow_cd, minor(dev)); - if (sc == NULL) - return ENXIO; + struct pow_softc *sc = &pows[minor(dev)]; if (sc->status == POW_BUSY) sc->status = POW_FREE; @@ -260,11 +207,7 @@ int powioctl(dev_t dev, u_long cmd, void *addr, int flag, struct lwp *l) { - struct pow_softc *sc; - - sc = device_lookup_private(&pow_cd, minor(dev)); - if (sc == NULL) - return ENXIO; + struct pow_softc *sc = &pows[minor(dev)]; switch (cmd) { case POWIOCGPOWERINFO: @@ -303,35 +246,3 @@ return 0; } - -static int -powintr(void *arg) -{ - struct pow_softc *sc = arg; - int sw; - - sw = ~mfp_get_gpip() & 6; - mfp_bit_clear_aer(sw); - mfp_bit_set_ierb(sw); - - sysmon_task_queue_sched(0, pow_pressed_event, sc); - - return 0; -} - -static void -pow_pressed_event(void *arg) -{ - struct pow_softc *sc = arg; - - sysmon_pswitch_event(&sc->smpsw, PSWITCH_EVENT_PRESSED); -} - -static void -pow_check_switch(void *dummy) -{ - extern int power_switch_is_off; - - if ((~mfp_get_gpip() & (POW_FRONTSW | POW_EXTERNALSW)) == 0) - power_switch_is_off = 1; -} Index: sys/arch/x68k/dev/powvar.h =================================================================== RCS file: /cvsroot/src/sys/arch/x68k/dev/powvar.h,v retrieving revision 1.4 diff -u -r1.4 powvar.h --- sys/arch/x68k/dev/powvar.h 20 Dec 2008 13:20:59 -0000 1.4 +++ sys/arch/x68k/dev/powvar.h 6 Nov 2011 07:00:30 -0000 @@ -40,5 +40,4 @@ short status; short rw; int sw; - struct sysmon_pswitch smpsw; }; --- /dev/null 2011-11-06 15:49:02.000000000 +0900 +++ sys/arch/x68k/dev/powsw.c 2011-11-06 15:06:57.000000000 +0900 @@ -0,0 +1,167 @@ +/* $NetBSD$ */ + +/* + * Copyright (c) 1995 MINOURA Makoto. + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Minoura Makoto. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission + * + * 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. + */ + +/* + * 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 device driver. + * Looking at the front or external power switch. + */ + +#include <sys/cdefs.h> +__KERNEL_RCSID(0, "$NetBSD$"); + +#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 <dev/sysmon/sysmonvar.h> +#include <dev/sysmon/sysmon_taskq.h> + +#include <machine/bus.h> +#include <machine/cpu.h> +#include <machine/powioctl.h> +#include <x68k/dev/intiovar.h> +#include <x68k/dev/mfp.h> + +struct powsw_softc { + int sw; + struct sysmon_pswitch smpsw; +}; + +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_pressed_event(void *); +static void powsw_check_switch(void *); + +CFATTACH_DECL_NEW(powsw, sizeof(struct powsw_softc), + powsw_match, powsw_attach, NULL, NULL); + +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); + struct mfp_softc *mfp = device_private(parent); + + sc->sw = ~mfp_get_gpip() & 7; + /* disable mfp power switch interrupt */ + mfp_bit_clear_ierb(7); + mfp_bit_clear_aer(7); + + if (sc->sw) { + mfp_bit_set_aer(sc->sw); + mfp_bit_set_ierb(sc->sw); + } + + sysmon_task_queue_init(); + sc->smpsw.smpsw_name = device_xname(self); + sc->smpsw.smpsw_type = PSWITCH_TYPE_POWER; + if (sysmon_pswitch_register(&sc->smpsw) != 0) + panic("can't register with sysmon"); + + /* MFP interrupt #1 for ext, #2 for front power switch */ + if (intio_intr_establish(mfp->sc_intr + 1, "powext", powsw_intr, sc) < 0) + panic("%s: can't establish interrupt", device_xname(self)); + if (intio_intr_establish(mfp->sc_intr + 2, "powfrt", powsw_intr, sc) < 0) + panic("%s: can't establish interrupt", device_xname(self)); + + shutdownhook_establish(powsw_check_switch, 0); + + printf("\n"); +} + +static int +powsw_intr(void *arg) +{ + struct powsw_softc *sc = arg; + int sw; + + sw = ~mfp_get_gpip() & 6; + mfp_bit_clear_aer(sw); + mfp_bit_set_ierb(sw); + + sysmon_task_queue_sched(0, powsw_pressed_event, sc); + + return 0; +} + +static void +powsw_pressed_event(void *arg) +{ + struct powsw_softc *sc = arg; + + sysmon_pswitch_event(&sc->smpsw, PSWITCH_EVENT_PRESSED); +} + +static void +powsw_check_switch(void *dummy) +{ + extern int power_switch_is_off; + + if ((~mfp_get_gpip() & (POW_FRONTSW | POW_EXTERNALSW)) == 0) + power_switch_is_off = 1; +} Index: sys/arch/x68k/conf/files.x68k =================================================================== RCS file: /cvsroot/src/sys/arch/x68k/conf/files.x68k,v retrieving revision 1.74 diff -u -r1.74 files.x68k --- sys/arch/x68k/conf/files.x68k 12 Jun 2011 03:35:49 -0000 1.74 +++ sys/arch/x68k/conf/files.x68k 6 Nov 2011 06:46:14 -0000 @@ -96,9 +96,9 @@ attach kbd at mfp file arch/x68k/dev/kbd.c kbd needs-flag -device pow: sysmon_power, sysmon_taskq -attach pow at mfp -file arch/x68k/dev/pow.c pow +device powsw: sysmon_power, sysmon_taskq +attach powsw at mfp +file arch/x68k/dev/powsw.c powsw device rtc attach rtc at intio @@ -172,6 +172,9 @@ defpseudo bell file arch/x68k/dev/opmbell.c bell needs-flag +defpseudo pow +file arch/x68k/dev/pow.c pow needs-count + # Nereid Ethernet attach ne at intio with ne_intio: rtl80x9 file arch/x68k/dev/if_ne_intio.c ne_intio Index: sys/arch/x68k/conf/GENERIC =================================================================== RCS file: /cvsroot/src/sys/arch/x68k/conf/GENERIC,v retrieving revision 1.155 diff -u -r1.155 GENERIC --- sys/arch/x68k/conf/GENERIC 17 Mar 2011 13:26:51 -0000 1.155 +++ sys/arch/x68k/conf/GENERIC 6 Nov 2011 06:55:11 -0000 @@ -252,7 +252,7 @@ ite0 at grf0 grfaddr 0 # internal terminal emulator options ITE_KERNEL_ATTR=4 # bold for kernel messages # see /sys/arch/x68k/dev/itevar.h -pow0 at mfp0 # software power switch +powsw0 at mfp0 # software power switch ## floppy disks fdc0 at intio0 addr 0xe94000 intr 96 dma 0 dmaintr 100 # floppy controller @@ -287,6 +287,7 @@ par0 at intio0 addr 0xe8c000 # Builtin printer port sram0 at intio0 addr 0xed0000 # battery-backuped static RAM +pseudo-device pow 2 # boot and alarm information pseudo-device bell # OPM bell xcom0 at mainbus0 # NS16550 fast serial Index: sys/arch/x68k/conf/INSTALL =================================================================== RCS file: /cvsroot/src/sys/arch/x68k/conf/INSTALL,v retrieving revision 1.91 diff -u -r1.91 INSTALL --- sys/arch/x68k/conf/INSTALL 6 Mar 2011 17:08:33 -0000 1.91 +++ sys/arch/x68k/conf/INSTALL 6 Nov 2011 06:56:30 -0000 @@ -223,7 +223,7 @@ ite0 at grf0 grfaddr 0 # internal terminal emulator options ITE_KERNEL_ATTR=4 # bold for kernel messages # see /sys/arch/x68k/dev/itevar.h -#pow0 at mfp0 # software power switch +#powsw0 at mfp0 # software power switch ## floppy disks fdc0 at intio0 addr 0xe94000 intr 96 dma 0 dmaintr 100 # floppy controller