Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 6 Dec 2019 22:32:06 +0000 (UTC)
From:      Ian Lepore <ian@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r355467 - head/sys/dev/gpio
Message-ID:  <201912062232.xB6MW6Y7052874@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: ian
Date: Fri Dec  6 22:32:06 2019
New Revision: 355467
URL: https://svnweb.freebsd.org/changeset/base/355467

Log:
  Implement bus_rescan for gpiobus(4).  This allows on-the-fly reconfiguration
  of gpio devices by using kenv to add hints for a new device and then do
  'devctl rescan gpiobus4' to make the new device(s) attach.
  
  It's not particularly easy to detect whether the 'at' hint has been deleted
  for a child device that's currently attached, so this doesn't handle that.
  But the user can use devctl commands to manually detach an existing device.

Modified:
  head/sys/dev/gpio/gpiobus.c

Modified: head/sys/dev/gpio/gpiobus.c
==============================================================================
--- head/sys/dev/gpio/gpiobus.c	Fri Dec  6 22:20:26 2019	(r355466)
+++ head/sys/dev/gpio/gpiobus.c	Fri Dec  6 22:32:06 2019	(r355467)
@@ -716,6 +716,21 @@ gpiobus_add_child(device_t dev, u_int order, const cha
 	return (child);
 }
 
+static int
+gpiobus_rescan(device_t dev)
+{
+
+	/*
+	 * Re-scan is supposed to remove and add children, but if someone has
+	 * deleted the hints for a child we attached earlier, we have no easy
+	 * way to handle that.  So this just attaches new children for whom new
+	 * hints or drivers have arrived since we last tried.
+	 */
+	bus_enumerate_hinted_children(dev);
+	bus_generic_attach(dev);
+	return (0);
+}
+
 static void
 gpiobus_hinted_child(device_t bus, const char *dname, int dunit)
 {
@@ -725,6 +740,10 @@ gpiobus_hinted_child(device_t bus, const char *dname, 
 	const char *pins;
 	int irq, pinmask;
 
+	if (device_find_child(bus, dname, dunit) != NULL) {
+		return;
+	}
+
 	child = BUS_ADD_CHILD(bus, 0, dname, dunit);
 	devi = GPIOBUS_IVAR(child);
 	if (resource_int_value(dname, dunit, "pins", &pinmask) == 0) {
@@ -1077,6 +1096,7 @@ static device_method_t gpiobus_methods[] = {
 	DEVMETHOD(bus_deactivate_resource,	bus_generic_deactivate_resource),
 	DEVMETHOD(bus_get_resource_list,	gpiobus_get_resource_list),
 	DEVMETHOD(bus_add_child,	gpiobus_add_child),
+	DEVMETHOD(bus_rescan,		gpiobus_rescan),
 	DEVMETHOD(bus_probe_nomatch,	gpiobus_probe_nomatch),
 	DEVMETHOD(bus_print_child,	gpiobus_print_child),
 	DEVMETHOD(bus_child_pnpinfo_str, gpiobus_child_pnpinfo_str),



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201912062232.xB6MW6Y7052874>