Module Name:    src
Committed By:   jruoho
Date:           Wed Apr 14 06:10:33 UTC 2010

Modified Files:
        src/sys/dev/acpi: acpi.c

Log Message:
Refactor the fixed-event handlers.

Also provide a detachment routine for these and fix a trivial bug;
a wrong structure was used when registering a sysmon_pswitch(9) switch.


To generate a diff of this commit:
cvs rdiff -u -r1.167 -r1.168 src/sys/dev/acpi/acpi.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/acpi/acpi.c
diff -u src/sys/dev/acpi/acpi.c:1.167 src/sys/dev/acpi/acpi.c:1.168
--- src/sys/dev/acpi/acpi.c:1.167	Mon Apr 12 18:59:08 2010
+++ src/sys/dev/acpi/acpi.c	Wed Apr 14 06:10:32 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: acpi.c,v 1.167 2010/04/12 18:59:08 jruoho Exp $	*/
+/*	$NetBSD: acpi.c,v 1.168 2010/04/14 06:10:32 jruoho Exp $	*/
 
 /*-
  * Copyright (c) 2003, 2007 The NetBSD Foundation, Inc.
@@ -70,7 +70,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: acpi.c,v 1.167 2010/04/12 18:59:08 jruoho Exp $");
+__KERNEL_RCSID(0, "$NetBSD: acpi.c,v 1.168 2010/04/14 06:10:32 jruoho Exp $");
 
 #include "opt_acpi.h"
 #include "opt_pcifixup.h"
@@ -184,7 +184,11 @@
 static ACPI_STATUS	acpi_make_devnode(ACPI_HANDLE, uint32_t,
 					  void *, void **);
 
-static void		acpi_enable_fixed_events(struct acpi_softc *);
+static void		acpi_register_fixed_button(struct acpi_softc *, int);
+static void		acpi_deregister_fixed_button(struct acpi_softc *, int);
+static uint32_t		acpi_fixed_button_handler(void *);
+static void		acpi_fixed_button_pressed(void *);
+
 static void		acpi_sleep_init(struct acpi_softc *);
 
 static ACPI_TABLE_HEADER *acpi_map_rsdt(void);
@@ -515,19 +519,21 @@
 	    AcpiGbl_FADT.SciInterrupt);
 
 	/*
-	 * Check for fixed-hardware features.
+	 * Install fixed-event handlers.
 	 */
-	acpi_enable_fixed_events(sc);
+	acpi_register_fixed_button(sc, ACPI_EVENT_POWER_BUTTON);
+	acpi_register_fixed_button(sc, ACPI_EVENT_SLEEP_BUTTON);
+
 	acpitimer_init();
 
-	/*
-	 * Scan the namespace and build our device tree.
-	 */
 #ifdef ACPI_DEBUGGER
 	if (acpi_dbgr & ACPI_DBGR_PROBE)
 		acpi_osd_debugger();
 #endif
 
+	/*
+	 * Scan the namespace and build our device tree.
+	 */
 	acpi_build_tree(sc);
 	acpi_sleep_init(sc);
 
@@ -544,6 +550,7 @@
 static int
 acpi_detach(device_t self, int flags)
 {
+	struct acpi_softc *sc = device_private(self);
 	int rc;
 
 #ifdef ACPI_DEBUGGER
@@ -601,11 +608,13 @@
 		    AcpiFormatException(rv));
 		return;
 	}
-	acpi_active = 1;
 
-	acpi_enable_fixed_events(sc);
+	acpi_active = 1;
 #endif
 
+	acpi_deregister_fixed_button(sc, ACPI_EVENT_POWER_BUTTON);
+	acpi_deregister_fixed_button(sc, ACPI_EVENT_SLEEP_BUTTON);
+
 	pmf_device_deregister(self);
 
 #if 0
@@ -997,98 +1006,123 @@
 	return UNCONF;
 }
 
-/*****************************************************************************
- * ACPI fixed-hardware feature handlers
- *****************************************************************************/
-
-static UINT32	acpi_fixed_button_handler(void *);
-static void	acpi_fixed_button_pressed(void *);
-
 /*
- * acpi_enable_fixed_events:
- *
- *	Enable any fixed-hardware feature handlers.
+ * Fixed buttons.
  */
 static void
