Index: head/share/man/man9/Makefile =================================================================== --- head/share/man/man9/Makefile +++ head/share/man/man9/Makefile @@ -34,6 +34,7 @@ BUS_CHILD_DELETED.9 \ BUS_CHILD_DETACHED.9 \ BUS_CONFIG_INTR.9 \ + bus_delayed_attach_children.9 \ BUS_DESCRIBE_INTR.9 \ bus_dma.9 \ bus_generic_attach.9 \ Index: head/share/man/man9/bus_delayed_attach_children.9 =================================================================== --- head/share/man/man9/bus_delayed_attach_children.9 +++ head/share/man/man9/bus_delayed_attach_children.9 @@ -0,0 +1,55 @@ +.\" -*- nroff -*- +.\" +.\" Copyright (c) 2019 M. Warner Losh +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY EXPRESS OR +.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +.\" IN NO EVENT SHALL THE DEVELOPERS BE LIABLE FOR ANY DIRECT, INDIRECT, +.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.\" $FreeBSD$ +.\" +.Dd August 29, 2019 +.Dt BUS_DELAYED_ATTACH_CHILDREN 9 +.Os +.Sh NAME +.Nm bus_delayed_attach_children +.Nd "request that the children be attached when interrupts are enabled" +.Sh SYNOPSIS +.In sys/param.h +.In sys/bus.h +.Pp +.Ft int +.Fn bus_delayed_attach_children "device_t dev" +.Sh DESCRIPTION +The +.Fn bus_delayed_attach_children +function requests that the children of this device +be attached when interrupts are running. +If interrupts are currently running, this happens immediately. +If interrupts aren't yet running, this happens after interrupts are enabled, but +before the system mounts root. +.Sh RETURN VALUES +A zero return value indicates success. +.Sh SEE ALSO +.Xr bus 9 , +.Xr device 9 , +.Xr driver 9 +.Sh AUTHORS +This manual page was written by +.An Warner Losh Aq Mt imp@FreeBSD.org . Index: head/sys/arm/broadcom/bcm2835/bcm2835_bsc.c =================================================================== --- head/sys/arm/broadcom/bcm2835/bcm2835_bsc.c +++ head/sys/arm/broadcom/bcm2835/bcm2835_bsc.c @@ -347,7 +347,7 @@ } /* Probe and attach the iicbus when interrupts are available. */ - config_intrhook_oneshot((ich_func_t)bus_generic_attach, dev); + bus_delayed_attach_children(dev); return (0); } Index: head/sys/arm/freescale/imx/imx_i2c.c =================================================================== --- head/sys/arm/freescale/imx/imx_i2c.c +++ head/sys/arm/freescale/imx/imx_i2c.c @@ -449,8 +449,7 @@ /* We don't do a hardware reset here because iicbus_attach() does it. */ /* Probe and attach the iicbus when interrupts are available. */ - config_intrhook_oneshot((ich_func_t)bus_generic_attach, dev); - return (0); + return (bus_delayed_attach_children(dev)); } static int Index: head/sys/arm/freescale/imx/imx_spi.c =================================================================== --- head/sys/arm/freescale/imx/imx_spi.c +++ head/sys/arm/freescale/imx/imx_spi.c @@ -566,9 +566,7 @@ * their attach. We can't do IO until timers and interrupts are working. */ sc->spibus = device_add_child(dev, "spibus", -1); - config_intrhook_oneshot((ich_func_t)bus_generic_attach, dev); - - return (0); + return (bus_delayed_attach_children(dev)); } static int Index: head/sys/arm/mv/a37x0_spi.c =================================================================== --- head/sys/arm/mv/a37x0_spi.c +++ head/sys/arm/mv/a37x0_spi.c @@ -220,7 +220,7 @@ device_add_child(dev, "spibus", -1); /* Probe and attach the spibus when interrupts are available. */ - config_intrhook_oneshot((ich_func_t)bus_generic_attach, dev); + bus_delayed_attach_children(dev); return (0); } Index: head/sys/arm/mv/mv_spi.c =================================================================== --- head/sys/arm/mv/mv_spi.c +++ head/sys/arm/mv/mv_spi.c @@ -174,9 +174,7 @@ device_add_child(dev, "spibus", -1); /* Probe and attach the spibus when interrupts are available. */ - config_intrhook_oneshot((ich_func_t)bus_generic_attach, dev); - - return (0); + return (bus_delayed_attach_children(dev)); } static int Index: head/sys/arm/ti/ti_i2c.c =================================================================== --- head/sys/arm/ti/ti_i2c.c +++ head/sys/arm/ti/ti_i2c.c @@ -905,7 +905,7 @@ } /* Probe and attach the iicbus when interrupts are available. */ - config_intrhook_oneshot((ich_func_t)bus_generic_attach, dev); + err = bus_delayed_attach_children(dev); out: if (err) { Index: head/sys/dev/glxiic/glxiic.c =================================================================== --- head/sys/dev/glxiic/glxiic.c +++ head/sys/dev/glxiic/glxiic.c @@ -411,8 +411,7 @@ glxiic_smb_enable(sc, IIC_FASTEST, 0); /* Probe and attach the iicbus when interrupts are available. */ - config_intrhook_oneshot((ich_func_t)bus_generic_attach, dev); - error = 0; + error = bus_delayed_attach_children(dev); out: if (error != 0) { Index: head/sys/dev/ichsmb/ichsmb.c =================================================================== --- head/sys/dev/ichsmb/ichsmb.c +++ head/sys/dev/ichsmb/ichsmb.c @@ -131,11 +131,8 @@ goto fail; } - /* Probe and attach the smbus when interrupts are available */ - config_intrhook_oneshot((ich_func_t)bus_generic_attach, dev); - - return (0); - + /* Attach children when interrupts are available */ + return (bus_delayed_attach_children(dev)); fail: mtx_destroy(&sc->mutex); return (error); Index: head/sys/dev/ow/owc_gpiobus.c =================================================================== --- head/sys/dev/ow/owc_gpiobus.c +++ head/sys/dev/ow/owc_gpiobus.c @@ -131,7 +131,7 @@ free(kids, M_TEMP); if (nkid == 0) device_add_child(dev, "ow", -1); - config_intrhook_oneshot((ich_func_t)bus_generic_attach, dev); + bus_delayed_attach_children(dev); return (0); } Index: head/sys/kern/subr_bus.c =================================================================== --- head/sys/kern/subr_bus.c +++ head/sys/kern/subr_bus.c @@ -3753,6 +3753,22 @@ } /** + * @brief Helper function for delaying attaching children + * + * Many buses can't run transactions on the bus which children need to probe and + * attach until after interrupts and/or timers are running. This function + * delays their attach until interrupts and timers are enabled. + */ +int +bus_delayed_attach_children(device_t dev) +{ + /* Probe and attach the bus children when interrupts are available */ + config_intrhook_oneshot((ich_func_t)bus_generic_attach, dev); + + return (0); +} + +/** * @brief Helper function for implementing DEVICE_DETACH() * * This function can be used to help implement the DEVICE_DETACH() for Index: head/sys/sys/bus.h =================================================================== --- head/sys/sys/bus.h +++ head/sys/sys/bus.h @@ -567,6 +567,7 @@ int bus_child_pnpinfo_str(device_t child, char *buf, size_t buflen); int bus_child_location_str(device_t child, char *buf, size_t buflen); void bus_enumerate_hinted_children(device_t bus); +int bus_delayed_attach_children(device_t bus); static __inline struct resource * bus_alloc_resource_any(device_t dev, int type, int *rid, u_int flags)