Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 8 Dec 2019 20:13:42 +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: r355531 - head/sys/dev/gpio
Message-ID:  <201912082013.xB8KDgYm007386@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: ian
Date: Sun Dec  8 20:13:42 2019
New Revision: 355531
URL: https://svnweb.freebsd.org/changeset/base/355531

Log:
  Several small fixes for the gpioths (temp/humidity sensor) driver.
  
  At the end of a read cycle, set the gpio pin to INPUT rather than OUTPUT.
  The state of the single-wire "bus" when idle should be high; setting the
  pin to input allows the external pullup to pull the line high.  Setting it
  to output (and leaving it driving low) was leading a good read cycle followed
  by one that would fail, and it just continued like that forever, effectively
  reading the sensor once every 10 seconds instead of 5.
  
  In the attach function, do an initial read from the device before registering
  the sysctls for accessing the last-read values, to prevent reading spurious
  values for the first 5 seconds after the driver attaches.
  
  Do a callout_drain() in the detach function to prevent crashes after
  unloading the module.

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

Modified: head/sys/dev/gpio/gpioths.c
==============================================================================
--- head/sys/dev/gpio/gpioths.c	Sun Dec  8 16:59:36 2019	(r355530)
+++ head/sys/dev/gpio/gpioths.c	Sun Dec  8 20:13:42 2019	(r355531)
@@ -198,9 +198,9 @@ gpioths_dht_readbytes(device_t bus, device_t dev)
 		}
 	}
 
-	err = GPIOBUS_PIN_SETFLAGS(bus, dev, 0, GPIO_PIN_OUTPUT);
+	err = GPIOBUS_PIN_SETFLAGS(bus, dev, 0, GPIO_PIN_INPUT);
 	if (err != 0) {
-		device_printf(dev, "err(FINAL_SETFLAGS, OUT) = %d\n", err);
+		device_printf(dev, "err(FINAL_SETFLAGS, IN) = %d\n", err);
 		goto error;
 	}
 	DELAY(1);
@@ -331,8 +331,11 @@ gpioths_attach(device_t dev)
 
 	sc->dev = dev;
 
-	callout_init(&sc->callout, 1);
-	callout_reset(&sc->callout, GPIOTHS_POLLTIME * hz, gpioths_poll, dev);
+	/* 
+	 * Do an initial read so we have correct values for reporting before
+	 * registering the sysctls that can access those values.
+	 */
+	gpioths_dht_readbytes(device_get_parent(dev), dev);
 
 	sc->temp_oid = SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
 	    "temperature", CTLTYPE_INT | CTLFLAG_RD, sc, 0,
@@ -346,12 +349,20 @@ gpioths_attach(device_t dev)
 	    "fails", CTLTYPE_INT | CTLFLAG_RD, sc, 0,
 	    gpioths_fails_sysctl, "I", "fails since last successful read");
 
+	callout_init(&sc->callout, 1);
+	callout_reset(&sc->callout, GPIOTHS_POLLTIME * hz, gpioths_poll, dev);
+
 	return (0);
 }
 
 static int
 gpioths_detach(device_t dev)
 {
+	struct gpioths_softc	*sc;
+
+	sc = device_get_softc(dev);
+
+	callout_drain(&sc->callout);
 
 	return (0);
 }



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