Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/i386/i386 Keep track of current power state (resume...



details:   https://anonhg.NetBSD.org/src/rev/d7b1d75a4a96
branches:  trunk
changeset: 485448:d7b1d75a4a96
user:      thorpej <thorpej%NetBSD.org@localhost>
date:      Fri Apr 28 04:48:51 2000 +0000

description:
Keep track of current power state (resumed, standing by, suspended), and
only perform standby/suspend/resume actions if the state actually changes.

Inspired by some similar code in the USB code, pulled into here so that
the workaround isn't needed in every driver.

diffstat:

 sys/arch/i386/i386/apm.c |  51 ++++++++++++++++++++++++++++++++++++++++-------
 1 files changed, 43 insertions(+), 8 deletions(-)

diffs (119 lines):

diff -r 24a094d6eeca -r d7b1d75a4a96 sys/arch/i386/i386/apm.c
--- a/sys/arch/i386/i386/apm.c  Fri Apr 28 03:48:56 2000 +0000
+++ b/sys/arch/i386/i386/apm.c  Fri Apr 28 04:48:51 2000 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: apm.c,v 1.47 2000/04/21 18:37:20 thorpej Exp $ */
+/*     $NetBSD: apm.c,v 1.48 2000/04/28 04:48:51 thorpej Exp $ */
 
 /*-
  * Copyright (c) 1996, 1997 The NetBSD Foundation, Inc.
@@ -111,6 +111,7 @@
        int     sc_flags;
        int     event_count;
        int     event_ptr;
+       int     sc_power_state;
        struct proc *sc_thread;
        struct lock sc_lock;
        struct  apm_event_info event_list[APM_NEVENTS];
@@ -161,9 +162,9 @@
 static int     apm_record_event __P((struct apm_softc *, u_int));
 static void    apm_get_capabilities __P((void));
 static void    apm_set_ver __P((struct apm_softc *));
-static void    apm_standby __P((void));
+static void    apm_standby __P((struct apm_softc *));
 static const char *apm_strerror __P((int));
-static void    apm_suspend __P((void));
+static void    apm_suspend __P((struct apm_softc *));
 static void    apm_resume __P((struct apm_softc *, struct bioscallregs *));
 
 cdev_decl(apm);
@@ -375,8 +376,19 @@
 #endif
 
 static void
-apm_suspend()
+apm_suspend(sc)
+       struct apm_softc *sc;
 {
+
+       if (sc->sc_power_state == PWR_SUSPEND) {
+#ifdef APMDEBUG
+               printf("%s: apm_suspend: already suspended?\n",
+                   sc->sc_dev.dv_xname);
+#endif
+               return;
+       }
+       sc->sc_power_state = PWR_SUSPEND;
+
        dopowerhooks(PWR_SUSPEND);
 
        /* XXX cgd */
@@ -384,8 +396,19 @@
 }
 
 static void
-apm_standby()
+apm_standby(sc)
+       struct apm_softc *sc;
 {
+
+       if (sc->sc_power_state == PWR_STANDBY) {
+#ifdef APMDEBUG
+               printf("%s: apm_standby: already standing by?\n",
+                   sc->sc_dev.dv_xname);
+#endif
+               return;
+       }
+       sc->sc_power_state = PWR_STANDBY;
+
        dopowerhooks(PWR_STANDBY);
 
        /* XXX cgd */
@@ -398,6 +421,15 @@
        struct bioscallregs *regs;
 {
 
+       if (sc->sc_power_state == PWR_RESUME) {
+#ifdef APMDEBUG
+               printf("%s: apm_resume: already running?\n",
+                   sc->sc_dev.dv_xname);
+#endif
+               return;
+       }
+       sc->sc_power_state = PWR_RESUME;
+
        /*
         * Some system requires its clock to be initialized after hybernation.
         */
@@ -538,7 +570,7 @@
        case APM_CRIT_SUSPEND_REQ:
                DPRINTF(APMDEBUG_EVENTS, ("apmev: critical system suspend\n"));
                apm_record_event(sc, regs->BX);
-               apm_suspend();
+               apm_suspend(sc);
                break;
 
        case APM_BATTERY_LOW:
@@ -604,10 +636,10 @@
                apm_perror("get event", &regs);
        if (apm_suspends) {
                apm_op_inprog = 0;
-               apm_suspend();
+               apm_suspend(sc);
        } else if (apm_standbys || apm_userstandbys) {
                apm_op_inprog = 0;
-               apm_standby();
+               apm_standby(sc);
        }
        apm_suspends = apm_standbys = apm_battlow = apm_userstandbys = 0;
        apm_damn_fool_bios = 0;
@@ -1260,6 +1292,9 @@
 
        lockinit(&apmsc->sc_lock, PWAIT, "apmlk", 0, 0);
 
+       /* Initial state is `resumed'. */
+       apmsc->sc_power_state = PWR_RESUME;
+
        /* Do an initial check. */
        apm_periodic_check(apmsc);
 



Home | Main Index | Thread Index | Old Index