Changeset View
Changeset View
Standalone View
Standalone View
head/sys/dev/acpica/acpi_resource.c
Show First 20 Lines • Show All 49 Lines • ▼ Show 20 Lines | |||||
#endif | #endif | ||||
/* Hooks for the ACPI CA debugging infrastructure */ | /* Hooks for the ACPI CA debugging infrastructure */ | ||||
#define _COMPONENT ACPI_BUS | #define _COMPONENT ACPI_BUS | ||||
ACPI_MODULE_NAME("RESOURCE") | ACPI_MODULE_NAME("RESOURCE") | ||||
struct lookup_irq_request { | struct lookup_irq_request { | ||||
ACPI_RESOURCE *acpi_res; | ACPI_RESOURCE *acpi_res; | ||||
struct resource *res; | u_int irq; | ||||
int counter; | int counter; | ||||
int rid; | int rid; | ||||
int found; | int found; | ||||
int checkrid; | |||||
int trig; | |||||
int pol; | |||||
}; | }; | ||||
static ACPI_STATUS | static ACPI_STATUS | ||||
acpi_lookup_irq_handler(ACPI_RESOURCE *res, void *context) | acpi_lookup_irq_handler(ACPI_RESOURCE *res, void *context) | ||||
{ | { | ||||
struct lookup_irq_request *req; | struct lookup_irq_request *req; | ||||
size_t len; | size_t len; | ||||
u_int irqnum, irq; | u_int irqnum, irq, trig, pol; | ||||
switch (res->Type) { | switch (res->Type) { | ||||
case ACPI_RESOURCE_TYPE_IRQ: | case ACPI_RESOURCE_TYPE_IRQ: | ||||
irqnum = res->Data.Irq.InterruptCount; | irqnum = res->Data.Irq.InterruptCount; | ||||
irq = res->Data.Irq.Interrupts[0]; | irq = res->Data.Irq.Interrupts[0]; | ||||
len = ACPI_RS_SIZE(ACPI_RESOURCE_IRQ); | len = ACPI_RS_SIZE(ACPI_RESOURCE_IRQ); | ||||
trig = res->Data.Irq.Triggering; | |||||
pol = res->Data.Irq.Polarity; | |||||
break; | break; | ||||
case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: | case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: | ||||
irqnum = res->Data.ExtendedIrq.InterruptCount; | irqnum = res->Data.ExtendedIrq.InterruptCount; | ||||
irq = res->Data.ExtendedIrq.Interrupts[0]; | irq = res->Data.ExtendedIrq.Interrupts[0]; | ||||
len = ACPI_RS_SIZE(ACPI_RESOURCE_EXTENDED_IRQ); | len = ACPI_RS_SIZE(ACPI_RESOURCE_EXTENDED_IRQ); | ||||
trig = res->Data.ExtendedIrq.Triggering; | |||||
pol = res->Data.ExtendedIrq.Polarity; | |||||
break; | break; | ||||
default: | default: | ||||
return (AE_OK); | return (AE_OK); | ||||
} | } | ||||
if (irqnum != 1) | if (irqnum != 1) | ||||
return (AE_OK); | return (AE_OK); | ||||
req = (struct lookup_irq_request *)context; | req = (struct lookup_irq_request *)context; | ||||
if (req->checkrid) { | |||||
if (req->counter != req->rid) { | if (req->counter != req->rid) { | ||||
req->counter++; | req->counter++; | ||||
return (AE_OK); | return (AE_OK); | ||||
} | } | ||||
KASSERT(irq == req->irq, ("IRQ resources do not match")); | |||||
} else { | |||||
if (req->irq != irq) | |||||
return (AE_OK); | |||||
} | |||||
req->found = 1; | req->found = 1; | ||||
KASSERT(irq == rman_get_start(req->res), | req->pol = pol; | ||||
("IRQ resources do not match")); | req->trig = trig; | ||||
if (req->acpi_res != NULL) | |||||
bcopy(res, req->acpi_res, len); | bcopy(res, req->acpi_res, len); | ||||
return (AE_CTRL_TERMINATE); | return (AE_CTRL_TERMINATE); | ||||
} | } | ||||
ACPI_STATUS | ACPI_STATUS | ||||
acpi_lookup_irq_resource(device_t dev, int rid, struct resource *res, | acpi_lookup_irq_resource(device_t dev, int rid, struct resource *res, | ||||
ACPI_RESOURCE *acpi_res) | ACPI_RESOURCE *acpi_res) | ||||
{ | { | ||||
struct lookup_irq_request req; | struct lookup_irq_request req; | ||||
ACPI_STATUS status; | ACPI_STATUS status; | ||||
req.acpi_res = acpi_res; | req.acpi_res = acpi_res; | ||||
req.res = res; | req.irq = rman_get_start(res); | ||||
req.counter = 0; | req.counter = 0; | ||||
req.rid = rid; | req.rid = rid; | ||||
req.found = 0; | req.found = 0; | ||||
req.checkrid = 1; | |||||
status = AcpiWalkResources(acpi_get_handle(dev), "_CRS", | status = AcpiWalkResources(acpi_get_handle(dev), "_CRS", | ||||
acpi_lookup_irq_handler, &req); | acpi_lookup_irq_handler, &req); | ||||
if (ACPI_SUCCESS(status) && req.found == 0) | if (ACPI_SUCCESS(status) && req.found == 0) | ||||
status = AE_NOT_FOUND; | status = AE_NOT_FOUND; | ||||
return (status); | return (status); | ||||
} | } | ||||
void | void | ||||
Show All 31 Lines | #if defined(__amd64__) || defined(__i386__) | ||||
if (irq < 16 && trig == ACPI_EDGE_SENSITIVE && pol == ACPI_ACTIVE_LOW) | if (irq < 16 && trig == ACPI_EDGE_SENSITIVE && pol == ACPI_ACTIVE_LOW) | ||||
pol = ACPI_ACTIVE_HIGH; | pol = ACPI_ACTIVE_HIGH; | ||||
#endif | #endif | ||||
BUS_CONFIG_INTR(dev, irq, (trig == ACPI_EDGE_SENSITIVE) ? | BUS_CONFIG_INTR(dev, irq, (trig == ACPI_EDGE_SENSITIVE) ? | ||||
INTR_TRIGGER_EDGE : INTR_TRIGGER_LEVEL, (pol == ACPI_ACTIVE_HIGH) ? | INTR_TRIGGER_EDGE : INTR_TRIGGER_LEVEL, (pol == ACPI_ACTIVE_HIGH) ? | ||||
INTR_POLARITY_HIGH : INTR_POLARITY_LOW); | INTR_POLARITY_HIGH : INTR_POLARITY_LOW); | ||||
} | } | ||||
#ifdef INTRNG | |||||
int | |||||
acpi_map_intr(device_t dev, u_int irq, ACPI_HANDLE handle) | |||||
{ | |||||
struct lookup_irq_request req; | |||||
int trig, pol; | |||||
trig = ACPI_LEVEL_SENSITIVE; | |||||
pol = ACPI_ACTIVE_HIGH; | |||||
if (handle != NULL) { | |||||
req.found = 0; | |||||
req.acpi_res = NULL; | |||||
req.irq = irq; | |||||
req.counter = 0; | |||||
req.rid = 0; | |||||
req.checkrid = 0; | |||||
AcpiWalkResources(handle, "_CRS", acpi_lookup_irq_handler, &req); | |||||
if (req.found != 0) { | |||||
trig = req.trig; | |||||
pol = req.pol; | |||||
} | |||||
} | |||||
return ACPI_BUS_MAP_INTR(device_get_parent(dev), dev, irq, | |||||
(trig == ACPI_EDGE_SENSITIVE) ? INTR_TRIGGER_EDGE : INTR_TRIGGER_LEVEL, | |||||
(pol == ACPI_ACTIVE_HIGH) ? INTR_POLARITY_HIGH : INTR_POLARITY_LOW); | |||||
} | |||||
#endif | |||||
struct acpi_resource_context { | struct acpi_resource_context { | ||||
struct acpi_parse_resource_set *set; | struct acpi_parse_resource_set *set; | ||||
device_t dev; | device_t dev; | ||||
void *context; | void *context; | ||||
}; | }; | ||||
#ifdef ACPI_DEBUG_OUTPUT | #ifdef ACPI_DEBUG_OUTPUT | ||||
static const char * | static const char * | ||||
▲ Show 20 Lines • Show All 420 Lines • ▼ Show 20 Lines | acpi_res_set_irq(device_t dev, void *context, uint8_t *irq, int count, | ||||
if (cp == NULL || irq == NULL) | if (cp == NULL || irq == NULL) | ||||
return; | return; | ||||
/* This implements no resource relocation. */ | /* This implements no resource relocation. */ | ||||
if (count != 1) | if (count != 1) | ||||
return; | return; | ||||
#ifdef INTRNG | |||||
intr = ACPI_BUS_MAP_INTR(device_get_parent(dev), dev, *irq, | |||||
(trig == ACPI_EDGE_SENSITIVE) ? INTR_TRIGGER_EDGE : INTR_TRIGGER_LEVEL, | |||||
(pol == ACPI_ACTIVE_HIGH) ? INTR_POLARITY_HIGH : INTR_POLARITY_LOW); | |||||
#else | |||||
intr = *irq; | intr = *irq; | ||||
#endif | |||||
bus_set_resource(dev, SYS_RES_IRQ, cp->ar_nirq++, intr, 1); | bus_set_resource(dev, SYS_RES_IRQ, cp->ar_nirq++, intr, 1); | ||||
} | } | ||||
static void | static void | ||||
acpi_res_set_ext_irq(device_t dev, void *context, uint32_t *irq, int count, | acpi_res_set_ext_irq(device_t dev, void *context, uint32_t *irq, int count, | ||||
int trig, int pol) | int trig, int pol) | ||||
{ | { | ||||
struct acpi_res_context *cp = (struct acpi_res_context *)context; | struct acpi_res_context *cp = (struct acpi_res_context *)context; | ||||
rman_res_t intr; | rman_res_t intr; | ||||
if (cp == NULL || irq == NULL) | if (cp == NULL || irq == NULL) | ||||
return; | return; | ||||
/* This implements no resource relocation. */ | /* This implements no resource relocation. */ | ||||
if (count != 1) | if (count != 1) | ||||
return; | return; | ||||
#ifdef INTRNG | |||||
intr = ACPI_BUS_MAP_INTR(device_get_parent(dev), dev, *irq, | |||||
(trig == ACPI_EDGE_SENSITIVE) ? INTR_TRIGGER_EDGE : INTR_TRIGGER_LEVEL, | |||||
(pol == ACPI_ACTIVE_HIGH) ? INTR_POLARITY_HIGH : INTR_POLARITY_LOW); | |||||
#else | |||||
intr = *irq; | intr = *irq; | ||||
#endif | |||||
bus_set_resource(dev, SYS_RES_IRQ, cp->ar_nirq++, intr, 1); | bus_set_resource(dev, SYS_RES_IRQ, cp->ar_nirq++, intr, 1); | ||||
} | } | ||||
static void | static void | ||||
acpi_res_set_drq(device_t dev, void *context, uint8_t *drq, int count) | acpi_res_set_drq(device_t dev, void *context, uint8_t *drq, int count) | ||||
{ | { | ||||
struct acpi_res_context *cp = (struct acpi_res_context *)context; | struct acpi_res_context *cp = (struct acpi_res_context *)context; | ||||
▲ Show 20 Lines • Show All 145 Lines • Show Last 20 Lines |