Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/gpio Before trying to attach a child device driver, ...
details: https://anonhg.NetBSD.org/src/rev/1180cd623daa
branches: trunk
changeset: 746847:1180cd623daa
user: mbalmer <mbalmer%NetBSD.org@localhost>
date: Fri Aug 21 12:53:42 2009 +0000
description:
Before trying to attach a child device driver, make sure the GPIO pins can
be mapped. This prevents drivers from later failing in the attach routine.
Problem found by me, solution suggested by jmcneill.
diffstat:
sys/dev/gpio/gpio.c | 35 ++++++++++++++++++++++++++++++++---
sys/dev/gpio/gpiovar.h | 3 ++-
2 files changed, 34 insertions(+), 4 deletions(-)
diffs (81 lines):
diff -r 05a4bd9939fa -r 1180cd623daa sys/dev/gpio/gpio.c
--- a/sys/dev/gpio/gpio.c Fri Aug 21 10:01:25 2009 +0000
+++ b/sys/dev/gpio/gpio.c Fri Aug 21 12:53:42 2009 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: gpio.c,v 1.26 2009/08/17 12:44:44 mbalmer Exp $ */
+/* $NetBSD: gpio.c,v 1.27 2009/08/21 12:53:42 mbalmer Exp $ */
/* $OpenBSD: gpio.c,v 1.6 2006/01/14 12:33:49 grange Exp $ */
/*
@@ -19,7 +19,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: gpio.c,v 1.26 2009/08/17 12:44:44 mbalmer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: gpio.c,v 1.27 2009/08/21 12:53:42 mbalmer Exp $");
/*
* General Purpose Input/Output framework.
@@ -217,6 +217,30 @@
return UNCONF;
}
+/* return 1 if all pins can be mapped, 0 if not */
+
+int
+gpio_pin_can_map(void *gpio, int offset, u_int32_t mask)
+{
+ struct gpio_softc *sc = gpio;
+ int npins, pin, i;
+
+ npins = gpio_npins(mask);
+ if (npins > sc->sc_npins)
+ return 0;
+
+ for (npins = 0, i = 0; i < 32; i++)
+ if (mask & (1 << i)) {
+ pin = offset + i;
+ if (pin < 0 || pin >= sc->sc_npins)
+ return 0;
+ if (sc->sc_pins[pin].pin_mapped)
+ return 0;
+ }
+
+ return 1;
+}
+
int
gpio_pin_map(void *gpio, int offset, u_int32_t mask, struct gpio_pinmap *map)
{
@@ -483,8 +507,13 @@
if (kauth_authorize_device(cred, KAUTH_DEVICE_GPIO_PINSET,
NULL, NULL, NULL, NULL))
return EPERM;
-
+
attach = (struct gpio_attach *)data;
+
+ /* do not try to attach if the pins are already mapped */
+ if (!gpio_pin_can_map(sc, attach->ga_offset, attach->ga_mask))
+ return EBUSY;
+
ga.ga_gpio = sc;
ga.ga_dvname = attach->ga_dvname;
ga.ga_offset = attach->ga_offset;
diff -r 05a4bd9939fa -r 1180cd623daa sys/dev/gpio/gpiovar.h
--- a/sys/dev/gpio/gpiovar.h Fri Aug 21 10:01:25 2009 +0000
+++ b/sys/dev/gpio/gpiovar.h Fri Aug 21 12:53:42 2009 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: gpiovar.h,v 1.9 2009/07/25 16:30:44 mbalmer Exp $ */
+/* $NetBSD: gpiovar.h,v 1.10 2009/08/21 12:53:42 mbalmer Exp $ */
/* $OpenBSD: gpiovar.h,v 1.3 2006/01/14 12:33:49 grange Exp $ */
/*
@@ -88,6 +88,7 @@
LIST_ENTRY(gpio_name) gp_next;
};
+int gpio_pin_can_map(void *, int, u_int32_t);
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);
Home |
Main Index |
Thread Index |
Old Index