Module Name: src Committed By: macallan Date: Wed Jun 1 05:27:40 UTC 2016
Modified Files: src/sys/arch/macppc/dev: pmu.c pmuvar.h Log Message: report the power button to sysmon when possible To generate a diff of this commit: cvs rdiff -u -r1.26 -r1.27 src/sys/arch/macppc/dev/pmu.c cvs rdiff -u -r1.8 -r1.9 src/sys/arch/macppc/dev/pmuvar.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/macppc/dev/pmu.c diff -u src/sys/arch/macppc/dev/pmu.c:1.26 src/sys/arch/macppc/dev/pmu.c:1.27 --- src/sys/arch/macppc/dev/pmu.c:1.26 Tue May 31 03:50:30 2016 +++ src/sys/arch/macppc/dev/pmu.c Wed Jun 1 05:27:40 2016 @@ -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 @@ __KERNEL_RCSID(0, "$NetBSD: pmu.c,v 1.26 #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 void pmu_autopoll(void *, int); 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 pmu_softc { 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 @@ struct pmu_softc { 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 @@ pmu_attach(device_t parent, device_t sel 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 @@ pmu_attach(device_t parent, device_t sel 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 @@ bat_done: 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 @@ pmu_intr(void *arg) 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 @@ pmu_intr(void *arg) 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 @@ pmu_intr(void *arg) 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 @@ pmu_i2c_exec(void *cookie, i2c_op_t op, 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 @@ pmu_thread(void *cookie) 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 @@ pmu_thread(void *cookie) 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); } Index: src/sys/arch/macppc/dev/pmuvar.h diff -u src/sys/arch/macppc/dev/pmuvar.h:1.8 src/sys/arch/macppc/dev/pmuvar.h:1.9 --- src/sys/arch/macppc/dev/pmuvar.h:1.8 Tue Nov 9 20:44:49 2010 +++ src/sys/arch/macppc/dev/pmuvar.h Wed Jun 1 05:27:40 2016 @@ -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 @@ __KERNEL_RCSID(0, "$NetBSD: pmuvar.h,v 1 /* 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 {