-acpi_enable_fixed_events(struct acpi_softc *sc)
+acpi_register_fixed_button(struct acpi_softc *sc, int event)
 {
-	static int beenhere;
+	struct sysmon_pswitch *smpsw;
 	ACPI_STATUS rv;
+	int type;
 
-	KASSERT(beenhere == 0);
-	beenhere = 1;
+	switch (event) {
 
-	/*
-	 * Check for fixed-hardware buttons.
-	 */
-	if ((AcpiGbl_FADT.Flags & ACPI_FADT_POWER_BUTTON) == 0) {
-		aprint_verbose_dev(sc->sc_dev,
-		    "fixed-feature power button present\n");
-		sc->sc_smpsw_power.smpsw_name = device_xname(sc->sc_dev);
-		sc->sc_smpsw_power.smpsw_type = PSWITCH_TYPE_POWER;
-		if (sysmon_pswitch_register(&sc->sc_smpsw_power) != 0) {
-			aprint_error_dev(sc->sc_dev,
-			    "unable to register fixed power "
-			    "button with sysmon\n");
-		} else {
-			rv = AcpiInstallFixedEventHandler(
-			    ACPI_EVENT_POWER_BUTTON,
-			    acpi_fixed_button_handler, &sc->sc_smpsw_power);
-			if (ACPI_FAILURE(rv)) {
-				aprint_error_dev(sc->sc_dev,
-				    "unable to install handler "
-				    "for fixed power button: %s\n",
-				    AcpiFormatException(rv));
-			}
-		}
+	case ACPI_EVENT_POWER_BUTTON:
+
+		if ((AcpiGbl_FADT.Flags & ACPI_FADT_POWER_BUTTON) != 0)
+			return;
+
+		type = PSWITCH_TYPE_POWER;
+		smpsw = &sc->sc_smpsw_power;
+		break;
+
+	case ACPI_EVENT_SLEEP_BUTTON:
+
+		if ((AcpiGbl_FADT.Flags & ACPI_FADT_SLEEP_BUTTON) != 0)
+			return;
+
+		type = PSWITCH_TYPE_SLEEP;
+		smpsw = &sc->sc_smpsw_sleep;
+		break;
+
+	default:
+		rv = AE_TYPE;
+		goto fail;
 	}
 
-	if ((AcpiGbl_FADT.Flags & ACPI_FADT_SLEEP_BUTTON) == 0) {
-		aprint_verbose_dev(sc->sc_dev,
-		    "fixed-feature sleep button present\n");
-		sc->sc_smpsw_sleep.smpsw_name = device_xname(sc->sc_dev);
-		sc->sc_smpsw_sleep.smpsw_type = PSWITCH_TYPE_SLEEP;
-		if (sysmon_pswitch_register(&sc->sc_smpsw_power) != 0) {
-			aprint_error_dev(sc->sc_dev,
-			    "unable to register fixed sleep "
-			    "button with sysmon\n");
-		} else {
-			rv = AcpiInstallFixedEventHandler(
-			    ACPI_EVENT_SLEEP_BUTTON,
-			    acpi_fixed_button_handler, &sc->sc_smpsw_sleep);
-			if (ACPI_FAILURE(rv)) {
-				aprint_error_dev(sc->sc_dev,
-				    "unable to install handler "
-				    "for fixed sleep button: %s\n",
-				    AcpiFormatException(rv));
-			}
+	smpsw->smpsw_type = type;
+	smpsw->smpsw_name = device_xname(sc->sc_dev);
+
+	if (sysmon_pswitch_register(smpsw) != 0) {
+		rv = AE_ERROR;
+		goto fail;
+	}
+
+	rv = AcpiInstallFixedEventHandler(event,
+	    acpi_fixed_button_handler, smpsw);
+
+	if (ACPI_FAILURE(rv))
+		goto fail;
+
+	aprint_debug_dev(sc->sc_dev, "fixed %s button present\n",
+	    (type != ACPI_EVENT_SLEEP_BUTTON) ? "power" : "sleep");
+
+	return;
+
+fail:
+	aprint_error_dev(sc->sc_dev, "failed to register "
+	    "fixed event: %s\n", AcpiFormatException(rv));
+}
+
+static void
+acpi_deregister_fixed_button(struct acpi_softc *sc, int event)
+{
+	struct sysmon_pswitch *smpsw;
+	ACPI_STATUS rv;
+
+	switch (event) {
+
+	case ACPI_EVENT_POWER_BUTTON:
+		smpsw = &sc->sc_smpsw_power;
+
+		if ((AcpiGbl_FADT.Flags & ACPI_FADT_POWER_BUTTON) != 0) {
+			KASSERT(smpsw->smpsw_type != PSWITCH_TYPE_POWER);
+			return;
+		}
+
+		break;
+
+	case ACPI_EVENT_SLEEP_BUTTON:
+		smpsw = &sc->sc_smpsw_sleep;
+
+		if ((AcpiGbl_FADT.Flags & ACPI_FADT_SLEEP_BUTTON) != 0) {
+			KASSERT(smpsw->smpsw_type != PSWITCH_TYPE_SLEEP);
+			return;
 		}
+
+		break;
+
+	default:
+		rv = AE_TYPE;
+		goto fail;
+	}
+
+	rv = AcpiRemoveFixedEventHandler(event, acpi_fixed_button_handler);
+
+	if (ACPI_SUCCESS(rv)) {
+		sysmon_pswitch_unregister(smpsw);
+		return;
 	}
+
+fail:
+	aprint_error_dev(sc->sc_dev, "failed to deregister "
+	    "fixed event: %s\n", AcpiFormatException(rv));
 }
 
-/*
- * acpi_fixed_button_handler:
- *
- *	Event handler for the fixed buttons.
- */
-static UINT32
+static uint32_t
 acpi_fixed_button_handler(void *context)
 {
 	static const int handler = OSL_NOTIFY_HANDLER;
 	struct sysmon_pswitch *smpsw = context;
 
-	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s\n", __func__));
+	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s: fixed event\n", __func__));
 
 	(void)AcpiOsExecute(handler, acpi_fixed_button_pressed, smpsw);
 
 	return ACPI_INTERRUPT_HANDLED;
 }
 
-/*
- * acpi_fixed_button_pressed:
- *
- *	Deal with a fixed button being pressed.
- */
 static void
 acpi_fixed_button_pressed(void *context)
 {

Reply via email to