Changeset View
Changeset View
Standalone View
Standalone View
sys/kern/subr_intr.c
Show First 20 Lines • Show All 58 Lines • ▼ Show 20 Lines | |||||
#endif | #endif | ||||
#include <machine/atomic.h> | #include <machine/atomic.h> | ||||
#include <machine/intr.h> | #include <machine/intr.h> | ||||
#include <machine/cpu.h> | #include <machine/cpu.h> | ||||
#include <machine/smp.h> | #include <machine/smp.h> | ||||
#include <machine/stdarg.h> | #include <machine/stdarg.h> | ||||
#ifdef FDT | |||||
#include <dev/ofw/openfirm.h> | |||||
#include <dev/ofw/ofw_bus.h> | |||||
#include <dev/ofw/ofw_bus_subr.h> | |||||
#endif | |||||
#ifdef DDB | #ifdef DDB | ||||
#include <ddb/ddb.h> | #include <ddb/ddb.h> | ||||
#endif | #endif | ||||
#include "pic_if.h" | #include "pic_if.h" | ||||
#include "msi_if.h" | #include "msi_if.h" | ||||
#define INTRNAME_LEN (2*MAXCOMLEN + 1) | #define INTRNAME_LEN (2*MAXCOMLEN + 1) | ||||
▲ Show 20 Lines • Show All 505 Lines • ▼ Show 20 Lines | intr_acpi_map_irq(device_t dev, u_int irq, enum intr_polarity pol, | ||||
daa = (struct intr_map_data_acpi *)ddata->idd_data; | daa = (struct intr_map_data_acpi *)ddata->idd_data; | ||||
daa->irq = irq; | daa->irq = irq; | ||||
daa->pol = pol; | daa->pol = pol; | ||||
daa->trig = trig; | daa->trig = trig; | ||||
return (ddata->idd_irq); | return (ddata->idd_irq); | ||||
} | } | ||||
#endif | #endif | ||||
#ifdef FDT | |||||
/* | |||||
* Map interrupt source according to FDT data into framework. If such mapping | |||||
* does not exist, create it. Return unique interrupt number (resource handle) | |||||
* associated with mapped interrupt source. | |||||
*/ | |||||
u_int | |||||
intr_fdt_map_irq(phandle_t node, pcell_t *cells, u_int ncells) | |||||
{ | |||||
size_t cellsize; | |||||
struct intr_dev_data *ddata; | |||||
struct intr_map_data_fdt *daf; | |||||
cellsize = ncells * sizeof(*cells); | |||||
ddata = intr_ddata_alloc(sizeof(struct intr_map_data_fdt) + cellsize); | |||||
if (ddata == NULL) | |||||
return (INTR_IRQ_INVALID); /* no space left */ | |||||
ddata->idd_xref = (intptr_t)node; | |||||
ddata->idd_data->type = INTR_MAP_DATA_FDT; | |||||
daf = (struct intr_map_data_fdt *)ddata->idd_data; | |||||
daf->ncells = ncells; | |||||
memcpy(daf->cells, cells, cellsize); | |||||
return (ddata->idd_irq); | |||||
} | |||||
#endif | |||||
/* | /* | ||||
* Store GPIO interrupt decription in framework and return unique interrupt | * Store GPIO interrupt decription in framework and return unique interrupt | ||||
* number (resource handle) associated with it. | * number (resource handle) associated with it. | ||||
*/ | */ | ||||
u_int | u_int | ||||
intr_gpio_map_irq(device_t dev, u_int pin_num, u_int pin_flags, u_int intr_mode) | intr_gpio_map_irq(device_t dev, u_int pin_num, u_int pin_flags, u_int intr_mode) | ||||
{ | { | ||||
struct intr_dev_data *ddata; | struct intr_dev_data *ddata; | ||||
▲ Show 20 Lines • Show All 399 Lines • ▼ Show 20 Lines | |||||
intr_alloc_irq(device_t dev, struct resource *res) | intr_alloc_irq(device_t dev, struct resource *res) | ||||
{ | { | ||||
struct intr_map_data *data; | struct intr_map_data *data; | ||||
struct intr_irqsrc *isrc; | struct intr_irqsrc *isrc; | ||||
KASSERT(rman_get_start(res) == rman_get_end(res), | KASSERT(rman_get_start(res) == rman_get_end(res), | ||||
("%s: more interrupts in resource", __func__)); | ("%s: more interrupts in resource", __func__)); | ||||
data = rman_get_virtual(res); | |||||
if (data == NULL) | |||||
isrc = intr_ddata_lookup(rman_get_start(res), &data); | isrc = intr_ddata_lookup(rman_get_start(res), &data); | ||||
else | |||||
isrc = isrc_lookup(rman_get_start(res)); | |||||
if (isrc == NULL) | if (isrc == NULL) | ||||
return (EINVAL); | return (EINVAL); | ||||
return (PIC_ALLOC_INTR(isrc->isrc_dev, isrc, res, data)); | return (PIC_ALLOC_INTR(isrc->isrc_dev, isrc, res, data)); | ||||
} | } | ||||
int | int | ||||
intr_release_irq(device_t dev, struct resource *res) | intr_release_irq(device_t dev, struct resource *res) | ||||
{ | { | ||||
struct intr_map_data *data; | struct intr_map_data *data; | ||||
struct intr_irqsrc *isrc; | struct intr_irqsrc *isrc; | ||||
KASSERT(rman_get_start(res) == rman_get_end(res), | KASSERT(rman_get_start(res) == rman_get_end(res), | ||||
("%s: more interrupts in resource", __func__)); | ("%s: more interrupts in resource", __func__)); | ||||
data = rman_get_virtual(res); | |||||
if (data == NULL) | |||||
isrc = intr_ddata_lookup(rman_get_start(res), &data); | isrc = intr_ddata_lookup(rman_get_start(res), &data); | ||||
else | |||||
isrc = isrc_lookup(rman_get_start(res)); | |||||
if (isrc == NULL) | if (isrc == NULL) | ||||
return (EINVAL); | return (EINVAL); | ||||
return (PIC_RELEASE_INTR(isrc->isrc_dev, isrc, res, data)); | return (PIC_RELEASE_INTR(isrc->isrc_dev, isrc, res, data)); | ||||
} | } | ||||
int | int | ||||
intr_setup_irq(device_t dev, struct resource *res, driver_filter_t filt, | intr_setup_irq(device_t dev, struct resource *res, driver_filter_t filt, | ||||
driver_intr_t hand, void *arg, int flags, void **cookiep) | driver_intr_t hand, void *arg, int flags, void **cookiep) | ||||
{ | { | ||||
int error; | int error; | ||||
struct intr_map_data *data; | struct intr_map_data *data; | ||||
struct intr_irqsrc *isrc; | struct intr_irqsrc *isrc; | ||||
const char *name; | const char *name; | ||||
KASSERT(rman_get_start(res) == rman_get_end(res), | KASSERT(rman_get_start(res) == rman_get_end(res), | ||||
("%s: more interrupts in resource", __func__)); | ("%s: more interrupts in resource", __func__)); | ||||
data = rman_get_virtual(res); | |||||
if (data == NULL) | |||||
isrc = intr_ddata_lookup(rman_get_start(res), &data); | isrc = intr_ddata_lookup(rman_get_start(res), &data); | ||||
else | |||||
isrc = isrc_lookup(rman_get_start(res)); | |||||
if (isrc == NULL) | if (isrc == NULL) | ||||
return (EINVAL); | return (EINVAL); | ||||
name = device_get_nameunit(dev); | name = device_get_nameunit(dev); | ||||
#ifdef INTR_SOLO | #ifdef INTR_SOLO | ||||
/* | /* | ||||
* Standard handling is done through MI interrupt framework. However, | * Standard handling is done through MI interrupt framework. However, | ||||
▲ Show 20 Lines • Show All 43 Lines • ▼ Show 20 Lines | |||||
{ | { | ||||
int error; | int error; | ||||
struct intr_map_data *data; | struct intr_map_data *data; | ||||
struct intr_irqsrc *isrc; | struct intr_irqsrc *isrc; | ||||
KASSERT(rman_get_start(res) == rman_get_end(res), | KASSERT(rman_get_start(res) == rman_get_end(res), | ||||
("%s: more interrupts in resource", __func__)); | ("%s: more interrupts in resource", __func__)); | ||||
data = rman_get_virtual(res); | |||||
if (data == NULL) | |||||
isrc = intr_ddata_lookup(rman_get_start(res), &data); | isrc = intr_ddata_lookup(rman_get_start(res), &data); | ||||
else | |||||
isrc = isrc_lookup(rman_get_start(res)); | |||||
if (isrc == NULL || isrc->isrc_handlers == 0) | if (isrc == NULL || isrc->isrc_handlers == 0) | ||||
return (EINVAL); | return (EINVAL); | ||||
#ifdef INTR_SOLO | #ifdef INTR_SOLO | ||||
if (isrc->isrc_filter != NULL) { | if (isrc->isrc_filter != NULL) { | ||||
if (isrc != cookie) | if (isrc != cookie) | ||||
return (EINVAL); | return (EINVAL); | ||||
▲ Show 20 Lines • Show All 348 Lines • Show Last 20 Lines |