From c739a12b6469730ac8c21d760bbfd884cd62fa99 Mon Sep 17 00:00:00 2001 From: Mark Kettenis Date: Sun, 10 Jan 2016 16:59:43 +0000 Subject: Introduce acpi_intr_establish(9), an API to establish interrupt handlers for "platform" devices that attach to acpi(4). ok mlarkin@, deraadt@ --- sys/arch/amd64/amd64/acpi_machdep.c | 59 ++++++++++++++++++++++++++++++++++++- sys/dev/acpi/acpivar.h | 5 +++- 2 files changed, 62 insertions(+), 2 deletions(-) (limited to 'sys') diff --git a/sys/arch/amd64/amd64/acpi_machdep.c b/sys/arch/amd64/amd64/acpi_machdep.c index fea60bf9ead..ac620bfec54 100644 --- a/sys/arch/amd64/amd64/acpi_machdep.c +++ b/sys/arch/amd64/amd64/acpi_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: acpi_machdep.c,v 1.71 2015/08/30 10:05:09 yasuoka Exp $ */ +/* $OpenBSD: acpi_machdep.c,v 1.72 2016/01/10 16:59:42 kettenis Exp $ */ /* * Copyright (c) 2005 Thorsten Lockert * @@ -40,13 +40,16 @@ #include #include #include +#include #include "isa.h" #include "ioapic.h" #include "lapic.h" #if NIOAPIC > 0 +#include #include +#include #endif #if NLAPIC > 0 @@ -97,6 +100,60 @@ acpi_unmap(struct acpi_mem_map *handle) uvm_km_free(kernel_map, handle->baseva, handle->vsize); } +void * +acpi_intr_establish(int irq, int flags, int level, + int (*handler)(void *), void *arg, const char *what) +{ +#if NIOAPIC > 0 + struct ioapic_softc *apic; + struct mp_intr_map *map; + int type; + + apic = ioapic_find_bybase(irq); + if (apic == NULL) + return NULL; + + map = malloc(sizeof(*map), M_DEVBUF, M_NOWAIT | M_ZERO); + if (map == NULL) + return NULL; + + map->ioapic = apic; + map->ioapic_pin = irq - apic->sc_apic_vecbase; + map->bus_pin = irq; + if (flags & LR_EXTIRQ_POLARITY) + map->flags |= (MPS_INTPO_ACTLO << MPS_INTPO_SHIFT); + else + map->flags |= (MPS_INTPO_ACTHI << MPS_INTPO_SHIFT); + if (flags & LR_EXTIRQ_MODE) + map->flags |= (MPS_INTTR_EDGE << MPS_INTTR_SHIFT); + else + map->flags |= (MPS_INTTR_LEVEL << MPS_INTTR_SHIFT); + + map->redir = (IOAPIC_REDLO_DEL_LOPRI << IOAPIC_REDLO_DEL_SHIFT); + map->redir = (IOAPIC_REDLO_DEL_LOPRI << IOAPIC_REDLO_DEL_SHIFT); + switch ((map->flags >> MPS_INTPO_SHIFT) & MPS_INTPO_MASK) { + case MPS_INTPO_DEF: + case MPS_INTPO_ACTLO: + map->redir |= IOAPIC_REDLO_ACTLO; + break; + } + switch ((map->flags >> MPS_INTTR_SHIFT) & MPS_INTTR_MASK) { + case MPS_INTTR_DEF: + case MPS_INTTR_LEVEL: + map->redir |= IOAPIC_REDLO_LEVEL; + break; + } + + apic->sc_pins[map->ioapic_pin].ip_map = map; + + type = (flags & LR_EXTIRQ_MODE) ? IST_EDGE : IST_LEVEL; + return (intr_establish(-1, (struct pic *)apic, map->ioapic_pin, + type, level, handler, arg, what)); +#else + return NULL; +#endif +} + u_int8_t * acpi_scan(struct acpi_mem_map *handle, paddr_t pa, size_t len) { diff --git a/sys/dev/acpi/acpivar.h b/sys/dev/acpi/acpivar.h index f7a7c442727..979ad54c0a2 100644 --- a/sys/dev/acpi/acpivar.h +++ b/sys/dev/acpi/acpivar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: acpivar.h,v 1.80 2016/01/09 18:54:51 kettenis Exp $ */ +/* $OpenBSD: acpivar.h,v 1.81 2016/01/10 16:59:41 kettenis Exp $ */ /* * Copyright (c) 2005 Thorsten Lockert * @@ -359,6 +359,9 @@ int acpi_release_glk(uint32_t *); void acpi_pciroots_attach(struct device *, void *, cfprint_t); +void *acpi_intr_establish(int, int, int, int (*)(void *), void *, + const char *); + #endif #endif /* !_ACPI_WAKECODE */ -- cgit v1.2.3