Index: sys/arm64/arm64/intr_machdep.c =================================================================== --- sys/arm64/arm64/intr_machdep.c +++ sys/arm64/arm64/intr_machdep.c @@ -446,6 +446,13 @@ critical_exit(); } +void +arm_unmask_irq(u_int irq) +{ + + PIC_UNMASK(root_pic, irq); +} + #ifdef SMP void arm_setup_ipihandler(driver_filter_t *filt, u_int ipi) Index: sys/arm64/arm64/nexus.c =================================================================== --- sys/arm64/arm64/nexus.c +++ sys/arm64/arm64/nexus.c @@ -112,6 +112,7 @@ static int nexus_setup_intr(device_t dev, device_t child, struct resource *res, int flags, driver_filter_t *filt, driver_intr_t *intr, void *arg, void **cookiep); static int nexus_teardown_intr(device_t, device_t, struct resource *, void *); +static int nexus_unmask_intr(device_t, device_t, struct resource *); #ifdef FDT static int nexus_ofw_map_intr(device_t dev, device_t child, phandle_t iparent, @@ -130,6 +131,7 @@ DEVMETHOD(bus_deactivate_resource, nexus_deactivate_resource), DEVMETHOD(bus_setup_intr, nexus_setup_intr), DEVMETHOD(bus_teardown_intr, nexus_teardown_intr), + DEVMETHOD(bus_unmask_intr, nexus_unmask_intr), { 0, 0 } }; @@ -288,6 +290,18 @@ } static int +nexus_unmask_intr(device_t dev, device_t child, struct resource *res) +{ + + if (res == NULL) + return (EINVAL); + + arm_unmask_irq(rman_get_start(res)); + + return (0); +} + +static int nexus_teardown_intr(device_t dev, device_t child, struct resource *r, void *ih) { Index: sys/dev/fdt/simplebus.c =================================================================== --- sys/dev/fdt/simplebus.c +++ sys/dev/fdt/simplebus.c @@ -85,6 +85,7 @@ DEVMETHOD(bus_read_ivar, bus_generic_read_ivar), DEVMETHOD(bus_write_ivar, bus_generic_write_ivar), DEVMETHOD(bus_setup_intr, bus_generic_setup_intr), + DEVMETHOD(bus_unmask_intr, bus_generic_unmask_intr), DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr), DEVMETHOD(bus_alloc_resource, simplebus_alloc_resource), DEVMETHOD(bus_release_resource, bus_generic_release_resource), Index: sys/kern/bus_if.m =================================================================== --- sys/kern/bus_if.m +++ sys/kern/bus_if.m @@ -390,6 +390,21 @@ }; /** + * @brief Unmask an interrupt handler + * + * This method is used to mask the previously set up interrupt. + * + * @param _dev the parent device of @p _child + * @param _child the device which allocated the resource + * @param _irq the resource representing the interrupt + */ +METHOD int unmask_intr { + device_t _dev; + device_t _child; + struct resource *_irq; +}; + +/** * @brief Uninstall an interrupt handler * * This method is used to disassociate an interrupt handler function Index: sys/kern/subr_bus.c =================================================================== --- sys/kern/subr_bus.c +++ sys/kern/subr_bus.c @@ -3926,6 +3926,23 @@ } /** + * @brief Helper function for implementing BUS_UNMASK_INTR(). + * + * This simple implementation of BUS_UNMASK_INTR() simply calls the + * BUS_UNMASK_INTR() method of the parent of @p dev. + */ +int +bus_generic_unmask_intr(device_t dev, device_t child, struct resource *irq) +{ + + /* Propagate up the bus hierarchy until someone handles it. */ + if (dev->parent) + return (BUS_UNMASK_INTR(dev->parent, child, irq)); + + return (EINVAL); +} + +/** * @brief Helper function for implementing BUS_TEARDOWN_INTR(). * * This simple implementation of BUS_TEARDOWN_INTR() simply calls the @@ -4379,6 +4396,27 @@ } /** + * @brief Wrapper function for BUS_UNMASK_INTR(). + * + * This function simply calls the BUS_UNMASK_INTR() method of the + * parent of @p dev. + */ +int +bus_unmask_intr(device_t dev, struct resource *r) +{ + int error; + + if (dev->parent == NULL) + return (EINVAL); + + error = BUS_UNMASK_INTR(dev->parent, dev, r); + if (error != 0) + return (error); + + return (0); +} + +/** * @brief Wrapper function for BUS_TEARDOWN_INTR(). * * This function simply calls the BUS_TEARDOWN_INTR() method of the Index: sys/sys/bus.h =================================================================== --- sys/sys/bus.h +++ sys/sys/bus.h @@ -402,6 +402,8 @@ struct resource *irq, int flags, driver_filter_t *filter, driver_intr_t *intr, void *arg, void **cookiep); +int bus_generic_unmask_intr(device_t dev, device_t child, + struct resource *irq); struct resource * bus_generic_rl_alloc_resource (device_t, device_t, int, int *, @@ -456,6 +458,7 @@ driver_filter_t filter, driver_intr_t handler, void *arg, void **cookiep); int bus_teardown_intr(device_t dev, struct resource *r, void *cookie); +int bus_unmask_intr(device_t dev, struct resource *r); int bus_bind_intr(device_t dev, struct resource *r, int cpu); int bus_describe_intr(device_t dev, struct resource *irq, void *cookie, const char *fmt, ...);