Create new wrapper function: bus_delayed_attach_children()

Delay the attachment of children, when requested, until after interrutps are
running. This is often needed to allow children to run transactions on i2c or
spi busses. It's a common enough idiom that it will be useful to have its own
wrapper.

Reviewed by: ian
Differential Revision: https://reviews.freebsd.org/D21465
This commit is contained in:
Warner Losh 2019-12-13 19:39:33 +00:00
parent 889ad0b890
commit b832a7e505
13 changed files with 83 additions and 19 deletions

View File

@ -34,6 +34,7 @@ MAN= accept_filter.9 \
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 \

View File

@ -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 .

View File

@ -347,7 +347,7 @@ bcm_bsc_attach(device_t dev)
}
/* 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);
}

View File

@ -449,8 +449,7 @@ no_recovery:
/* 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

View File

@ -566,9 +566,7 @@ spi_attach(device_t dev)
* 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

View File

@ -220,7 +220,7 @@ a37x0_spi_attach(device_t dev)
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);
}

View File

@ -174,9 +174,7 @@ mv_spi_attach(device_t dev)
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

View File

@ -905,7 +905,7 @@ ti_i2c_attach(device_t dev)
}
/* 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) {

View File

@ -411,8 +411,7 @@ glxiic_attach(device_t dev)
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) {

View File

@ -131,11 +131,8 @@ ichsmb_attach(device_t dev)
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);

View File

@ -131,7 +131,7 @@ owc_gpiobus_attach(device_t dev)
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);
}

View File

@ -3752,6 +3752,22 @@ bus_generic_attach(device_t dev)
return (0);
}
/**
* @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()
*

View File

@ -567,6 +567,7 @@ int bus_child_present(device_t child);
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)