aboutsummaryrefslogtreecommitdiff
path: root/sys/i386
diff options
context:
space:
mode:
authorJohn Baldwin <jhb@FreeBSD.org>2008-03-20 21:24:32 +0000
committerJohn Baldwin <jhb@FreeBSD.org>2008-03-20 21:24:32 +0000
commitdcc8106854ab911281cbeb98d0bff04f50e7531c (patch)
tree885a4249c364d8b7ce6b6edbc94f378c0e100668 /sys/i386
parent471798c3104b9133e410d898ed2a0f9aae852811 (diff)
downloadsrc-dcc8106854ab911281cbeb98d0bff04f50e7531c.tar.gz
src-dcc8106854ab911281cbeb98d0bff04f50e7531c.zip
Implement a BUS_BIND_INTR() method in the bus interface to bind an IRQ
resource to a CPU. The default method is to pass the request up to the parent similar to BUS_CONFIG_INTR() so that all busses don't have to explicitly implement bus_bind_intr. A bus_bind_intr(9) wrapper routine similar to bus_setup/teardown_intr() is added for device drivers to use. Unbinding an interrupt is done by binding it to NOCPU. The IRQ resource must be allocated, but it can happen in any order with respect to bus_setup_intr(). Currently it is only supported on amd64 and i386 via nexus(4) methods that simply call the intr_bind() routine. Tested by: gallatin
Notes
Notes: svn path=/head/; revision=177467
Diffstat (limited to 'sys/i386')
-rw-r--r--sys/i386/i386/nexus.c14
1 files changed, 14 insertions, 0 deletions
diff --git a/sys/i386/i386/nexus.c b/sys/i386/i386/nexus.c
index 0c09c3467759..98adc933a23b 100644
--- a/sys/i386/i386/nexus.c
+++ b/sys/i386/i386/nexus.c
@@ -91,6 +91,9 @@ static device_t nexus_add_child(device_t bus, int order, const char *name,
int unit);
static struct resource *nexus_alloc_resource(device_t, device_t, int, int *,
u_long, u_long, u_long, u_int);
+#ifdef SMP
+static int nexus_bind_intr(device_t, device_t, struct resource *, int);
+#endif
static int nexus_config_intr(device_t, int, enum intr_trigger,
enum intr_polarity);
static int nexus_activate_resource(device_t, device_t, int, int,
@@ -134,6 +137,9 @@ static device_method_t nexus_methods[] = {
DEVMETHOD(bus_deactivate_resource, nexus_deactivate_resource),
DEVMETHOD(bus_setup_intr, nexus_setup_intr),
DEVMETHOD(bus_teardown_intr, nexus_teardown_intr),
+#ifdef SMP
+ DEVMETHOD(bus_bind_intr, nexus_bind_intr),
+#endif
DEVMETHOD(bus_config_intr, nexus_config_intr),
DEVMETHOD(bus_get_resource_list, nexus_get_reslist),
DEVMETHOD(bus_set_resource, nexus_set_resource),
@@ -505,6 +511,14 @@ nexus_teardown_intr(device_t dev, device_t child, struct resource *r, void *ih)
return (intr_remove_handler(ih));
}
+#ifdef SMP
+static int
+nexus_bind_intr(device_t dev, device_t child, struct resource *irq, int cpu)
+{
+ return (intr_bind(rman_get_start(irq), cpu));
+}
+#endif
+
static int
nexus_config_intr(device_t dev, int irq, enum intr_trigger trig,
enum intr_polarity pol)