xref: /netbsd-src/sys/dev/gpio/gpio.c (revision 19ef5b5b0bcb90f63509df6e78769de1b57c2758)
1 /* $NetBSD: gpio.c,v 1.54 2014/04/04 14:47:26 christos Exp $ */
2 /*	$OpenBSD: gpio.c,v 1.6 2006/01/14 12:33:49 grange Exp $	*/
3 
4 /*
5  * Copyright (c) 2008, 2009, 2010, 2011 Marc Balmer <marc@msys.ch>
6  * Copyright (c) 2004, 2006 Alexander Yurchenko <grange@openbsd.org>
7  *
8  * Permission to use, copy, modify, and distribute this software for any
9  * purpose with or without fee is hereby granted, provided that the above
10  * copyright notice and this permission notice appear in all copies.
11  *
12  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19  */
20 
21 #include <sys/cdefs.h>
22 __KERNEL_RCSID(0, "$NetBSD: gpio.c,v 1.54 2014/04/04 14:47:26 christos Exp $");
23 
24 /*
25  * General Purpose Input/Output framework.
26  */
27 
28 #include <sys/param.h>
29 #include <sys/callout.h>
30 #include <sys/systm.h>
31 #include <sys/conf.h>
32 #include <sys/device.h>
33 #include <sys/fcntl.h>
34 #include <sys/ioctl.h>
35 #include <sys/gpio.h>
36 #include <sys/kernel.h>
37 #include <sys/vnode.h>
38 #include <sys/kmem.h>
39 #include <sys/mutex.h>
40 #include <sys/condvar.h>
41 #include <sys/queue.h>
42 #include <sys/kauth.h>
43 #include <sys/module.h>
44 #include <dev/gpio/gpiovar.h>
45 
46 #include "locators.h"
47 
48 #ifdef GPIO_DEBUG
49 #define DPRINTFN(n, x)	do { if (gpiodebug > (n)) printf x; } while (0)
50 int gpiodebug = 0;
51 #else
52 #define DPRINTFN(n, x)
53 #endif
54 #define DPRINTF(x)	DPRINTFN(0, x)
55 
56 struct gpio_softc {
57 	device_t		 sc_dev;
58 
59 	gpio_chipset_tag_t	 sc_gc;		/* GPIO controller */
60 	gpio_pin_t		*sc_pins;	/* pins array */
61 	int			 sc_npins;	/* number of pins */
62 
63 	kmutex_t		 sc_mtx;
64 	kcondvar_t		 sc_ioctl;	/* ioctl in progress */
65 	int			 sc_ioctl_busy;	/* ioctl is busy */
66 	kcondvar_t		 sc_attach;	/* attach/detach in progress */
67 	int			 sc_attach_busy;/* busy in attach/detach */
68 #ifdef COMPAT_50
69 	LIST_HEAD(, gpio_dev)	 sc_devs;	/* devices */
70 #endif
71 	LIST_HEAD(, gpio_name)	 sc_names;	/* named pins */
72 };
73 
74 static int	gpio_match(device_t, cfdata_t, void *);
75 int		gpio_submatch(device_t, cfdata_t, const int *, void *);
76 static void	gpio_attach(device_t, device_t, void *);
77 static int	gpio_rescan(device_t, const char *, const int *);
78 static void	gpio_childdetached(device_t, device_t);
79 static bool	gpio_resume(device_t, const pmf_qual_t *);
80 static int	gpio_detach(device_t, int);
81 static int	gpio_search(device_t, cfdata_t, const int *, void *);
82 static int	gpio_print(void *, const char *);
83 static int	gpio_pinbyname(struct gpio_softc *, char *);
84 static int	gpio_ioctl(struct gpio_softc *, u_long, void *, int,
85     struct lwp *);
86 
87 #ifdef COMPAT_50
88 /* Old API */
89 static int	gpio_ioctl_oapi(struct gpio_softc *, u_long, void *, int,
90     kauth_cred_t);
91 #endif
92 
93 CFATTACH_DECL3_NEW(gpio, sizeof(struct gpio_softc),
94     gpio_match, gpio_attach, gpio_detach, NULL, gpio_rescan,
95     gpio_childdetached, DVF_DETACH_SHUTDOWN);
96 
97 dev_type_open(gpioopen);
98 dev_type_close(gpioclose);
99 dev_type_ioctl(gpioioctl);
100 dev_type_ioctl(gpioioctl_locked);
101 
102 const struct cdevsw gpio_cdevsw = {
103 	.d_open = gpioopen,
104 	.d_close = gpioclose,
105 	.d_read = noread,
106 	.d_write = nowrite,
107 	.d_ioctl = gpioioctl,
108 	.d_stop = nostop,
109 	.d_tty = notty,
110 	.d_poll = nopoll,
111 	.d_mmap = nommap,
112 	.d_kqfilter = nokqfilter,
113 	.d_flag = D_OTHER | D_MPSAFE
114 };
115 
116 extern struct cfdriver gpio_cd;
117 
118 static int
119 gpio_match(device_t parent, cfdata_t cf, void *aux)
120 {
121 	return 1;
122 }
123 
124 int
125 gpio_submatch(device_t parent, cfdata_t cf, const int *ip, void *aux)
126 {
127 	struct gpio_attach_args *ga = aux;
128 
129 	if (ga->ga_offset == -1)
130 		return 0;
131 
132 	return strcmp(ga->ga_dvname, cf->cf_name) == 0;
133 }
134 
135 static bool
136 gpio_resume(device_t self, const pmf_qual_t *qual)
137 {
138 	struct gpio_softc *sc = device_private(self);
139 	int pin;
140 
141 	for (pin = 0; pin < sc->sc_npins; pin++) {
142 		gpiobus_pin_ctl(sc->sc_gc, pin, sc->sc_pins[pin].pin_flags);
143 		gpiobus_pin_write(sc->sc_gc, pin, sc->sc_pins[pin].pin_state);
144 	}
145 	return true;
146 }
147 
148 static void
149 gpio_childdetached(device_t self, device_t child)
150 {
151 #ifdef COMPAT_50
152 	struct gpio_dev *gdev;
153 	struct gpio_softc *sc;
154 	int error;
155 
156 	/*
157 	 * gpio_childetached is serialized because it can be entered in
158 	 * different ways concurrently, e.g. via the GPIODETACH ioctl and
159 	 * drvctl(8) or modunload(8).
160 	 */
161 	sc = device_private(self);
162 	error = 0;
163 	mutex_enter(&sc->sc_mtx);
164 	while (sc->sc_attach_busy) {
165 		error = cv_wait_sig(&sc->sc_attach, &sc->sc_mtx);
166 		if (error)
167 			break;
168 	}
169 	if (!error)
170 		sc->sc_attach_busy = 1;
171 	mutex_exit(&sc->sc_mtx);
172 	if (error)
173 		return;
174 
175 	LIST_FOREACH(gdev, &sc->sc_devs, sc_next)
176 		if (gdev->sc_dev == child) {
177 			LIST_REMOVE(gdev, sc_next);
178 			kmem_free(gdev, sizeof(struct gpio_dev));
179 			break;
180 		}
181 
182 	mutex_enter(&sc->sc_mtx);
183 	sc->sc_attach_busy = 0;
184 	cv_signal(&sc->sc_attach);
185 	mutex_exit(&sc->sc_mtx);
186 #endif
187 }
188 
189 static int
190 gpio_rescan(device_t self, const char *ifattr, const int *locators)
191 {
192 	struct gpio_softc *sc = device_private(self);
193 
194 	config_search_loc(gpio_search, self, ifattr, locators, sc);
195 
196 	return 0;
197 }
198 
199 static void
200 gpio_attach(device_t parent, device_t self, void *aux)
201 {
202 	struct gpio_softc *sc = device_private(self);
203 	struct gpiobus_attach_args *gba = aux;
204 
205 	sc->sc_dev = self;
206 	sc->sc_gc = gba->gba_gc;
207 	sc->sc_pins = gba->gba_pins;
208 	sc->sc_npins = gba->gba_npins;
209 
210 	aprint_normal(": %d pins\n", sc->sc_npins);
211 
212 	if (!pmf_device_register(self, NULL, gpio_resume))
213 		aprint_error_dev(self, "couldn't establish power handler\n");
214 	mutex_init(&sc->sc_mtx, MUTEX_DEFAULT, IPL_VM);
215 	cv_init(&sc->sc_ioctl, "gpioctl");
216 	cv_init(&sc->sc_attach, "gpioatch");
217 	/*
218 	 * Attach all devices that can be connected to the GPIO pins
219 	 * described in the kernel configuration file.
220 	 */
221 	gpio_rescan(self, "gpio", NULL);
222 }
223 
224 static int
225 gpio_detach(device_t self, int flags)
226 {
227 	struct gpio_softc *sc;
228 	int rc;
229 
230 	sc = device_private(self);
231 
232 	if ((rc = config_detach_children(self, flags)) != 0)
233 		return rc;
234 	mutex_destroy(&sc->sc_mtx);
235 	cv_destroy(&sc->sc_ioctl);
236 #if 0
237 	int maj, mn;
238 
239 	/* Locate the major number */
240 	for (maj = 0; maj < nchrdev; maj++)
241 		if (cdevsw[maj].d_open == gpioopen)
242 			break;
243 
244 	/* Nuke the vnodes for any open instances (calls close) */
245 	mn = device_unit(self);
246 	vdevgone(maj, mn, mn, VCHR);
247 #endif
248 	return 0;
249 }
250 
251 static int
252 gpio_search(device_t parent, cfdata_t cf, const int *ldesc, void *aux)
253 {
254 	struct gpio_attach_args ga;
255 	size_t namlen;
256 
257 	ga.ga_gpio = aux;
258 	ga.ga_offset = cf->cf_loc[GPIOCF_OFFSET];
259 	ga.ga_mask = cf->cf_loc[GPIOCF_MASK];
260 	ga.ga_flags = cf->cf_loc[GPIOCF_FLAG];
261 	namlen = strlen(cf->cf_name) + 1;
262 	ga.ga_dvname = kmem_alloc(namlen, KM_NOSLEEP);
263 	if (ga.ga_dvname == NULL)
264 		return 0;
265 	strcpy(ga.ga_dvname, cf->cf_name);
266 
267 	if (config_match(parent, cf, &ga) > 0)
268 		config_attach(parent, cf, &ga, gpio_print);
269 	kmem_free(ga.ga_dvname, namlen);
270 	return 0;
271 }
272 
273 int
274 gpio_print(void *aux, const char *pnp)
275 {
276 	struct gpio_attach_args *ga = aux;
277 	int i;
278 
279 	aprint_normal(" pins");
280 	for (i = 0; i < 32; i++)
281 		if (ga->ga_mask & (1 << i))
282 			aprint_normal(" %d", ga->ga_offset + i);
283 
284 	return UNCONF;
285 }
286 
287 int
288 gpiobus_print(void *aux, const char *pnp)
289 {
290 #if 0
291 	struct gpiobus_attach_args *gba = aux;
292 #endif
293 	if (pnp != NULL)
294 		aprint_normal("gpiobus at %s", pnp);
295 
296 	return UNCONF;
297 }
298 
299 /* return 1 if all pins can be mapped, 0 if not */
300 int
301 gpio_pin_can_map(void *gpio, int offset, uint32_t mask)
302 {
303 	struct gpio_softc *sc = gpio;
304 	int npins, pin, i;
305 
306 	npins = gpio_npins(mask);
307 	if (npins > sc->sc_npins)
308 		return 0;
309 
310 	for (npins = 0, i = 0; i < 32; i++)
311 		if (mask & (1 << i)) {
312 			pin = offset + i;
313 			if (pin < 0 || pin >= sc->sc_npins)
314 				return 0;
315 			if (sc->sc_pins[pin].pin_mapped)
316 				return 0;
317 		}
318 
319 	return 1;
320 }
321 
322 int
323 gpio_pin_map(void *gpio, int offset, uint32_t mask, struct gpio_pinmap *map)
324 {
325 	struct gpio_softc *sc = gpio;
326 	int npins, pin, i;
327 
328 	npins = gpio_npins(mask);
329 	if (npins > sc->sc_npins)
330 		return 1;
331 
332 	for (npins = 0, i = 0; i < 32; i++)
333 		if (mask & (1 << i)) {
334 			pin = offset + i;
335 			if (pin < 0 || pin >= sc->sc_npins)
336 				return 1;
337 			if (sc->sc_pins[pin].pin_mapped)
338 				return 1;
339 			sc->sc_pins[pin].pin_mapped = 1;
340 			map->pm_map[npins++] = pin;
341 		}
342 	map->pm_size = npins;
343 
344 	return 0;
345 }
346 
347 void
348 gpio_pin_unmap(void *gpio, struct gpio_pinmap *map)
349 {
350 	struct gpio_softc *sc = gpio;
351 	int pin, i;
352 
353 	for (i = 0; i < map->pm_size; i++) {
354 		pin = map->pm_map[i];
355 		sc->sc_pins[pin].pin_mapped = 0;
356 	}
357 }
358 
359 int
360 gpio_pin_read(void *gpio, struct gpio_pinmap *map, int pin)
361 {
362 	struct gpio_softc *sc = gpio;
363 
364 	return gpiobus_pin_read(sc->sc_gc, map->pm_map[pin]);
365 }
366 
367 void
368 gpio_pin_write(void *gpio, struct gpio_pinmap *map, int pin, int value)
369 {
370 	struct gpio_softc *sc = gpio;
371 
372 	gpiobus_pin_write(sc->sc_gc, map->pm_map[pin], value);
373 	sc->sc_pins[map->pm_map[pin]].pin_state = value;
374 }
375 
376 void
377 gpio_pin_ctl(void *gpio, struct gpio_pinmap *map, int pin, int flags)
378 {
379 	struct gpio_softc *sc = gpio;
380 
381 	return gpiobus_pin_ctl(sc->sc_gc, map->pm_map[pin], flags);
382 }
383 
384 int
385 gpio_pin_caps(void *gpio, struct gpio_pinmap *map, int pin)
386 {
387 	struct gpio_softc *sc = gpio;
388 
389 	return sc->sc_pins[map->pm_map[pin]].pin_caps;
390 }
391 
392 int
393 gpio_npins(uint32_t mask)
394 {
395 	int npins, i;
396 
397 	for (npins = 0, i = 0; i < 32; i++)
398 		if (mask & (1 << i))
399 			npins++;
400 
401 	return npins;
402 }
403 
404 int
405 gpio_lock(void *data)
406 {
407 	struct gpio_softc *sc;
408 	int error;
409 
410 	error = 0;
411 	sc = data;
412 	mutex_enter(&sc->sc_mtx);
413 	while (sc->sc_ioctl_busy) {
414 		error = cv_wait_sig(&sc->sc_ioctl, &sc->sc_mtx);
415 		if (error)
416 			break;
417 	}
418 	if (!error)
419 		sc->sc_ioctl_busy = 1;
420 	mutex_exit(&sc->sc_mtx);
421 	return error;
422 }
423 
424 void
425 gpio_unlock(void *data)
426 {
427 	struct gpio_softc *sc;
428 
429 	sc = data;
430 	mutex_enter(&sc->sc_mtx);
431 	sc->sc_ioctl_busy = 0;
432 	cv_signal(&sc->sc_ioctl);
433 	mutex_exit(&sc->sc_mtx);
434 }
435 
436 int
437 gpioopen(dev_t dev, int flag, int mode, struct lwp *l)
438 {
439 	struct gpio_softc *sc;
440 
441 	sc = device_lookup_private(&gpio_cd, minor(dev));
442 	if (sc == NULL)
443 		return ENXIO;
444 
445 	return gpiobus_open(sc->sc_gc, sc->sc_dev);
446 }
447 
448 int
449 gpioclose(dev_t dev, int flag, int mode, struct lwp *l)
450 {
451 	struct gpio_softc *sc;
452 
453 	sc = device_lookup_private(&gpio_cd, minor(dev));
454 	return gpiobus_close(sc->sc_gc, sc->sc_dev);
455 }
456 
457 static int
458 gpio_pinbyname(struct gpio_softc *sc, char *gp_name)
459 {
460         struct gpio_name *nm;
461 
462         LIST_FOREACH(nm, &sc->sc_names, gp_next)
463                 if (!strcmp(nm->gp_name, gp_name))
464                         return nm->gp_pin;
465         return -1;
466 }
467 
468 int
469 gpioioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l)
470 {
471 	int error;
472 	struct gpio_softc *sc;
473 
474 	sc = device_lookup_private(&gpio_cd, minor(dev));
475 
476 	error = gpio_lock(sc);
477 	if (error)
478 		return error;
479 
480 	error = gpio_ioctl(sc, cmd, data, flag, l);
481 	gpio_unlock(sc);
482 	return error;
483 }
484 
485 static int
486 gpio_ioctl(struct gpio_softc *sc, u_long cmd, void *data, int flag,
487     struct lwp *l)
488 {
489 	gpio_chipset_tag_t gc;
490 	struct gpio_info *info;
491 	struct gpio_attach *attach;
492 	struct gpio_attach_args ga;
493 	struct gpio_req *req;
494 	struct gpio_name *nm;
495 	struct gpio_set *set;
496 #ifdef COMPAT_50
497 	struct gpio_dev *gdev;
498 #endif
499 	device_t dv;
500 	cfdata_t cf;
501 	kauth_cred_t cred;
502 	int locs[GPIOCF_NLOCS];
503 	int error, pin, value, flags, npins;
504 
505 	gc = sc->sc_gc;
506 	ga.ga_flags = 0;
507 
508 	if (cmd != GPIOINFO && !device_is_active(sc->sc_dev)) {
509 		DPRINTF(("%s: device is not active\n",
510 		    device_xname(sc->sc_dev)));
511 		return EBUSY;
512 	}
513 
514 	cred = kauth_cred_get();
515 
516 	switch (cmd) {
517 	case GPIOINFO:
518 		info = data;
519 		if (!kauth_authorize_device(cred, KAUTH_DEVICE_GPIO_PINSET,
520 		    NULL, NULL, NULL, NULL))
521 			info->gpio_npins = sc->sc_npins;
522 		else {
523 			for (pin = npins = 0; pin < sc->sc_npins; pin++)
524 				if (sc->sc_pins[pin].pin_flags & GPIO_PIN_SET)
525 					++npins;
526 			info->gpio_npins = npins;
527 		}
528 		break;
529 	case GPIOREAD:
530 		req = data;
531 
532 		if (req->gp_name[0] != '\0')
533 			pin = gpio_pinbyname(sc, req->gp_name);
534 		else
535 			pin = req->gp_pin;
536 
537 		if (pin < 0 || pin >= sc->sc_npins)
538 			return EINVAL;
539 
540 		if (!(sc->sc_pins[pin].pin_flags & GPIO_PIN_SET) &&
541 		    kauth_authorize_device(cred, KAUTH_DEVICE_GPIO_PINSET,
542 		    NULL, NULL, NULL, NULL))
543 			return EPERM;
544 
545 		/* return read value */
546 		req->gp_value = gpiobus_pin_read(gc, pin);
547 		break;
548 	case GPIOWRITE:
549 		if ((flag & FWRITE) == 0)
550 			return EBADF;
551 
552 		req = data;
553 
554 		if (req->gp_name[0] != '\0')
555 			pin = gpio_pinbyname(sc, req->gp_name);
556 		else
557 			pin = req->gp_pin;
558 
559 		if (pin < 0 || pin >= sc->sc_npins)
560 			return EINVAL;
561 
562 		if (sc->sc_pins[pin].pin_mapped)
563 			return EBUSY;
564 
565 		if (!(sc->sc_pins[pin].pin_flags & GPIO_PIN_SET) &&
566 		    kauth_authorize_device(cred, KAUTH_DEVICE_GPIO_PINSET,
567 		    NULL, NULL, NULL, NULL))
568 			return EPERM;
569 
570 		value = req->gp_value;
571 		if (value != GPIO_PIN_LOW && value != GPIO_PIN_HIGH)
572 			return EINVAL;
573 
574 		/* return old value */
575 		req->gp_value = gpiobus_pin_read(gc, pin);
576 		gpiobus_pin_write(gc, pin, value);
577 		/* update current value */
578 		sc->sc_pins[pin].pin_state = value;
579 		break;
580 	case GPIOTOGGLE:
581 		if ((flag & FWRITE) == 0)
582 			return EBADF;
583 
584 		req = data;
585 
586 		if (req->gp_name[0] != '\0')
587 			pin = gpio_pinbyname(sc, req->gp_name);
588 		else
589 			pin = req->gp_pin;
590 
591 		if (pin < 0 || pin >= sc->sc_npins)
592 			return EINVAL;
593 
594 		if (sc->sc_pins[pin].pin_mapped)
595 			return EBUSY;
596 
597 		if (!(sc->sc_pins[pin].pin_flags & GPIO_PIN_SET) &&
598 		    kauth_authorize_device(cred, KAUTH_DEVICE_GPIO_PINSET,
599 		    NULL, NULL, NULL, NULL))
600 			return EPERM;
601 
602 		value = (sc->sc_pins[pin].pin_state == GPIO_PIN_LOW ?
603 		    GPIO_PIN_HIGH : GPIO_PIN_LOW);
604 		gpiobus_pin_write(gc, pin, value);
605 		/* return old value */
606 		req->gp_value = sc->sc_pins[pin].pin_state;
607 		/* update current value */
608 		sc->sc_pins[pin].pin_state = value;
609 		break;
610 	case GPIOATTACH:
611 		attach = data;
612 		ga.ga_flags = attach->ga_flags;
613 #ifdef COMPAT_50
614 		/* FALLTHROUGH */
615 	case GPIOATTACH50:
616 		/*
617 		 * The double assignment to 'attach' in case of GPIOATTACH
618 		 * and COMPAT_50 is on purpose. It ensures backward
619 		 * compatability in case we are called through the old
620 		 * GPIOATTACH50 ioctl(2), which had not the ga_flags field
621 		 * in struct gpio_attach.
622 		 */
623 		attach = data;
624 #endif
625 		if (kauth_authorize_device(cred, KAUTH_DEVICE_GPIO_PINSET,
626 		    NULL, NULL, NULL, NULL))
627 			return EPERM;
628 
629 		/* do not try to attach if the pins are already mapped */
630 		if (!gpio_pin_can_map(sc, attach->ga_offset, attach->ga_mask))
631 			return EBUSY;
632 
633 		error = 0;
634 		mutex_enter(&sc->sc_mtx);
635 		while (sc->sc_attach_busy) {
636 			error = cv_wait_sig(&sc->sc_attach, &sc->sc_mtx);
637 			if (error)
638 				break;
639 		}
640 		if (!error)
641 			sc->sc_attach_busy = 1;
642 		mutex_exit(&sc->sc_mtx);
643 		if (error)
644 			return EBUSY;
645 
646 		ga.ga_gpio = sc;
647 		/* Don't access attach->ga_flags here. */
648 		ga.ga_dvname = attach->ga_dvname;
649 		ga.ga_offset = attach->ga_offset;
650 		ga.ga_mask = attach->ga_mask;
651 		DPRINTF(("%s: attach %s with offset %d, mask "
652 		    "0x%02x, and flags 0x%02x\n", device_xname(sc->sc_dev),
653 		    ga.ga_dvname, ga.ga_offset, ga.ga_mask, ga.ga_flags));
654 
655 		locs[GPIOCF_OFFSET] = ga.ga_offset;
656 		locs[GPIOCF_MASK] = ga.ga_mask;
657 		locs[GPIOCF_FLAG] = ga.ga_flags;
658 
659 		cf = config_search_loc(NULL, sc->sc_dev, "gpio", locs, &ga);
660 		if (cf != NULL) {
661 			dv = config_attach_loc(sc->sc_dev, cf, locs, &ga,
662 			    gpiobus_print);
663 #ifdef COMPAT_50
664 			if (dv != NULL) {
665 				gdev = kmem_alloc(sizeof(struct gpio_dev),
666 				    KM_SLEEP);
667 				gdev->sc_dev = dv;
668 				LIST_INSERT_HEAD(&sc->sc_devs, gdev, sc_next);
669 			} else
670 				error = EINVAL;
671 #else
672 			if (dv == NULL)
673 				error = EINVAL;
674 #endif
675 		} else
676 			error = EINVAL;
677 		mutex_enter(&sc->sc_mtx);
678 		sc->sc_attach_busy = 0;
679 		cv_signal(&sc->sc_attach);
680 		mutex_exit(&sc->sc_mtx);
681 		return error;
682 	case GPIOSET:
683 		if (kauth_authorize_device(cred, KAUTH_DEVICE_GPIO_PINSET,
684 		    NULL, NULL, NULL, NULL))
685 			return EPERM;
686 
687 		set = data;
688 
689 		if (set->gp_name[0] != '\0')
690 			pin = gpio_pinbyname(sc, set->gp_name);
691 		else
692 			pin = set->gp_pin;
693 
694 		if (pin < 0 || pin >= sc->sc_npins)
695 			return EINVAL;
696 		flags = set->gp_flags;
697 
698 		/* check that the controller supports all requested flags */
699 		if ((flags & sc->sc_pins[pin].pin_caps) != flags)
700 			return ENODEV;
701 		flags = set->gp_flags | GPIO_PIN_SET;
702 
703 		set->gp_caps = sc->sc_pins[pin].pin_caps;
704 		/* return old value */
705 		set->gp_flags = sc->sc_pins[pin].pin_flags;
706 		if (flags > 0) {
707 			gpiobus_pin_ctl(gc, pin, flags);
708 			/* update current value */
709 			sc->sc_pins[pin].pin_flags = flags;
710 		}
711 
712 		/* rename pin or new pin? */
713 		if (set->gp_name2[0] != '\0') {
714 			struct gpio_name *gnm;
715 
716 			gnm = NULL;
717 			LIST_FOREACH(nm, &sc->sc_names, gp_next) {
718 				if (!strcmp(nm->gp_name, set->gp_name2) &&
719 				    nm->gp_pin != pin)
720 					return EINVAL;	/* duplicate name */
721 				if (nm->gp_pin == pin)
722 					gnm = nm;
723 			}
724 			if (gnm != NULL)
725 				strlcpy(gnm->gp_name, set->gp_name2,
726 				    sizeof(gnm->gp_name));
727 			else  {
728 				nm = kmem_alloc(sizeof(struct gpio_name),
729 				    KM_SLEEP);
730 				strlcpy(nm->gp_name, set->gp_name2,
731 				    sizeof(nm->gp_name));
732 				nm->gp_pin = set->gp_pin;
733 				LIST_INSERT_HEAD(&sc->sc_names, nm, gp_next);
734 			}
735 		}
736 		break;
737 	case GPIOUNSET:
738 		if (kauth_authorize_device(cred, KAUTH_DEVICE_GPIO_PINSET,
739 		    NULL, NULL, NULL, NULL))
740 			return EPERM;
741 
742 		set = data;
743 		if (set->gp_name[0] != '\0')
744 			pin = gpio_pinbyname(sc, set->gp_name);
745 		else
746 			pin = set->gp_pin;
747 
748 		if (pin < 0 || pin >= sc->sc_npins)
749 			return EINVAL;
750 		if (sc->sc_pins[pin].pin_mapped)
751 			return EBUSY;
752 		if (!(sc->sc_pins[pin].pin_flags & GPIO_PIN_SET))
753 			return EINVAL;
754 
755 		LIST_FOREACH(nm, &sc->sc_names, gp_next) {
756 			if (nm->gp_pin == pin) {
757 				LIST_REMOVE(nm, gp_next);
758 				kmem_free(nm, sizeof(struct gpio_name));
759 				break;
760 			}
761 		}
762 		sc->sc_pins[pin].pin_flags &= ~GPIO_PIN_SET;
763 		break;
764 	default:
765 #ifdef COMPAT_50
766 		/* Try the old API */
767 		DPRINTF(("%s: trying the old API\n", device_xname(sc->sc_dev)));
768 		return gpio_ioctl_oapi(sc, cmd, data, flag, cred);
769 #else
770 		return ENOTTY;
771 #endif
772 	}
773 	return 0;
774 }
775 
776 #ifdef COMPAT_50
777 static int
778 gpio_ioctl_oapi(struct gpio_softc *sc, u_long cmd, void *data, int flag,
779     kauth_cred_t cred)
780 {
781 	gpio_chipset_tag_t gc;
782 	struct gpio_pin_op *op;
783 	struct gpio_pin_ctl *ctl;
784 	struct gpio_attach *attach;
785 	struct gpio_dev *gdev;
786 
787 	int error, pin, value, flags;
788 
789 	gc = sc->sc_gc;
790 
791 	switch (cmd) {
792 	case GPIOPINREAD:
793 		op = data;
794 
795 		pin = op->gp_pin;
796 
797 		if (pin < 0 || pin >= sc->sc_npins)
798 			return EINVAL;
799 
800 		if (!(sc->sc_pins[pin].pin_flags & GPIO_PIN_SET) &&
801 		    kauth_authorize_device(cred, KAUTH_DEVICE_GPIO_PINSET,
802 		    NULL, NULL, NULL, NULL))
803 			return EPERM;
804 
805 		/* return read value */
806 		op->gp_value = gpiobus_pin_read(gc, pin);
807 		break;
808 	case GPIOPINWRITE:
809 		if ((flag & FWRITE) == 0)
810 			return EBADF;
811 
812 		op = data;
813 
814 		pin = op->gp_pin;
815 
816 		if (pin < 0 || pin >= sc->sc_npins)
817 			return EINVAL;
818 
819 		if (sc->sc_pins[pin].pin_mapped)
820 			return EBUSY;
821 
822 		if (!(sc->sc_pins[pin].pin_flags & GPIO_PIN_SET) &&
823 		    kauth_authorize_device(cred, KAUTH_DEVICE_GPIO_PINSET,
824 		    NULL, NULL, NULL, NULL))
825 			return EPERM;
826 
827 		value = op->gp_value;
828 		if (value != GPIO_PIN_LOW && value != GPIO_PIN_HIGH)
829 			return EINVAL;
830 
831 		gpiobus_pin_write(gc, pin, value);
832 		/* return old value */
833 		op->gp_value = sc->sc_pins[pin].pin_state;
834 		/* update current value */
835 		sc->sc_pins[pin].pin_state = value;
836 		break;
837 	case GPIOPINTOGGLE:
838 		if ((flag & FWRITE) == 0)
839 			return EBADF;
840 
841 		op = data;
842 
843 		pin = op->gp_pin;
844 
845 		if (pin < 0 || pin >= sc->sc_npins)
846 			return EINVAL;
847 
848 		if (sc->sc_pins[pin].pin_mapped)
849 			return EBUSY;
850 
851 		if (!(sc->sc_pins[pin].pin_flags & GPIO_PIN_SET) &&
852 		    kauth_authorize_device(cred, KAUTH_DEVICE_GPIO_PINSET,
853 		    NULL, NULL, NULL, NULL))
854 			return EPERM;
855 
856 		value = (sc->sc_pins[pin].pin_state == GPIO_PIN_LOW ?
857 		    GPIO_PIN_HIGH : GPIO_PIN_LOW);
858 		gpiobus_pin_write(gc, pin, value);
859 		/* return old value */
860 		op->gp_value = sc->sc_pins[pin].pin_state;
861 		/* update current value */
862 		sc->sc_pins[pin].pin_state = value;
863 		break;
864 	case GPIOPINCTL:
865 		ctl = data;
866 
867 		if (kauth_authorize_device(cred, KAUTH_DEVICE_GPIO_PINSET,
868 		    NULL, NULL, NULL, NULL))
869 			return EPERM;
870 
871 		pin = ctl->gp_pin;
872 
873 		if (pin < 0 || pin >= sc->sc_npins)
874 			return EINVAL;
875 		if (sc->sc_pins[pin].pin_mapped)
876 			return EBUSY;
877 		flags = ctl->gp_flags;
878 
879 		/* check that the controller supports all requested flags */
880 		if ((flags & sc->sc_pins[pin].pin_caps) != flags)
881 			return ENODEV;
882 
883 		ctl->gp_caps = sc->sc_pins[pin].pin_caps;
884 		/* return old value */
885 		ctl->gp_flags = sc->sc_pins[pin].pin_flags;
886 		if (flags > 0) {
887 			gpiobus_pin_ctl(gc, pin, flags);
888 			/* update current value */
889 			sc->sc_pins[pin].pin_flags = flags;
890 		}
891 		break;
892 	case GPIODETACH50:
893 		/* FALLTHOUGH */
894 	case GPIODETACH:
895 		if (kauth_authorize_device(cred, KAUTH_DEVICE_GPIO_PINSET,
896 		    NULL, NULL, NULL, NULL))
897 			return EPERM;
898 
899 		error = 0;
900 		mutex_enter(&sc->sc_mtx);
901 		while (sc->sc_attach_busy) {
902 			error = cv_wait_sig(&sc->sc_attach, &sc->sc_mtx);
903 			if (error)
904 				break;
905 		}
906 		if (!error)
907 			sc->sc_attach_busy = 1;
908 		mutex_exit(&sc->sc_mtx);
909 		if (error)
910 			return EBUSY;
911 
912 		attach = data;
913 		LIST_FOREACH(gdev, &sc->sc_devs, sc_next) {
914 			if (strcmp(device_xname(gdev->sc_dev),
915 			    attach->ga_dvname) == 0) {
916 				mutex_enter(&sc->sc_mtx);
917 				sc->sc_attach_busy = 0;
918 				cv_signal(&sc->sc_attach);
919 				mutex_exit(&sc->sc_mtx);
920 
921 				if (config_detach(gdev->sc_dev, 0) == 0)
922 					return 0;
923 				break;
924 			}
925 		}
926 		if (gdev == NULL) {
927 			mutex_enter(&sc->sc_mtx);
928 			sc->sc_attach_busy = 0;
929 			cv_signal(&sc->sc_attach);
930 			mutex_exit(&sc->sc_mtx);
931 		}
932 		return EINVAL;
933 
934 	default:
935 		return ENOTTY;
936 	}
937 	return 0;
938 }
939 #endif	/* COMPAT_50 */
940 
941 MODULE(MODULE_CLASS_DRIVER, gpio, NULL);
942 
943 #ifdef _MODULE
944 #include "ioconf.c"
945 #endif
946 
947 static int
948 gpio_modcmd(modcmd_t cmd, void *opaque)
949 {
950 #ifdef _MODULE
951 	devmajor_t cmajor = NODEVMAJOR, bmajor = NODEVMAJOR;
952 	int error;
953 #endif
954 	switch (cmd) {
955 	case MODULE_CMD_INIT:
956 #ifdef _MODULE
957 		error = config_init_component(cfdriver_ioconf_gpio,
958 		    cfattach_ioconf_gpio, cfdata_ioconf_gpio);
959 		if (error) {
960 			aprint_error("%s: unable to init component\n",
961 			    gpio_cd.cd_name);
962 			return error;
963 		}
964 		error = devsw_attach(gpio_cd.cd_name, NULL, &bmajor,
965 		    &gpio_cdevsw, &cmajor);
966 		if (error) {
967 			aprint_error("%s: unable to register devsw\n",
968 			    gpio_cd.cd_name);
969 			return config_fini_component(cfdriver_ioconf_gpio,
970 			    cfattach_ioconf_gpio, cfdata_ioconf_gpio);
971 		}
972 #endif
973 		return 0;
974 	case MODULE_CMD_FINI:
975 #ifdef _MODULE
976 		config_fini_component(cfdriver_ioconf_gpio,
977 		    cfattach_ioconf_gpio, cfdata_ioconf_gpio);
978 		devsw_detach(NULL, &gpio_cdevsw);
979 #endif
980 		return 0;
981 	default:
982 		return ENOTTY;
983 	}
984 }
985