Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/i2c convert device polling from callout to kthread.
details: https://anonhg.NetBSD.org/src/rev/a88fb8eadfa4
branches: trunk
changeset: 346246:a88fb8eadfa4
user: kardel <kardel%NetBSD.org@localhost>
date: Sun Jul 03 12:26:55 2016 +0000
description:
convert device polling from callout to kthread.
Solves:
- hung initialization on A20 (bananapi)
- allows iic_exec() implementations to use condvars
diffstat:
sys/dev/i2c/hytp14.c | 96 ++++++++++++++++++++++++++++++++++++++++--------
sys/dev/i2c/hytp14var.h | 16 ++++++--
2 files changed, 91 insertions(+), 21 deletions(-)
diffs (208 lines):
diff -r ff4c2d1921b2 -r a88fb8eadfa4 sys/dev/i2c/hytp14.c
--- a/sys/dev/i2c/hytp14.c Sun Jul 03 11:55:27 2016 +0000
+++ b/sys/dev/i2c/hytp14.c Sun Jul 03 12:26:55 2016 +0000
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2014 The NetBSD Foundation, Inc.
+ * Copyright (c) 2014,2016 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
@@ -37,7 +37,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: hytp14.c,v 1.6 2015/09/18 17:21:43 phx Exp $");
+__KERNEL_RCSID(0, "$NetBSD: hytp14.c,v 1.7 2016/07/03 12:26:55 kardel Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -45,6 +45,9 @@
#include <sys/device.h>
#include <sys/module.h>
#include <sys/sysctl.h>
+#include <sys/mutex.h>
+#include <sys/condvar.h>
+#include <sys/kthread.h>
#include <dev/sysmon/sysmonvar.h>
#include <dev/i2c/i2cvar.h>
@@ -59,9 +62,11 @@
static void hytp14_refresh(struct sysmon_envsys *, envsys_data_t *);
static void hytp14_refresh_humidity(struct hytp14_sc *, envsys_data_t *);
static void hytp14_refresh_temp(struct hytp14_sc *, envsys_data_t *);
+static void hytp14_thread(void *);
static int sysctl_hytp14_interval(SYSCTLFN_ARGS);
-/*#define HYT_DEBUG 3*/
+/* #define HYT_DEBUG 3 */
+
#ifdef HYT_DEBUG
volatile int hythygtemp_debug = HYT_DEBUG;
@@ -115,7 +120,7 @@
const struct sysctlnode *rnode, *node;
struct hytp14_sc *sc;
struct i2c_attach_args *ia;
- int i;
+ int i, rv;
ia = aux;
sc = device_private(self);
@@ -123,6 +128,12 @@
sc->sc_dev = self;
sc->sc_tag = ia->ia_tag;
sc->sc_addr = ia->ia_addr;
+
+ mutex_init(&sc->sc_mutex, MUTEX_DEFAULT, IPL_NONE);
+ cv_init(&sc->sc_condvar, "hytcv");
+
+ sc->sc_state = HYTP14_THR_INIT;
+
sc->sc_valid = ENVSYS_SINVALID;
sc->sc_numsensors = __arraycount(hytp14_sensors);
@@ -180,15 +191,18 @@
sysctl_hytp14_interval, 0, (void *)sc, 0,
CTL_HW, rnode->sysctl_num, CTL_CREATE, CTL_EOL);
- aprint_normal(": HYT-221/271/939 humidity and temperature sensor\n");
- /* set up callout for the default measurement interval */
+ /* set up the default measurement interval for worker thread */
sc->sc_mrinterval = HYTP14_MR_INTERVAL;
- callout_init(&sc->sc_mrcallout, 0);
- callout_setfunc(&sc->sc_mrcallout, hytp14_measurement_request, sc);
- /* issue initial measurement request */
- hytp14_measurement_request(sc);
+ /* create worker kthread */
+ rv = kthread_create(PRI_NONE, KTHREAD_MUSTJOIN, NULL,
+ hytp14_thread, sc, &sc->sc_thread,
+ "%s", device_xname(sc->sc_dev));
+ if (rv)
+ aprint_error_dev(self, "unable to create intr thread\n");
+
+ aprint_normal(": HYT-221/271/939 humidity and temperature sensor\n");
}
static int
@@ -203,11 +217,62 @@
sc->sc_sme = NULL;
}
- /* stop our measurement requests */
- callout_stop(&sc->sc_mrcallout);
- callout_destroy(&sc->sc_mrcallout);
+ /* stop measurement thread */
+ mutex_enter(&sc->sc_mutex);
+ sc->sc_state = HYTP14_THR_STOP;
+ cv_signal(&sc->sc_condvar);
+ mutex_exit(&sc->sc_mutex);
+
+ /* await thread completion */
+ kthread_join(sc->sc_thread);
+
+ /* cleanup */
+ cv_destroy(&sc->sc_condvar);
+ mutex_destroy(&sc->sc_mutex);
+
+ return 0;
+}
+
+static void
+hytp14_thread(void *aux)
+{
+ struct hytp14_sc *sc = aux;
+ int rv;
+
+ mutex_enter(&sc->sc_mutex);
- return 0;
+ DPRINTF(2, ("%s(%s): thread start - state=%d\n",
+ __func__, device_xname(sc->sc_dev),
+ sc->sc_state));
+
+ while (sc->sc_state != HYTP14_THR_STOP) {
+ sc->sc_state = HYTP14_THR_RUN;
+
+ DPRINTF(2, ("%s(%s): waiting %d seconds\n",
+ __func__, device_xname(sc->sc_dev),
+ sc->sc_mrinterval));
+
+ rv = cv_timedwait(&sc->sc_condvar, &sc->sc_mutex, hz * sc->sc_mrinterval);
+
+ if (rv == EWOULDBLOCK) {
+ /* timeout - run measurement */
+ DPRINTF(2, ("%s(%s): timeout -> measurement\n",
+ __func__, device_xname(sc->sc_dev)));
+
+ hytp14_measurement_request(sc);
+ } else {
+ DPRINTF(2, ("%s(%s): condvar signalled - state=%d\n",
+ __func__, device_xname(sc->sc_dev),
+ sc->sc_state));
+ }
+ }
+
+ mutex_exit(&sc->sc_mutex);
+
+ DPRINTF(2, ("%s(%s): thread exit\n",
+ __func__, device_xname(sc->sc_dev)));
+
+ kthread_exit(0);
}
static void
@@ -267,9 +332,6 @@
DPRINTF(2, ("%s: %s: failed acquire i2c bus - error %d\n",
device_xname(sc->sc_dev), __func__, error));
}
-
- /* schedule next measurement interval */
- callout_schedule(&sc->sc_mrcallout, sc->sc_mrinterval * hz);
}
static int
diff -r ff4c2d1921b2 -r a88fb8eadfa4 sys/dev/i2c/hytp14var.h
--- a/sys/dev/i2c/hytp14var.h Sun Jul 03 11:55:27 2016 +0000
+++ b/sys/dev/i2c/hytp14var.h Sun Jul 03 12:26:55 2016 +0000
@@ -1,7 +1,7 @@
-/* $NetBSD: hytp14var.h,v 1.3 2015/09/09 17:16:20 phx Exp $ */
+/* $NetBSD: hytp14var.h,v 1.4 2016/07/03 12:26:55 kardel Exp $ */
/*-
- * Copyright (c) 2014 The NetBSD Foundation, Inc.
+ * Copyright (c) 2014,2016 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
@@ -47,18 +47,26 @@
/* the default measurement interval is 50 seconds */
#define HYTP14_MR_INTERVAL 50
+#define HYTP14_THR_INIT 0
+#define HYTP14_THR_RUN 1
+#define HYTP14_THR_STOP 2
+
struct hytp14_sc {
device_t sc_dev;
i2c_tag_t sc_tag;
i2c_addr_t sc_addr;
-
+
+ kmutex_t sc_mutex;
+ kcondvar_t sc_condvar;
+ struct lwp *sc_thread; /* measurement poll thread */
+ int sc_state; /* thread communication */
+
int sc_valid; /* ENVSYS validity state for this sensor */
uint8_t sc_data[4]; /* current sensor data */
uint8_t sc_last[4]; /* last sensor data, before MR */
int sc_numsensors;
- callout_t sc_mrcallout;
int32_t sc_mrinterval;
struct sysmon_envsys *sc_sme;
Home |
Main Index |
Thread Index |
Old Index