diff options
author | Marc Balmer <mbalmer@cvs.openbsd.org> | 2008-11-24 12:12:13 +0000 |
---|---|---|
committer | Marc Balmer <mbalmer@cvs.openbsd.org> | 2008-11-24 12:12:13 +0000 |
commit | b4ed2f28ea065bc5bcbe1d53040fb5279aeb61c8 (patch) | |
tree | c4160f4c716b126e6f70a6d856147c5952f04367 /sys/dev/gpio | |
parent | 4b1d709239a91447e0420f89c7a1bd2ba3916ded (diff) |
- Add two new ioctls to gpio(4), GPIOATTACH and GPIODETACH, to allow to attach
and detach devices on a gpiobus at runtime. The offset and mask locators
in kernel config files can still be used for static configuration, so this
does not break existing custome kernel configs.
- Have gpioow(4) unmap the pins it used from the gpiobus during detach
Changes to gpioctl(8) will be a separate committ.
ok uwe
Diffstat (limited to 'sys/dev/gpio')
-rw-r--r-- | sys/dev/gpio/files.gpio | 9 | ||||
-rw-r--r-- | sys/dev/gpio/gpio.c | 51 | ||||
-rw-r--r-- | sys/dev/gpio/gpioiic.c | 6 | ||||
-rw-r--r-- | sys/dev/gpio/gpioow.c | 8 | ||||
-rw-r--r-- | sys/dev/gpio/gpiovar.h | 8 |
5 files changed, 73 insertions, 9 deletions
diff --git a/sys/dev/gpio/files.gpio b/sys/dev/gpio/files.gpio index 79fd80d3a03..796dbc02e43 100644 --- a/sys/dev/gpio/files.gpio +++ b/sys/dev/gpio/files.gpio @@ -1,11 +1,16 @@ -# $OpenBSD: files.gpio,v 1.6 2006/03/04 16:27:03 grange Exp $ +# $OpenBSD: files.gpio,v 1.7 2008/11/24 12:12:12 mbalmer Exp $ -define gpio {offset, mask} +define gpio {[offset = -1], [mask = 0]} device gpio: gpio attach gpio at gpiobus file dev/gpio/gpio.c gpio needs-flag +# GPIO simulator +device gpiosim: gpiobus +attach gpiosim at root +file dev/gpio/gpiosim.c gpiosim needs-flag + # I2C bus bit-banging device gpioiic: i2cbus, i2c_bitbang attach gpioiic at gpio diff --git a/sys/dev/gpio/gpio.c b/sys/dev/gpio/gpio.c index 88326b0a313..9a910140ba6 100644 --- a/sys/dev/gpio/gpio.c +++ b/sys/dev/gpio/gpio.c @@ -1,4 +1,4 @@ -/* $OpenBSD: gpio.c,v 1.7 2006/03/26 18:48:17 grange Exp $ */ +/* $OpenBSD: gpio.c,v 1.8 2008/11/24 12:12:12 mbalmer Exp $ */ /* * Copyright (c) 2004, 2006 Alexander Yurchenko <grange@openbsd.org> @@ -28,6 +28,8 @@ #include <sys/ioctl.h> #include <sys/gpio.h> #include <sys/vnode.h> +#include <sys/malloc.h> +#include <sys/queue.h> #include <dev/gpio/gpiovar.h> @@ -39,9 +41,11 @@ struct gpio_softc { int sc_npins; /* total number of pins */ int sc_opened; + LIST_HEAD(, gpio_dev) sc_list; }; int gpio_match(struct device *, void *, void *); +int gpio_submatch(struct device *, void *, void *); void gpio_attach(struct device *, struct device *, void *); int gpio_detach(struct device *, int); int gpio_search(struct device *, void *, void *); @@ -64,10 +68,16 @@ gpio_match(struct device *parent, void *match, void *aux) struct cfdata *cf = match; struct gpiobus_attach_args *gba = aux; - if (strcmp(gba->gba_name, cf->cf_driver->cd_name) != 0) - return (0); + return (strcmp(gba->gba_name, cf->cf_driver->cd_name) == 0); +} + +int +gpio_submatch(struct device *parent, void *match, void *aux) +{ + struct cfdata *cf = match; + struct gpio_attach_args *ga = aux; - return (1); + return (strcmp(ga->ga_dvname, cf->cf_driver->cd_name) == 0); } void @@ -263,6 +273,10 @@ gpioioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) struct gpio_info *info; struct gpio_pin_op *op; struct gpio_pin_ctl *ctl; + struct gpio_attach *attach; + struct gpio_attach_args ga; + struct gpio_dev *gdev; + struct device *dv; int pin, value, flags; sc = (struct gpio_softc *)device_lookup(&gpio_cd, minor(dev)); @@ -352,6 +366,35 @@ gpioioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) sc->sc_pins[pin].pin_flags = flags; } break; + case GPIOATTACH: + attach = (struct gpio_attach *)data; + bzero(&ga, sizeof(ga)); + ga.ga_gpio = sc; + ga.ga_dvname = attach->ga_dvname; + ga.ga_offset = attach->ga_offset; + ga.ga_mask = attach->ga_mask; + dv = config_found_sm((struct device *)sc, &ga, gpiobus_print, + gpio_submatch); + if (dv != NULL) { + gdev = malloc(sizeof(struct gpio_dev), M_DEVBUF, + M_WAITOK); + gdev->sc_dev = dv; + LIST_INSERT_HEAD(&sc->sc_list, gdev, sc_next); + } + break; + case GPIODETACH: + attach = (struct gpio_attach *)data; + LIST_FOREACH(gdev, &sc->sc_list, sc_next) { + if (strcmp(gdev->sc_dev->dv_xname, attach->ga_dvname) + == 0) { + if (config_detach(gdev->sc_dev, 0) == 0) { + LIST_REMOVE(gdev, sc_next); + free(gdev, M_DEVBUF); + } + break; + } + } + break; default: return (ENOTTY); } diff --git a/sys/dev/gpio/gpioiic.c b/sys/dev/gpio/gpioiic.c index 559717f8f7c..ea86c322b7d 100644 --- a/sys/dev/gpio/gpioiic.c +++ b/sys/dev/gpio/gpioiic.c @@ -1,4 +1,4 @@ -/* $OpenBSD: gpioiic.c,v 1.7 2007/06/05 08:37:20 jsg Exp $ */ +/* $OpenBSD: gpioiic.c,v 1.8 2008/11/24 12:12:12 mbalmer Exp $ */ /* * Copyright (c) 2006 Alexander Yurchenko <grange@openbsd.org> @@ -90,6 +90,10 @@ int gpioiic_match(struct device *parent, void *match, void *aux) { struct cfdata *cf = match; + struct gpio_attach_args *ga = aux; + + if (ga->ga_offset == -1) + return 0; return (strcmp(cf->cf_driver->cd_name, "gpioiic") == 0); } diff --git a/sys/dev/gpio/gpioow.c b/sys/dev/gpio/gpioow.c index 23adb2fc6f8..51536de91c5 100644 --- a/sys/dev/gpio/gpioow.c +++ b/sys/dev/gpio/gpioow.c @@ -1,4 +1,4 @@ -/* $OpenBSD: gpioow.c,v 1.2 2006/06/23 06:27:11 miod Exp $ */ +/* $OpenBSD: gpioow.c,v 1.3 2008/11/24 12:12:12 mbalmer Exp $ */ /* * Copyright (c) 2006 Alexander Yurchenko <grange@openbsd.org> @@ -82,6 +82,10 @@ int gpioow_match(struct device *parent, void *match, void *aux) { struct cfdata *cf = match; + struct gpio_attach_args *ga = aux; + + if (ga->ga_offset == -1) + return 0; return (strcmp(cf->cf_driver->cd_name, "gpioow") == 0); } @@ -157,6 +161,8 @@ gpioow_detach(struct device *self, int flags) struct gpioow_softc *sc = (struct gpioow_softc *)self; int rv = 0; + gpio_pin_unmap(sc->sc_gpio, &sc->sc_map); + if (sc->sc_ow_dev != NULL) rv = config_detach(sc->sc_ow_dev, flags); diff --git a/sys/dev/gpio/gpiovar.h b/sys/dev/gpio/gpiovar.h index e8568fe4464..b507370ebe2 100644 --- a/sys/dev/gpio/gpiovar.h +++ b/sys/dev/gpio/gpiovar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: gpiovar.h,v 1.3 2006/01/14 12:33:49 grange Exp $ */ +/* $OpenBSD: gpiovar.h,v 1.4 2008/11/24 12:12:12 mbalmer Exp $ */ /* * Copyright (c) 2004, 2006 Alexander Yurchenko <grange@openbsd.org> @@ -60,6 +60,7 @@ struct gpio_attach_args { void * ga_gpio; int ga_offset; u_int32_t ga_mask; + char *ga_dvname; }; /* GPIO pin map */ @@ -68,6 +69,11 @@ struct gpio_pinmap { int pm_size; /* map size */ }; +struct gpio_dev { + struct device *sc_dev; /* the gpio device */ + LIST_ENTRY(gpio_dev) sc_next; +}; + int gpio_pin_map(void *, int, u_int32_t, struct gpio_pinmap *); void gpio_pin_unmap(void *, struct gpio_pinmap *); int gpio_pin_read(void *, struct gpio_pinmap *, int); |