Module Name: src Committed By: jruoho Date: Thu Oct 28 15:55:05 UTC 2010
Modified Files: src/sys/dev/acpi/wmi: wmi_acpi.c wmi_acpivar.h Log Message: Install EC space handler and pass everything to acpiec(4). Should fix PR # 43659. To generate a diff of this commit: cvs rdiff -u -r1.10 -r1.11 src/sys/dev/acpi/wmi/wmi_acpi.c cvs rdiff -u -r1.4 -r1.5 src/sys/dev/acpi/wmi/wmi_acpivar.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/wmi/wmi_acpi.c diff -u src/sys/dev/acpi/wmi/wmi_acpi.c:1.10 src/sys/dev/acpi/wmi/wmi_acpi.c:1.11 --- src/sys/dev/acpi/wmi/wmi_acpi.c:1.10 Mon Oct 25 15:38:05 2010 +++ src/sys/dev/acpi/wmi/wmi_acpi.c Thu Oct 28 15:55:04 2010 @@ -1,4 +1,4 @@ -/* $NetBSD: wmi_acpi.c,v 1.10 2010/10/25 15:38:05 jruoho Exp $ */ +/* $NetBSD: wmi_acpi.c,v 1.11 2010/10/28 15:55:04 jruoho Exp $ */ /*- * Copyright (c) 2009, 2010 Jukka Ruohonen <jruoho...@iki.fi> @@ -27,7 +27,7 @@ * SUCH DAMAGE. */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: wmi_acpi.c,v 1.10 2010/10/25 15:38:05 jruoho Exp $"); +__KERNEL_RCSID(0, "$NetBSD: wmi_acpi.c,v 1.11 2010/10/28 15:55:04 jruoho Exp $"); #include <sys/param.h> #include <sys/device.h> @@ -38,6 +38,7 @@ #include <dev/acpi/acpireg.h> #include <dev/acpi/acpivar.h> +#include <dev/acpi/acpi_ecvar.h> #include <dev/acpi/wmi/wmi_acpivar.h> #define _COMPONENT ACPI_RESOURCE_COMPONENT @@ -52,26 +53,28 @@ * (Obtained on Thu Feb 12 18:21:44 EET 2009.) */ -static int acpi_wmi_match(device_t, cfdata_t, void *); -static void acpi_wmi_attach(device_t, device_t, void *); -static int acpi_wmi_detach(device_t, int); -static int acpi_wmi_rescan(device_t, const char *, const int *); -static void acpi_wmi_childdet(device_t, device_t); -static int acpi_wmi_print(void *, const char *); -static bool acpi_wmi_init(struct acpi_wmi_softc *); -static bool acpi_wmi_add(struct acpi_wmi_softc *, ACPI_OBJECT *); -static void acpi_wmi_del(struct acpi_wmi_softc *); -static void acpi_wmi_dump(struct acpi_wmi_softc *); - -static ACPI_STATUS acpi_wmi_guid_get(struct acpi_wmi_softc *, - const char *, struct wmi_t **); -static void acpi_wmi_event_add(struct acpi_wmi_softc *); -static void acpi_wmi_event_del(struct acpi_wmi_softc *); -static void acpi_wmi_event_handler(ACPI_HANDLE, uint32_t, void *); -static bool acpi_wmi_suspend(device_t, const pmf_qual_t *); -static bool acpi_wmi_resume(device_t, const pmf_qual_t *); -static ACPI_STATUS acpi_wmi_enable(ACPI_HANDLE, const char *, bool, bool); -static bool acpi_wmi_input(struct wmi_t *, uint8_t, uint8_t); +static int acpi_wmi_match(device_t, cfdata_t, void *); +static void acpi_wmi_attach(device_t, device_t, void *); +static int acpi_wmi_detach(device_t, int); +static int acpi_wmi_rescan(device_t, const char *, const int *); +static void acpi_wmi_childdet(device_t, device_t); +static int acpi_wmi_print(void *, const char *); +static bool acpi_wmi_init(struct acpi_wmi_softc *); +static void acpi_wmi_init_ec(struct acpi_wmi_softc *); +static bool acpi_wmi_add(struct acpi_wmi_softc *, ACPI_OBJECT *); +static void acpi_wmi_del(struct acpi_wmi_softc *); +static void acpi_wmi_dump(struct acpi_wmi_softc *); +static ACPI_STATUS acpi_wmi_guid_get(struct acpi_wmi_softc *, + const char *, struct wmi_t **); +static void acpi_wmi_event_add(struct acpi_wmi_softc *); +static void acpi_wmi_event_del(struct acpi_wmi_softc *); +static void acpi_wmi_event_handler(ACPI_HANDLE, uint32_t, void *); +static ACPI_STATUS acpi_wmi_ec_handler(uint32_t, ACPI_PHYSICAL_ADDRESS, + uint32_t, ACPI_INTEGER *, void *, void *); +static bool acpi_wmi_suspend(device_t, const pmf_qual_t *); +static bool acpi_wmi_resume(device_t, const pmf_qual_t *); +static ACPI_STATUS acpi_wmi_enable(ACPI_HANDLE, const char *, bool, bool); +static bool acpi_wmi_input(struct wmi_t *, uint8_t, uint8_t); const char * const acpi_wmi_ids[] = { "PNP0C14", @@ -104,6 +107,7 @@ sc->sc_node = aa->aa_node; sc->sc_child = NULL; + sc->sc_ecdev = NULL; sc->sc_handler = NULL; aprint_naive("\n"); @@ -113,8 +117,8 @@ return; acpi_wmi_dump(sc); + acpi_wmi_init_ec(sc); acpi_wmi_event_add(sc); - acpi_wmi_rescan(self, NULL, NULL); (void)pmf_device_register(self, acpi_wmi_suspend, acpi_wmi_resume); @@ -127,6 +131,12 @@ acpi_wmi_event_del(sc); + if (sc->sc_ecdev != NULL) { + + (void)AcpiRemoveAddressSpaceHandler(sc->sc_node->ad_handle, + ACPI_ADR_SPACE_EC, acpi_wmi_ec_handler); + } + if (sc->sc_child != NULL) (void)config_detach(sc->sc_child, flags); @@ -291,6 +301,36 @@ } } +static void +acpi_wmi_init_ec(struct acpi_wmi_softc *sc) +{ + ACPI_STATUS rv; + deviter_t i; + device_t d; + + d = deviter_first(&i, DEVITER_F_ROOT_FIRST); + + for (; d != NULL; d = deviter_next(&i)) { + + if (device_is_a(d, "acpiec") != false || + device_is_a(d, "acpiecdt") != false) { + sc->sc_ecdev = d; + break; + } + } + + deviter_release(&i); + + if (sc->sc_ecdev == NULL) + return; + + rv = AcpiInstallAddressSpaceHandler(sc->sc_node->ad_handle, + ACPI_ADR_SPACE_EC, acpi_wmi_ec_handler, NULL, sc); + + if (ACPI_FAILURE(rv)) + sc->sc_ecdev = NULL; +} + static ACPI_STATUS acpi_wmi_guid_get(struct acpi_wmi_softc *sc, const char *src, struct wmi_t **out) @@ -510,6 +550,38 @@ } /* + * Handler for EC regions, which may be embedded in WMI. + */ +static ACPI_STATUS +acpi_wmi_ec_handler(uint32_t func, ACPI_PHYSICAL_ADDRESS addr, + uint32_t width, ACPI_INTEGER *val, void *setup, void *aux) +{ + struct acpi_wmi_softc *sc = aux; + + if (aux == NULL || val == NULL) + return AE_BAD_PARAMETER; + + if (addr > 0xFF || width % 8 != 0) + return AE_BAD_ADDRESS; + + switch (func) { + + case ACPI_READ: + (void)acpiec_bus_read(sc->sc_ecdev, addr, val, width); + break; + + case ACPI_WRITE: + (void)acpiec_bus_write(sc->sc_ecdev, addr, *val, width); + break; + + default: + return AE_BAD_PARAMETER; + } + + return AE_OK; +} + +/* * As there is no prior knowledge about the expensive * events that cause "significant overhead", try to * disable (enable) these before suspending (resuming). Index: src/sys/dev/acpi/wmi/wmi_acpivar.h diff -u src/sys/dev/acpi/wmi/wmi_acpivar.h:1.4 src/sys/dev/acpi/wmi/wmi_acpivar.h:1.5 --- src/sys/dev/acpi/wmi/wmi_acpivar.h:1.4 Sat Jun 5 06:07:12 2010 +++ src/sys/dev/acpi/wmi/wmi_acpivar.h Thu Oct 28 15:55:04 2010 @@ -1,4 +1,4 @@ -/* $NetBSD: wmi_acpivar.h,v 1.4 2010/06/05 06:07:12 jruoho Exp $ */ +/* $NetBSD: wmi_acpivar.h,v 1.5 2010/10/28 15:55:04 jruoho Exp $ */ /*- * Copyright (c) 2009, 2010 Jukka Ruohonen <jruoho...@iki.fi> @@ -31,7 +31,7 @@ #define _SYS_DEV_ACPI_WMI_WMI_ACPIVAR_H #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: wmi_acpivar.h,v 1.4 2010/06/05 06:07:12 jruoho Exp $"); +__KERNEL_RCSID(0, "$NetBSD: wmi_acpivar.h,v 1.5 2010/10/28 15:55:04 jruoho Exp $"); ACPI_STATUS acpi_wmi_event_register(device_t, ACPI_NOTIFY_HANDLER); ACPI_STATUS acpi_wmi_event_deregister(device_t); @@ -91,10 +91,11 @@ }; struct acpi_wmi_softc { - device_t sc_dev; - device_t sc_child; - ACPI_NOTIFY_HANDLER sc_handler; + device_t sc_dev; + device_t sc_child; + device_t sc_ecdev; struct acpi_devnode *sc_node; + ACPI_NOTIFY_HANDLER sc_handler; SIMPLEQ_HEAD(, wmi_t) wmi_head; };