Teach the bridge wrapper how to handle the filter+ithread case.
Reviewed by: marius
This commit is contained in:
parent
8d715a3523
commit
f9a41a1101
@ -51,7 +51,8 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sparc64/sbus/ofw_sbus.h>
|
||||
|
||||
struct fhc_clr {
|
||||
driver_filter_t *fc_func;
|
||||
driver_filter_t *fc_filter;
|
||||
driver_intr_t *fc_func;
|
||||
void *fc_arg;
|
||||
void *fc_cookie;
|
||||
bus_space_tag_t fc_bt;
|
||||
@ -86,7 +87,8 @@ static bus_alloc_resource_t fhc_alloc_resource;
|
||||
static bus_get_resource_list_t fhc_get_resource_list;
|
||||
static ofw_bus_get_devinfo_t fhc_get_devinfo;
|
||||
|
||||
static driver_filter_t fhc_intr_stub;
|
||||
static driver_filter_t fhc_filter_stub;
|
||||
static driver_intr_t fhc_intr_stub;
|
||||
static void fhc_led_func(void *, int);
|
||||
static int fhc_print_res(struct fhc_devinfo *);
|
||||
|
||||
@ -351,7 +353,8 @@ fhc_setup_intr(device_t bus, device_t child, struct resource *r, int flags,
|
||||
fc = malloc(sizeof(*fc), M_DEVBUF, M_WAITOK | M_ZERO);
|
||||
if (fc == NULL)
|
||||
return (0);
|
||||
fc->fc_func = (filt != NULL) ? filt : (driver_filter_t *)func;
|
||||
fc->fc_filter = filt;
|
||||
fc->fc_func = func;
|
||||
fc->fc_arg = arg;
|
||||
fc->fc_bt = bt;
|
||||
fc->fc_bh = bh;
|
||||
@ -359,12 +362,8 @@ fhc_setup_intr(device_t bus, device_t child, struct resource *r, int flags,
|
||||
bus_space_write_4(bt, bh, FHC_IMAP, inr);
|
||||
bus_space_read_4(bt, bh, FHC_IMAP);
|
||||
|
||||
if (filt != NULL)
|
||||
error = bus_generic_setup_intr(bus, child, r, flags,
|
||||
fhc_intr_stub, NULL, fc, cookiep);
|
||||
else
|
||||
error = bus_generic_setup_intr(bus, child, r, flags,
|
||||
NULL, (driver_intr_t *)fhc_intr_stub, fc, cookiep);
|
||||
error = bus_generic_setup_intr(bus, child, r, flags, fhc_filter_stub,
|
||||
fhc_intr_stub, fc, cookiep);
|
||||
if (error != 0) {
|
||||
free(fc, M_DEVBUF);
|
||||
return (error);
|
||||
@ -394,15 +393,31 @@ fhc_teardown_intr(device_t bus, device_t child, struct resource *r,
|
||||
}
|
||||
|
||||
static int
|
||||
fhc_filter_stub(void *arg)
|
||||
{
|
||||
struct fhc_clr *fc = arg;
|
||||
int res;
|
||||
|
||||
if (fc->fc_filter != NULL) {
|
||||
res = fc->fc_filter(fc->fc_arg);
|
||||
bus_space_write_4(fc->fc_bt, fc->fc_bh, FHC_ICLR, 0x0);
|
||||
bus_space_read_4(fc->fc_bt, fc->fc_bh, FHC_ICLR);
|
||||
} else
|
||||
res = FILTER_SCHEDULE_THREAD;
|
||||
|
||||
return (res);
|
||||
}
|
||||
|
||||
static void
|
||||
fhc_intr_stub(void *arg)
|
||||
{
|
||||
struct fhc_clr *fc = arg;
|
||||
|
||||
fc->fc_func(fc->fc_arg);
|
||||
|
||||
bus_space_write_4(fc->fc_bt, fc->fc_bh, FHC_ICLR, 0x0);
|
||||
bus_space_read_4(fc->fc_bt, fc->fc_bh, FHC_ICLR);
|
||||
return (FILTER_HANDLED);
|
||||
if (fc->fc_filter == NULL) {
|
||||
bus_space_write_4(fc->fc_bt, fc->fc_bh, FHC_ICLR, 0x0);
|
||||
bus_space_read_4(fc->fc_bt, fc->fc_bh, FHC_ICLR);
|
||||
}
|
||||
}
|
||||
|
||||
static struct resource *
|
||||
|
@ -82,7 +82,8 @@ static void psycho_set_intr(struct psycho_softc *, int, bus_addr_t, int,
|
||||
driver_filter_t);
|
||||
static int psycho_find_intrmap(struct psycho_softc *, int, bus_addr_t *,
|
||||
bus_addr_t *, u_long *);
|
||||
static driver_filter_t psycho_intr_stub;
|
||||
static driver_filter_t psycho_filter_stub;
|
||||
static driver_intr_t psycho_intr_stub;
|
||||
static bus_space_tag_t psycho_alloc_bus_tag(struct psycho_softc *, int);
|
||||
|
||||
/* Interrupt handlers */
|
||||
@ -170,7 +171,8 @@ SLIST_HEAD(, psycho_softc) psycho_softcs =
|
||||
struct psycho_clr {
|
||||
struct psycho_softc *pci_sc;
|
||||
bus_addr_t pci_clr; /* clear register */
|
||||
driver_filter_t *pci_handler; /* handler to call */
|
||||
driver_filter_t *pci_filter;
|
||||
driver_intr_t *pci_handler; /* handler to call */
|
||||
void *pci_arg; /* argument for the handler */
|
||||
void *pci_cookie; /* parent bus int. cookie */
|
||||
device_t pci_ppb; /* farest PCI-PCI bridge */
|
||||
@ -982,6 +984,20 @@ psycho_read_ivar(device_t dev, device_t child, int which, uintptr_t *result)
|
||||
|
||||
/* Write to the correct clr register, and call the actual handler. */
|
||||
static int
|
||||
psycho_filter_stub(void *arg)
|
||||
{
|
||||
struct psycho_clr *pc = arg;
|
||||
int res;
|
||||
|
||||
if (pc->pci_filter != NULL) {
|
||||
res = pc->pci_filter(pc->pci_arg);
|
||||
PSYCHO_WRITE8(pc->pci_sc, pc->pci_clr, 0);
|
||||
} else
|
||||
res = FILTER_SCHEDULE_THREAD;
|
||||
return (res);
|
||||
}
|
||||
|
||||
static void
|
||||
psycho_intr_stub(void *arg)
|
||||
{
|
||||
struct psycho_clr *pc = arg;
|
||||
@ -992,8 +1008,8 @@ psycho_intr_stub(void *arg)
|
||||
(void)PSYCHO_READ8(pc->pci_sc, PSR_DMA_WRITE_SYNC);
|
||||
}
|
||||
pc->pci_handler(pc->pci_arg);
|
||||
PSYCHO_WRITE8(pc->pci_sc, pc->pci_clr, 0);
|
||||
return (FILTER_HANDLED);
|
||||
if (pc->pci_filter == NULL)
|
||||
PSYCHO_WRITE8(pc->pci_sc, pc->pci_clr, 0);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -1046,7 +1062,8 @@ psycho_setup_intr(device_t dev, device_t child, struct resource *ires,
|
||||
|
||||
pc->pci_sc = sc;
|
||||
pc->pci_arg = arg;
|
||||
pc->pci_handler = (filt != NULL) ? filt : (driver_filter_t *)intr;
|
||||
pc->pci_filter = filt;
|
||||
pc->pci_handler = intr;
|
||||
pc->pci_clr = intrclrptr;
|
||||
|
||||
/*
|
||||
@ -1102,12 +1119,8 @@ psycho_setup_intr(device_t dev, device_t child, struct resource *ires,
|
||||
/* Disable the interrupt while we fiddle with it. */
|
||||
mr = PSYCHO_READ8(sc, intrmapptr);
|
||||
PSYCHO_WRITE8(sc, intrmapptr, mr & ~INTMAP_V);
|
||||
if (filt != NULL)
|
||||
error = BUS_SETUP_INTR(device_get_parent(dev), child, ires, flags,
|
||||
psycho_intr_stub, NULL, pc, cookiep);
|
||||
else
|
||||
error = BUS_SETUP_INTR(device_get_parent(dev), child, ires, flags,
|
||||
NULL, (driver_intr_t *)psycho_intr_stub, pc, cookiep);
|
||||
error = BUS_SETUP_INTR(device_get_parent(dev), child, ires, flags,
|
||||
psycho_filter_stub, psycho_intr_stub, pc, cookiep);
|
||||
if (error != 0) {
|
||||
free(pc, M_DEVBUF);
|
||||
return (error);
|
||||
|
@ -176,7 +176,8 @@ struct sbus_softc {
|
||||
struct sbus_clr {
|
||||
struct sbus_softc *scl_sc;
|
||||
bus_addr_t scl_clr; /* clear register */
|
||||
driver_filter_t *scl_handler; /* handler to call */
|
||||
driver_filter_t *scl_filter;
|
||||
driver_intr_t *scl_handler; /* handler to call */
|
||||
void *scl_arg; /* argument for the handler */
|
||||
void *scl_cookie; /* parent bus int. cookie */
|
||||
};
|
||||
@ -205,7 +206,8 @@ static int sbus_inlist(const char *, const char **);
|
||||
static struct sbus_devinfo * sbus_setup_dinfo(device_t, struct sbus_softc *,
|
||||
phandle_t);
|
||||
static void sbus_destroy_dinfo(struct sbus_devinfo *);
|
||||
static driver_filter_t sbus_intr_stub;
|
||||
static driver_filter_t sbus_filter_stub;
|
||||
static driver_intr_t sbus_intr_stub;
|
||||
static bus_space_tag_t sbus_alloc_bustag(struct sbus_softc *);
|
||||
static driver_filter_t sbus_overtemp;
|
||||
static driver_filter_t sbus_pwrfail;
|
||||
@ -627,14 +629,29 @@ sbus_get_resource_list(device_t dev, device_t child)
|
||||
|
||||
/* Write to the correct clr register, and call the actual handler. */
|
||||
static int
|
||||
sbus_filter_stub(void *arg)
|
||||
{
|
||||
struct sbus_clr *scl;
|
||||
int res;
|
||||
|
||||
scl = (struct sbus_clr *)arg;
|
||||
if (scl->scl_filter != NULL) {
|
||||
res = scl->scl_filter(scl->scl_arg);
|
||||
SYSIO_WRITE8(scl->scl_sc, scl->scl_clr, 0);
|
||||
} else
|
||||
res = FILTER_SCHEDULE_THREAD;
|
||||
return (res);
|
||||
}
|
||||
|
||||
static void
|
||||
sbus_intr_stub(void *arg)
|
||||
{
|
||||
struct sbus_clr *scl;
|
||||
|
||||
scl = (struct sbus_clr *)arg;
|
||||
scl->scl_handler(scl->scl_arg);
|
||||
SYSIO_WRITE8(scl->scl_sc, scl->scl_clr, 0);
|
||||
return (FILTER_HANDLED);
|
||||
if (scl->scl_filter == NULL)
|
||||
SYSIO_WRITE8(scl->scl_sc, scl->scl_clr, 0);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -689,17 +706,13 @@ sbus_setup_intr(device_t dev, device_t child, struct resource *ires, int flags,
|
||||
|
||||
scl->scl_sc = sc;
|
||||
scl->scl_arg = arg;
|
||||
scl->scl_handler = (filt != NULL) ? filt : (driver_filter_t *)intr;
|
||||
scl->scl_filter = filt;
|
||||
scl->scl_handler = intr;
|
||||
scl->scl_clr = intrclrptr;
|
||||
/* Disable the interrupt while we fiddle with it */
|
||||
SYSIO_WRITE8(sc, intrmapptr, intrmap & ~INTMAP_V);
|
||||
if (filt != NULL)
|
||||
error = BUS_SETUP_INTR(device_get_parent(dev), child, ires,
|
||||
flags, sbus_intr_stub, NULL, scl, cookiep);
|
||||
else
|
||||
error = BUS_SETUP_INTR(device_get_parent(dev), child, ires,
|
||||
flags, NULL, (driver_intr_t *)sbus_intr_stub, scl,
|
||||
cookiep);
|
||||
error = BUS_SETUP_INTR(device_get_parent(dev), child, ires, flags,
|
||||
sbus_filter_stub, sbus_intr_stub, scl, cookiep);
|
||||
if (error != 0) {
|
||||
free(scl, M_DEVBUF);
|
||||
return (error);
|
||||
|
Loading…
x
Reference in New Issue
Block a user