diff options
Diffstat (limited to 'sys/dev/acpica/acpi.c')
-rw-r--r-- | sys/dev/acpica/acpi.c | 102 |
1 files changed, 66 insertions, 36 deletions
diff --git a/sys/dev/acpica/acpi.c b/sys/dev/acpica/acpi.c index ad1af9373fb7..f2ff1d59ccc7 100644 --- a/sys/dev/acpica/acpi.c +++ b/sys/dev/acpica/acpi.c @@ -55,6 +55,8 @@ #if defined(__i386__) || defined(__amd64__) #include <machine/clock.h> #include <machine/pci_cfgreg.h> +#include <x86/cputypes.h> +#include <x86/x86_var.h> #endif #include <machine/resource.h> #include <machine/bus.h> @@ -140,6 +142,7 @@ static bus_child_location_t acpi_child_location_method; static bus_hint_device_unit_t acpi_hint_device_unit; static bus_get_property_t acpi_bus_get_prop; static bus_get_device_path_t acpi_get_device_path; +static bus_get_domain_t acpi_get_domain_method; static acpi_id_probe_t acpi_device_id_probe; static acpi_evaluate_object_t acpi_device_eval_obj; @@ -217,7 +220,7 @@ static device_method_t acpi_methods[] = { DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr), DEVMETHOD(bus_hint_device_unit, acpi_hint_device_unit), DEVMETHOD(bus_get_cpus, acpi_get_cpus), - DEVMETHOD(bus_get_domain, acpi_get_domain), + DEVMETHOD(bus_get_domain, acpi_get_domain_method), DEVMETHOD(bus_get_property, acpi_bus_get_prop), DEVMETHOD(bus_get_device_path, acpi_get_device_path), @@ -297,6 +300,10 @@ int acpi_susp_bounce; SYSCTL_INT(_debug_acpi, OID_AUTO, suspend_bounce, CTLFLAG_RW, &acpi_susp_bounce, 0, "Don't actually suspend, just test devices."); +#if defined(__amd64__) || defined(__i386__) +int acpi_override_isa_irq_polarity; +#endif + /* * ACPI standard UUID for Device Specific Data Package * "Device Properties UUID for _DSD" Rev. 2.0 @@ -611,6 +618,19 @@ acpi_attach(device_t dev) OID_AUTO, "handle_reboot", CTLFLAG_RW, &sc->acpi_handle_reboot, 0, "Use ACPI Reset Register to reboot"); +#if defined(__amd64__) || defined(__i386__) + /* + * Enable workaround for incorrect ISA IRQ polarity by default on + * systems with Intel CPUs. + */ + if (cpu_vendor_id == CPU_VENDOR_INTEL) + acpi_override_isa_irq_polarity = 1; + SYSCTL_ADD_INT(&sc->acpi_sysctl_ctx, SYSCTL_CHILDREN(sc->acpi_sysctl_tree), + OID_AUTO, "override_isa_irq_polarity", CTLFLAG_RDTUN, + &acpi_override_isa_irq_polarity, 0, + "Force active-hi polarity for edge-triggered ISA IRQs"); +#endif + /* * Default to 1 second before sleeping to give some machines time to * stabilize. @@ -800,6 +820,7 @@ acpi_add_child(device_t bus, u_int order, const char *name, int unit) if ((ad = malloc(sizeof(*ad), M_ACPIDEV, M_NOWAIT | M_ZERO)) == NULL) return (NULL); + ad->ad_domain = ACPI_DEV_DOMAIN_UNKNOWN; resource_list_init(&ad->ad_rl); child = device_add_child_ordered(bus, order, name, unit); @@ -1036,6 +1057,9 @@ acpi_read_ivar(device_t dev, device_t child, int index, uintptr_t *result) case ACPI_IVAR_FLAGS: *(int *)result = ad->ad_flags; break; + case ACPI_IVAR_DOMAIN: + *(int *)result = ad->ad_domain; + break; case ISA_IVAR_VENDORID: case ISA_IVAR_SERIAL: case ISA_IVAR_COMPATID: @@ -1080,6 +1104,9 @@ acpi_write_ivar(device_t dev, device_t child, int index, uintptr_t value) case ACPI_IVAR_FLAGS: ad->ad_flags = (int)value; break; + case ACPI_IVAR_DOMAIN: + ad->ad_domain = (int)value; + break; default: panic("bad ivar write request (%d)", index); return (ENOENT); @@ -1227,8 +1254,8 @@ acpi_hint_device_unit(device_t acdev, device_t child, const char *name, * _PXM to a NUMA domain. If the device does not have a _PXM method, * -2 is returned. If any other error occurs, -1 is returned. */ -static int -acpi_parse_pxm(device_t dev) +int +acpi_pxm_parse(device_t dev) { #ifdef NUMA #if defined(__i386__) || defined(__amd64__) || defined(__aarch64__) @@ -1255,7 +1282,7 @@ acpi_get_cpus(device_t dev, device_t child, enum cpu_sets op, size_t setsize, { int d, error; - d = acpi_parse_pxm(child); + d = acpi_pxm_parse(child); if (d < 0) return (bus_generic_get_cpus(dev, child, op, setsize, cpuset)); @@ -1278,29 +1305,16 @@ acpi_get_cpus(device_t dev, device_t child, enum cpu_sets op, size_t setsize, } } -/* - * Fetch the NUMA domain for the given device 'dev'. - * - * If a device has a _PXM method, map that to a NUMA domain. - * Otherwise, pass the request up to the parent. - * If there's no matching domain or the domain cannot be - * determined, return ENOENT. - */ -int -acpi_get_domain(device_t dev, device_t child, int *domain) +static int +acpi_get_domain_method(device_t dev, device_t child, int *domain) { - int d; + int error; - d = acpi_parse_pxm(child); - if (d >= 0) { - *domain = d; + error = acpi_read_ivar(dev, child, ACPI_IVAR_DOMAIN, + (uintptr_t *)domain); + if (error == 0 && *domain != ACPI_DEV_DOMAIN_UNKNOWN) return (0); - } - if (d == -1) - return (ENOENT); - - /* No _PXM node; go up a level */ - return (bus_generic_get_domain(dev, child, domain)); + return (ENOENT); } static struct rman * @@ -1651,19 +1665,22 @@ acpi_map_resource(device_t bus, device_t child, struct resource *r, args.offset = start - rman_get_start(sysres); args.length = length; - return (bus_generic_map_resource(bus, child, sysres, &args, map)); + return (bus_map_resource(bus, sysres, &args, map)); } static int acpi_unmap_resource(device_t bus, device_t child, struct resource *r, struct resource_map *map) { - if (acpi_is_resource_managed(bus, r)) { - r = acpi_managed_resource(bus, r); - if (r == NULL) - return (ENOENT); - } - return (bus_generic_unmap_resource(bus, child, r, map)); + struct resource *sysres; + + if (!acpi_is_resource_managed(bus, r)) + return (bus_generic_unmap_resource(bus, child, r, map)); + + sysres = acpi_managed_resource(bus, r); + if (sysres == NULL) + return (ENOENT); + return (bus_unmap_resource(bus, sysres, map)); } /* Allocate an IO port or memory resource, given its GAS. */ @@ -2262,11 +2279,11 @@ acpi_probe_children(device_t bus) /* Create any static children by calling device identify methods. */ ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "device identify routines\n")); - bus_generic_probe(bus); + bus_identify_children(bus); /* Probe/attach all children, created statically and from the namespace. */ - ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "acpi bus_generic_attach\n")); - bus_generic_attach(bus); + ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "acpi bus_attach_children\n")); + bus_attach_children(bus); /* * Reserve resources allocated to children but not yet allocated @@ -2326,7 +2343,7 @@ acpi_probe_child(ACPI_HANDLE handle, UINT32 level, void *context, void **status) ACPI_HANDLE h; device_t bus, child; char *handle_str; - int order; + int d, order; ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); @@ -2374,7 +2391,7 @@ acpi_probe_child(ACPI_HANDLE handle, UINT32 level, void *context, void **status) ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "scanning '%s'\n", handle_str)); order = level * 10 + ACPI_DEV_BASE_ORDER; acpi_probe_order(handle, &order); - child = BUS_ADD_CHILD(bus, order, NULL, -1); + child = BUS_ADD_CHILD(bus, order, NULL, DEVICE_UNIT_ANY); if (child == NULL) break; @@ -2434,6 +2451,10 @@ acpi_probe_child(ACPI_HANDLE handle, UINT32 level, void *context, void **status) } AcpiOsFree(devinfo); } + + d = acpi_pxm_parse(child); + if (d >= 0) + ad->ad_domain = d; break; } } @@ -3881,13 +3902,22 @@ acpi_invoke_wake_eventhandler(void *context) UINT32 acpi_event_power_button_sleep(void *context) { +#if defined(__amd64__) || defined(__i386__) struct acpi_softc *sc = (struct acpi_softc *)context; +#else + (void)context; +#endif ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); +#if defined(__amd64__) || defined(__i386__) if (ACPI_FAILURE(AcpiOsExecute(OSL_NOTIFY_HANDLER, acpi_invoke_sleep_eventhandler, &sc->acpi_power_button_sx))) return_VALUE (ACPI_INTERRUPT_NOT_HANDLED); +#else + shutdown_nice(RB_POWEROFF); +#endif + return_VALUE (ACPI_INTERRUPT_HANDLED); } |