Source-Changes-HG archive

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

[src/trunk]: src/sys/arch/macppc/dev report the power button to sysmon when p...



details:   https://anonhg.NetBSD.org/src/rev/25bafb86b37b
branches:  trunk
changeset: 345583:25bafb86b37b
user:      macallan <macallan%NetBSD.org@localhost>
date:      Wed Jun 01 05:27:40 2016 +0000

description:
report the power button to sysmon when possible

diffstat:

 sys/arch/macppc/dev/pmu.c    |  86 ++++++++++++++++++++++++++++++++-----------
 sys/arch/macppc/dev/pmuvar.h |   3 +-
 2 files changed, 66 insertions(+), 23 deletions(-)

diffs (230 lines):

diff -r a50549da99e9 -r 25bafb86b37b sys/arch/macppc/dev/pmu.c
--- a/sys/arch/macppc/dev/pmu.c Wed Jun 01 05:13:07 2016 +0000
+++ b/sys/arch/macppc/dev/pmu.c Wed Jun 01 05:27:40 2016 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: pmu.c,v 1.26 2016/05/31 03:50:30 macallan Exp $ */
+/*     $NetBSD: pmu.c,v 1.27 2016/06/01 05:27:40 macallan Exp $ */
 
 /*-
  * Copyright (c) 2006 Michael Lorenz
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pmu.c,v 1.26 2016/05/31 03:50:30 macallan Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pmu.c,v 1.27 2016/06/01 05:27:40 macallan Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -35,6 +35,7 @@
 #include <sys/device.h>
 #include <sys/proc.h>
 #include <sys/kthread.h>
+#include <sys/atomic.h>
 
 #include <sys/bus.h>
 #include <machine/pio.h>
@@ -70,6 +71,13 @@
 
 static int pmu_intr(void *);
 
+
+/* bits for sc_pending, as signals to the event thread */
+#define PMU_EV_CARD0   1
+#define PMU_EV_CARD1   2
+#define PMU_EV_BUTTON  4
+#define PMU_EV_LID     8
+
 struct pmu_softc {
        device_t sc_dev;
        void *sc_ih;
@@ -78,6 +86,7 @@
        struct i2c_controller sc_i2c;
        struct pmu_ops sc_pmu_ops;
        struct sysmon_pswitch sc_lidswitch;
+       struct sysmon_pswitch sc_powerbutton;
        bus_space_tag_t sc_memt;
        bus_space_handle_t sc_memh;
        uint32_t sc_flags;
@@ -86,13 +95,15 @@
        int sc_iic_done;
        int sc_error;
        int sc_autopoll;
-       int sc_pending_eject;
        int sc_brightness, sc_brightness_wanted;
        int sc_volume, sc_volume_wanted;
        int sc_lid_closed;
-       int sc_pswitch_pending;
+       int sc_button;
+       uint8_t sc_env_old;
+       uint8_t sc_env_mask;
        /* deferred processing */
        lwp_t *sc_thread;
+       int sc_pending;
        /* signalling the event thread */
        int sc_event;
        /* ADB */
@@ -261,7 +272,7 @@
        int type = IST_EDGE;
        uint8_t cmd[2] = {2, 0};
        uint8_t resp[16];
-       char name[256];
+       char name[256], model[32];
 
        extint_node = of_getnode_byname(OF_parent(ca->ca_node), "extint-gpio1");
        if (extint_node) {
@@ -280,13 +291,27 @@
 
        sc->sc_error = 0;
        sc->sc_autopoll = 0;
-       sc->sc_pending_eject = 0;
+       sc->sc_pending = 0;
+       sc->sc_env_old = 0;
        sc->sc_brightness = sc->sc_brightness_wanted = 0x80;
        sc->sc_volume = sc->sc_volume_wanted = 0x80;
        sc->sc_flags = 0;
        sc->sc_callback = NULL;
        sc->sc_lid_closed = 0;
-       sc->sc_pswitch_pending = 0;
+       sc->sc_button = 0;
+       sc->sc_env_mask = 0xff;
+
+       /*
+        * core99 PowerMacs like to send environment messages with the lid
+        * switch bit set - since that doesn't make any sense here and it
+        * probably means something else anyway we mask it out
+        */
+
+       if (OF_getprop(root_node, "model", model, 32) != 0) {
+               if (strncmp(model, "PowerMac", 8) == 0) {
+                       sc->sc_env_mask = PMU_ENV_POWER_BUTTON;
+               }
+       }
 
        if (bus_space_map(sc->sc_memt, ca->ca_reg[0] + ca->ca_baseaddr,
            ca->ca_reg[1], 0, &sc->sc_memh) != 0) {
@@ -411,6 +436,12 @@
        if (sysmon_pswitch_register(&sc->sc_lidswitch) != 0)
                aprint_error_dev(self,
                    "unable to register lid switch with sysmon\n");
+
+       sc->sc_powerbutton.smpsw_name = "Power button";
+       sc->sc_powerbutton.smpsw_type = PSWITCH_TYPE_POWER;
+       if (sysmon_pswitch_register(&sc->sc_powerbutton) != 0)
+               aprint_error_dev(self,
+                   "unable to register power button with sysmon\n");
 }
 
 static void
@@ -636,7 +667,7 @@
        if (resp[1] & PMU_INT_PCEJECT) {
                /* deal with PCMCIA eject buttons */
                DPRINTF("card eject %d\n", resp[3]);
-               sc->sc_pending_eject |= (resp[3] & 3);
+               atomic_or_32(&sc->sc_pending, (resp[3] & 3));
                wakeup(&sc->sc_event);
                goto done;
        }
@@ -649,7 +680,7 @@
                goto done;
        }
        if (resp[1] & PMU_INT_ENVIRONMENT) {
-               int closed;
+               uint8_t diff;
 #ifdef PMU_VERBOSE
                /* deal with environment messages */
                printf("environment:");
@@ -657,10 +688,17 @@
                        printf(" %02x", resp[i]);
                printf("\n");
 #endif
-               closed = (resp[2] & PMU_ENV_LID_CLOSED) != 0;
-               if (closed != sc->sc_lid_closed) {
-                       sc->sc_lid_closed = closed;
-                       sc->sc_pswitch_pending = 1;
+               diff = (resp[2] ^ sc->sc_env_old ) & sc->sc_env_mask;
+               if (diff == 0) goto done;
+               sc->sc_env_old = resp[2];
+               if (diff & PMU_ENV_LID_CLOSED) {
+                       sc->sc_lid_closed = (resp[2] & PMU_ENV_LID_CLOSED) != 0;
+                       atomic_or_32(&sc->sc_pending, PMU_EV_LID);
+                       wakeup(&sc->sc_event);
+               }
+               if (diff & PMU_ENV_POWER_BUTTON) {
+                       sc->sc_button = (resp[2] & PMU_ENV_POWER_BUTTON) != 0;
+                       atomic_or_32(&sc->sc_pending, PMU_EV_BUTTON);
                        wakeup(&sc->sc_event);
                }
                goto done;
@@ -936,13 +974,10 @@
 static void
 pmu_eject_card(struct pmu_softc *sc, int socket)
 {
-       int s;
        uint8_t buf[] = {socket | 4};
        uint8_t res[4];
 
-       s = splhigh();
-       sc->sc_pending_eject &= ~socket;
-       splx(s);
+       atomic_and_32(&sc->sc_pending, ~socket);
        pmu_send(sc, PMU_EJECT_PCMCIA, 1, buf, 4, res);
 }
 
@@ -1003,10 +1038,10 @@
        
        while (1) {
                tsleep(&sc->sc_event, PWAIT, "wait", ticks);
-               if (sc->sc_pending_eject != 0) {
-                       DPRINTF("eject %d\n", sc->sc_pending_eject);
+               if ((sc->sc_pending & 3) != 0) {
+                       DPRINTF("eject %d\n", sc->sc_pending & 3);
                        for (i = 1; i < 3; i++) {
-                               if (i & sc->sc_pending_eject)
+                               if (i & sc->sc_pending)
                                        pmu_eject_card(sc, i);
                        }
                }
@@ -1024,13 +1059,20 @@
                        sc->sc_volume = sc->sc_volume_wanted;
                }
 
-               if (sc->sc_pswitch_pending) {
-                       sc->sc_pswitch_pending = 0;
+               if (sc->sc_pending & PMU_EV_LID) {
+                       atomic_and_32(&sc->sc_pending, ~PMU_EV_LID);
                        sysmon_pswitch_event(&sc->sc_lidswitch, 
                            sc->sc_lid_closed ? PSWITCH_EVENT_PRESSED : 
                            PSWITCH_EVENT_RELEASED);
                }
 
+               if (sc->sc_pending & PMU_EV_BUTTON) {
+                       atomic_and_32(&sc->sc_pending, ~PMU_EV_BUTTON);
+                       sysmon_pswitch_event(&sc->sc_powerbutton, 
+                           sc->sc_button ? PSWITCH_EVENT_PRESSED : 
+                           PSWITCH_EVENT_RELEASED);
+               }
+
                if (sc->sc_callback != NULL)
                        sc->sc_callback(sc->sc_cb_cookie);
        }
diff -r a50549da99e9 -r 25bafb86b37b sys/arch/macppc/dev/pmuvar.h
--- a/sys/arch/macppc/dev/pmuvar.h      Wed Jun 01 05:13:07 2016 +0000
+++ b/sys/arch/macppc/dev/pmuvar.h      Wed Jun 01 05:27:40 2016 +0000
@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pmuvar.h,v 1.8 2010/11/09 20:44:49 macallan Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pmuvar.h,v 1.9 2016/06/01 05:27:40 macallan Exp $");
 
 #ifndef PMUVAR_H
 #define PMUVAR_H
@@ -99,6 +99,7 @@
 
 /* Bits from PMU_GET_LID_STATE or PMU_INT_ENVIRONMENT on core99 */
 #define PMU_ENV_LID_CLOSED     0x01    /* The lid is closed */
+#define PMU_ENV_POWER_BUTTON   0x08    /* power button on ADB-less Macs */
 
 /* PMU PMU_POWER_EVENTS commands */
 enum {



Home | Main Index | Thread Index | Old Index