Module Name: src Committed By: jruoho Date: Fri Mar 5 21:01:44 UTC 2010
Modified Files: src/sys/dev/acpi: acpi.c acpi_lid.c acpi_wakedev.c acpi_wakedev.h Log Message: Preparing a device for wakeup involves: (a) turning on all power resources required by the device; and (b) executing _DSW (or _PSW) control method. This implements (b). Ok jmcne...@. To generate a diff of this commit: cvs rdiff -u -r1.155 -r1.156 src/sys/dev/acpi/acpi.c cvs rdiff -u -r1.36 -r1.37 src/sys/dev/acpi/acpi_lid.c cvs rdiff -u -r1.3 -r1.4 src/sys/dev/acpi/acpi_wakedev.c cvs rdiff -u -r1.2 -r1.3 src/sys/dev/acpi/acpi_wakedev.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/dev/acpi/acpi.c diff -u src/sys/dev/acpi/acpi.c:1.155 src/sys/dev/acpi/acpi.c:1.156 --- src/sys/dev/acpi/acpi.c:1.155 Fri Mar 5 14:00:16 2010 +++ src/sys/dev/acpi/acpi.c Fri Mar 5 21:01:44 2010 @@ -1,4 +1,4 @@ -/* $NetBSD: acpi.c,v 1.155 2010/03/05 14:00:16 jruoho Exp $ */ +/* $NetBSD: acpi.c,v 1.156 2010/03/05 21:01:44 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.155 2010/03/05 14:00:16 jruoho Exp $"); +__KERNEL_RCSID(0, "$NetBSD: acpi.c,v 1.156 2010/03/05 21:01:44 jruoho Exp $"); #include "opt_acpi.h" #include "opt_pcifixup.h" @@ -1519,7 +1519,7 @@ break; } - acpi_wakedev_commit(sc); + acpi_wakedev_commit(sc, state); if (state != ACPI_STATE_S1 && !pmf_system_suspend(PMF_Q_NONE)) { aprint_error_dev(sc->sc_dev, "aborting suspend\n"); Index: src/sys/dev/acpi/acpi_lid.c diff -u src/sys/dev/acpi/acpi_lid.c:1.36 src/sys/dev/acpi/acpi_lid.c:1.37 --- src/sys/dev/acpi/acpi_lid.c:1.36 Fri Mar 5 14:00:16 2010 +++ src/sys/dev/acpi/acpi_lid.c Fri Mar 5 21:01:44 2010 @@ -1,4 +1,4 @@ -/* $NetBSD: acpi_lid.c,v 1.36 2010/03/05 14:00:16 jruoho Exp $ */ +/* $NetBSD: acpi_lid.c,v 1.37 2010/03/05 21:01:44 jruoho Exp $ */ /* * Copyright 2001, 2003 Wasabi Systems, Inc. @@ -40,7 +40,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: acpi_lid.c,v 1.36 2010/03/05 14:00:16 jruoho Exp $"); +__KERNEL_RCSID(0, "$NetBSD: acpi_lid.c,v 1.37 2010/03/05 21:01:44 jruoho Exp $"); #include <sys/param.h> #include <sys/device.h> @@ -69,8 +69,6 @@ static int acpilid_detach(device_t, int); static void acpilid_status_changed(void *); static void acpilid_notify_handler(ACPI_HANDLE, UINT32, void *); -static void acpilid_wake_event(device_t, bool); -static bool acpilid_suspend(device_t, const pmf_qual_t *); CFATTACH_DECL_NEW(acpilid, sizeof(struct acpilid_softc), acpilid_match, acpilid_attach, acpilid_detach, NULL); @@ -111,8 +109,8 @@ sc->sc_smpsw.smpsw_name = device_xname(self); sc->sc_smpsw.smpsw_type = PSWITCH_TYPE_LID; + (void)pmf_device_register(self, NULL, NULL); (void)sysmon_pswitch_register(&sc->sc_smpsw); - (void)pmf_device_register(self, acpilid_suspend, NULL); rv = AcpiInstallNotifyHandler(sc->sc_node->ad_handle, ACPI_DEVICE_NOTIFY, acpilid_notify_handler, self); @@ -139,47 +137,6 @@ return 0; } -static void -acpilid_wake_event(device_t dv, bool enable) -{ - struct acpilid_softc *sc = device_private(dv); - ACPI_OBJECT_LIST arg; - ACPI_OBJECT obj[3]; - ACPI_STATUS rv; - - /* - * First try to call the Device Sleep Wake control method, _DSW. - * Only if this is not available, resort to to the Power State - * Wake control method, _PSW, which was deprecated in ACPI 3.0. - */ - obj[0].Integer.Value = enable ? 1 : 0; - obj[1].Integer.Value = obj[2].Integer.Value = 0; - obj[0].Type = obj[1].Type = obj[2].Type = ACPI_TYPE_INTEGER; - - arg.Count = 3; - arg.Pointer = obj; - - rv = AcpiEvaluateObject(sc->sc_node->ad_handle, "_DSW", &arg, NULL); - - if (ACPI_SUCCESS(rv)) - return; - - if (rv != AE_NOT_FOUND) - goto fail; - - rv = acpi_eval_set_integer(sc->sc_node->ad_handle, "_PSW", - enable ? 1 : 0); - - if (ACPI_FAILURE(rv) && rv != AE_NOT_FOUND) - goto fail; - - return; - -fail: - aprint_error_dev(dv, "unable to evaluate wake control method: %s\n", - AcpiFormatException(rv)); -} - /* * acpilid_status_changed: * @@ -223,16 +180,6 @@ } } -static bool -acpilid_suspend(device_t dv, const pmf_qual_t *qual) -{ - struct acpilid_softc *sc = device_private(dv); - - acpilid_wake_event(dv, sc->sc_status == 0); - - return true; -} - #ifdef _MODULE MODULE(MODULE_CLASS_DRIVER, acpilid, NULL); Index: src/sys/dev/acpi/acpi_wakedev.c diff -u src/sys/dev/acpi/acpi_wakedev.c:1.3 src/sys/dev/acpi/acpi_wakedev.c:1.4 --- src/sys/dev/acpi/acpi_wakedev.c:1.3 Fri Mar 5 14:00:17 2010 +++ src/sys/dev/acpi/acpi_wakedev.c Fri Mar 5 21:01:44 2010 @@ -1,4 +1,4 @@ -/* $NetBSD: acpi_wakedev.c,v 1.3 2010/03/05 14:00:17 jruoho Exp $ */ +/* $NetBSD: acpi_wakedev.c,v 1.4 2010/03/05 21:01:44 jruoho Exp $ */ /*- * Copyright (c) 2009 Jared D. McNeill <jmcne...@invisible.ca> @@ -27,7 +27,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: acpi_wakedev.c,v 1.3 2010/03/05 14:00:17 jruoho Exp $"); +__KERNEL_RCSID(0, "$NetBSD: acpi_wakedev.c,v 1.4 2010/03/05 21:01:44 jruoho Exp $"); #include <sys/param.h> #include <sys/device.h> @@ -40,6 +40,8 @@ #include <dev/acpi/acpivar.h> #include <dev/acpi/acpi_wakedev.h> +static void acpi_wakedev_prepare(struct acpi_devnode *, int, int); + struct acpi_wakedev; static TAILQ_HEAD(, acpi_wakedev) acpi_wakedevlist = @@ -173,16 +175,83 @@ } void -acpi_wakedev_commit(struct acpi_softc *sc) +acpi_wakedev_commit(struct acpi_softc *sc, int state) { struct acpi_wakedev *aw; + /* + * As noted in ACPI 3.0 (p. 243), preparing + * a device for wakeup is a two-step process: + * + * 1. Enable all power resources in _PRW. + * + * 2. If present, execute _DSW/_PSW method. + * + * XXX: The first one is yet to be implemented. + */ TAILQ_FOREACH(aw, &acpi_wakedevlist, aw_list) { + if (aw->aw_enabled) { aprint_debug_dev(sc->sc_dev, "set wake GPE (%s)\n", aw->aw_node->ad_name); acpi_set_wake_gpe(aw->aw_node->ad_handle); } else acpi_clear_wake_gpe(aw->aw_node->ad_handle); + + acpi_wakedev_prepare(aw->aw_node, aw->aw_enabled, state); } } + +static void +acpi_wakedev_prepare(struct acpi_devnode *ad, int enable, int state) +{ + ACPI_OBJECT_LIST arg; + ACPI_OBJECT obj[3]; + ACPI_STATUS rv; + + /* + * First try to call the Device Sleep Wake control method, _DSW. + * Only if this is not available, resort to to the Power State + * Wake control method, _PSW, which was deprecated in ACPI 3.0. + * + * The arguments to these methods are as follows: + * + * arg0 arg1 arg2 + * ---- ---- ---- + * _PSW 0: disable + * 1: enable + * + * _DSW 0: disable 0: S0 0: D0 + * 1: enable 1: S1 1: D0 or D1 + * 2: D0, D1, or D2 + * x: Sx 3: D0, D1, D2 or D3 + */ + arg.Count = 3; + arg.Pointer = obj; + + obj[0].Integer.Value = enable; + obj[1].Integer.Value = state; + obj[2].Integer.Value = 3; + + obj[0].Type = obj[1].Type = obj[2].Type = ACPI_TYPE_INTEGER; + + rv = AcpiEvaluateObject(ad->ad_handle, "_DSW", &arg, NULL); + + if (ACPI_SUCCESS(rv)) + return; + + if (rv != AE_NOT_FOUND) + goto fail; + + rv = acpi_eval_set_integer(ad->ad_handle, "_PSW", enable); + + if (ACPI_FAILURE(rv) && rv != AE_NOT_FOUND) + goto fail; + + return; + +fail: + aprint_error_dev(ad->ad_device, "failed to evaluate wake " + "control method: %s\n", AcpiFormatException(rv)); +} + Index: src/sys/dev/acpi/acpi_wakedev.h diff -u src/sys/dev/acpi/acpi_wakedev.h:1.2 src/sys/dev/acpi/acpi_wakedev.h:1.3 --- src/sys/dev/acpi/acpi_wakedev.h:1.2 Fri Mar 5 08:30:48 2010 +++ src/sys/dev/acpi/acpi_wakedev.h Fri Mar 5 21:01:44 2010 @@ -1,4 +1,4 @@ -/* $NetBSD: acpi_wakedev.h,v 1.2 2010/03/05 08:30:48 jruoho Exp $ */ +/* $NetBSD: acpi_wakedev.h,v 1.3 2010/03/05 21:01:44 jruoho Exp $ */ /*- * Copyright (c) 2009 Jared D. McNeill <jmcne...@invisible.ca> @@ -30,6 +30,6 @@ #define _SYS_DEV_ACPI_ACPI_WAKEDEV_H int acpi_wakedev_scan(struct acpi_softc *); -void acpi_wakedev_commit(struct acpi_softc *); +void acpi_wakedev_commit(struct acpi_softc *, int); #endif /* !_SYS_DEV_ACPI_ACPI_WAKEDEV_H */