xref: /freebsd/sys/dev/gpio/gpioc.c (revision 22cf89c938886d14f5796fc49f9f020c23ea8eaf)
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause
3  *
4  * Copyright (c) 2009 Oleksandr Tymoshenko <gonzo@freebsd.org>
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  */
28 
29 #include <sys/cdefs.h>
30 #include <sys/param.h>
31 #include <sys/systm.h>
32 #include <sys/bus.h>
33 #include <sys/conf.h>
34 #include <sys/gpio.h>
35 #include <sys/ioccom.h>
36 #include <sys/filio.h>
37 #include <sys/fcntl.h>
38 #include <sys/sigio.h>
39 #include <sys/signalvar.h>
40 #include <sys/kernel.h>
41 #include <sys/malloc.h>
42 #include <sys/uio.h>
43 #include <sys/poll.h>
44 #include <sys/selinfo.h>
45 #include <sys/module.h>
46 
47 #include <dev/gpio/gpiobusvar.h>
48 
49 #include "gpio_if.h"
50 #include "gpiobus_if.h"
51 
52 #undef GPIOC_DEBUG
53 #ifdef GPIOC_DEBUG
54 #define dprintf printf
55 #define ddevice_printf device_printf
56 #else
57 #define dprintf(x, arg...)
58 #define ddevice_printf(dev, x, arg...)
59 #endif
60 
61 struct gpioc_softc {
62 	device_t		sc_dev;		/* gpiocX dev */
63 	device_t		sc_pdev;	/* gpioX dev */
64 	struct cdev		*sc_ctl_dev;	/* controller device */
65 	int			sc_unit;
66 	int			sc_npins;
67 	struct gpioc_pin_intr	*sc_pin_intr;
68 };
69 
70 struct gpioc_pin_intr {
71 	struct gpioc_softc				*sc;
72 	gpio_pin_t					pin;
73 	bool						config_locked;
74 	int						intr_rid;
75 	struct resource					*intr_res;
76 	void						*intr_cookie;
77 	struct mtx					mtx;
78 	SLIST_HEAD(gpioc_privs_list, gpioc_privs)	privs;
79 };
80 
81 
82 struct gpioc_cdevpriv {
83 	struct gpioc_softc			*sc;
84 	struct selinfo				selinfo;
85 	bool					async;
86 	uint8_t					report_option;
87 	struct sigio				*sigio;
88 	struct mtx				mtx;
89 	struct gpioc_pin_event			*events;
90 	int					numevents;
91 	int					evidx_head;
92 	int					evidx_tail;
93 	SLIST_HEAD(gpioc_pins_list, gpioc_pins)	pins;
94 };
95 
96 struct gpioc_privs {
97 	struct gpioc_cdevpriv		*priv;
98 	SLIST_ENTRY(gpioc_privs)	next;
99 };
100 
101 struct gpioc_pins {
102 	struct gpioc_pin_intr	*pin;
103 	int			eventcount;
104 	int			firstevent;
105 	SLIST_ENTRY(gpioc_pins)	next;
106 };
107 
108 struct gpioc_pin_event {
109 	struct gpioc_pins	*privpin;
110 	sbintime_t		event_time;
111 	bool			event_pin_state;
112 };
113 
114 static MALLOC_DEFINE(M_GPIOC, "gpioc", "gpioc device data");
115 
116 static int	gpioc_allocate_pin_intr(struct gpioc_pin_intr*, uint32_t);
117 static int	gpioc_release_pin_intr(struct gpioc_pin_intr*);
118 static int	gpioc_attach_priv_pin(struct gpioc_cdevpriv*,
119 		    struct gpioc_pin_intr*);
120 static int	gpioc_detach_priv_pin(struct gpioc_cdevpriv*,
121 		    struct gpioc_pin_intr*);
122 static bool	gpioc_intr_reconfig_allowed(struct gpioc_cdevpriv*,
123 		    struct gpioc_pin_intr *intr_conf);
124 static uint32_t	gpioc_get_intr_config(struct gpioc_softc*,
125 		    struct gpioc_cdevpriv*, uint32_t pin);
126 static int	gpioc_set_intr_config(struct gpioc_softc*,
127 		    struct gpioc_cdevpriv*, uint32_t, uint32_t);
128 static void	gpioc_interrupt_handler(void*);
129 
130 static int	gpioc_kqread(struct knote*, long);
131 static void	gpioc_kqdetach(struct knote*);
132 
133 static int	gpioc_probe(device_t dev);
134 static int	gpioc_attach(device_t dev);
135 static int	gpioc_detach(device_t dev);
136 
137 static void	gpioc_cdevpriv_dtor(void*);
138 
139 static d_open_t		gpioc_open;
140 static d_read_t		gpioc_read;
141 static d_ioctl_t	gpioc_ioctl;
142 static d_poll_t		gpioc_poll;
143 static d_kqfilter_t	gpioc_kqfilter;
144 
145 static struct cdevsw gpioc_cdevsw = {
146 	.d_version	= D_VERSION,
147 	.d_open		= gpioc_open,
148 	.d_read		= gpioc_read,
149 	.d_ioctl	= gpioc_ioctl,
150 	.d_poll		= gpioc_poll,
151 	.d_kqfilter	= gpioc_kqfilter,
152 	.d_name		= "gpioc",
153 };
154 
155 static struct filterops gpioc_read_filterops = {
156 	.f_isfd =	true,
157 	.f_attach =	NULL,
158 	.f_detach =	gpioc_kqdetach,
159 	.f_event =	gpioc_kqread,
160 	.f_touch =	NULL
161 };
162 
163 static struct gpioc_pin_event *
164 next_head_event(struct gpioc_cdevpriv *priv)
165 {
166 	struct gpioc_pin_event *rv;
167 
168 	rv = &priv->events[priv->evidx_head++];
169 	if (priv->evidx_head == priv->numevents)
170 		priv->evidx_head = 0;
171 	return (rv);
172 }
173 
174 static struct gpioc_pin_event *
175 next_tail_event(struct gpioc_cdevpriv *priv)
176 {
177 	struct gpioc_pin_event *rv;
178 
179 	rv = &priv->events[priv->evidx_tail++];
180 	if (priv->evidx_tail == priv->numevents)
181 		priv->evidx_tail = 0;
182 	return (rv);
183 }
184 
185 static size_t
186 number_of_events(struct gpioc_cdevpriv *priv)
187 {
188 	if (priv->evidx_head >= priv->evidx_tail)
189 		return (priv->evidx_head - priv->evidx_tail);
190 	else
191 		return (priv->numevents + priv->evidx_head - priv->evidx_tail);
192 }
193 
194 static int
195 gpioc_allocate_pin_intr(struct gpioc_pin_intr *intr_conf, uint32_t flags)
196 {
197 	int err;
198 
199 	intr_conf->config_locked = true;
200 	mtx_unlock(&intr_conf->mtx);
201 
202 	intr_conf->intr_res = gpio_alloc_intr_resource(intr_conf->pin->dev,
203 	    &intr_conf->intr_rid, RF_ACTIVE, intr_conf->pin, flags);
204 	if (intr_conf->intr_res == NULL) {
205 		err = ENXIO;
206 		goto error_exit;
207 	}
208 
209 	err = bus_setup_intr(intr_conf->pin->dev, intr_conf->intr_res,
210 	    INTR_TYPE_MISC | INTR_MPSAFE, NULL, gpioc_interrupt_handler,
211 	    intr_conf, &intr_conf->intr_cookie);
212 	if (err != 0)
213 		goto error_exit;
214 
215 	intr_conf->pin->flags = flags;
216 
217 error_exit:
218 	mtx_lock(&intr_conf->mtx);
219 	intr_conf->config_locked = false;
220 	wakeup(&intr_conf->config_locked);
221 
222 	return (err);
223 }
224 
225 static int
226 gpioc_release_pin_intr(struct gpioc_pin_intr *intr_conf)
227 {
228 	int err;
229 
230 	intr_conf->config_locked = true;
231 	mtx_unlock(&intr_conf->mtx);
232 
233 	if (intr_conf->intr_cookie != NULL) {
234 		err = bus_teardown_intr(intr_conf->pin->dev,
235 		    intr_conf->intr_res, intr_conf->intr_cookie);
236 		if (err != 0)
237 			goto error_exit;
238 		else
239 			intr_conf->intr_cookie = NULL;
240 	}
241 
242 	if (intr_conf->intr_res != NULL) {
243 		err = bus_release_resource(intr_conf->pin->dev, SYS_RES_IRQ,
244 		    intr_conf->intr_rid, intr_conf->intr_res);
245 		if (err != 0)
246 			goto error_exit;
247 		else {
248 			intr_conf->intr_rid = 0;
249 			intr_conf->intr_res = NULL;
250 		}
251 	}
252 
253 	intr_conf->pin->flags = 0;
254 	err = 0;
255 
256 error_exit:
257 	mtx_lock(&intr_conf->mtx);
258 	intr_conf->config_locked = false;
259 	wakeup(&intr_conf->config_locked);
260 
261 	return (err);
262 }
263 
264 static int
265 gpioc_attach_priv_pin(struct gpioc_cdevpriv *priv,
266     struct gpioc_pin_intr *intr_conf)
267 {
268 	struct gpioc_privs	*priv_link;
269 	struct gpioc_pins	*pin_link;
270 	unsigned int		consistency_a __diagused;
271 	unsigned int		consistency_b __diagused;
272 
273 	consistency_a = 0;
274 	consistency_b = 0;
275 	mtx_assert(&intr_conf->mtx, MA_OWNED);
276 	mtx_lock(&priv->mtx);
277 	SLIST_FOREACH(priv_link, &intr_conf->privs, next) {
278 		if (priv_link->priv == priv)
279 			consistency_a++;
280 	}
281 	KASSERT(consistency_a <= 1,
282 	    ("inconsistent links between pin config and cdevpriv"));
283 	SLIST_FOREACH(pin_link, &priv->pins, next) {
284 		if (pin_link->pin == intr_conf)
285 			consistency_b++;
286 	}
287 	KASSERT(consistency_a == consistency_b,
288 	    ("inconsistent links between pin config and cdevpriv"));
289 	if (consistency_a == 1 && consistency_b == 1) {
290 		mtx_unlock(&priv->mtx);
291 		return (EEXIST);
292 	}
293 	priv_link = malloc(sizeof(struct gpioc_privs), M_GPIOC,
294 	    M_NOWAIT | M_ZERO);
295 	if (priv_link == NULL)
296 	{
297 		mtx_unlock(&priv->mtx);
298 		return (ENOMEM);
299 	}
300 	pin_link = malloc(sizeof(struct gpioc_pins), M_GPIOC,
301 	    M_NOWAIT | M_ZERO);
302 	if (pin_link == NULL) {
303 		mtx_unlock(&priv->mtx);
304 		return (ENOMEM);
305 	}
306 	priv_link->priv = priv;
307 	pin_link->pin = intr_conf;
308 	SLIST_INSERT_HEAD(&intr_conf->privs, priv_link, next);
309 	SLIST_INSERT_HEAD(&priv->pins, pin_link, next);
310 	mtx_unlock(&priv->mtx);
311 
312 	return (0);
313 }
314 
315 static int
316 gpioc_detach_priv_pin(struct gpioc_cdevpriv *priv,
317     struct gpioc_pin_intr *intr_conf)
318 {
319 	struct gpioc_privs	*priv_link, *priv_link_temp;
320 	struct gpioc_pins	*pin_link, *pin_link_temp;
321 	unsigned int		consistency_a __diagused;
322 	unsigned int		consistency_b __diagused;
323 
324 	consistency_a = 0;
325 	consistency_b = 0;
326 	mtx_assert(&intr_conf->mtx, MA_OWNED);
327 	mtx_lock(&priv->mtx);
328 	SLIST_FOREACH_SAFE(priv_link, &intr_conf->privs, next, priv_link_temp) {
329 		if (priv_link->priv == priv) {
330 			SLIST_REMOVE(&intr_conf->privs, priv_link, gpioc_privs,
331 			    next);
332 			free(priv_link, M_GPIOC);
333 			consistency_a++;
334 		}
335 	}
336 	KASSERT(consistency_a <= 1,
337 	    ("inconsistent links between pin config and cdevpriv"));
338 	SLIST_FOREACH_SAFE(pin_link, &priv->pins, next, pin_link_temp) {
339 		if (pin_link->pin == intr_conf) {
340 			/*
341 			 * If the pin we're removing has events in the priv's
342 			 * event fifo, we can't leave dangling pointers from
343 			 * those events to the gpioc_pins struct we're about to
344 			 * free.  We also can't remove random items and leave
345 			 * holes in the events fifo, so just empty it out.
346 			 */
347 			if (pin_link->eventcount > 0) {
348 				priv->evidx_head = priv->evidx_tail = 0;
349 			}
350 			SLIST_REMOVE(&priv->pins, pin_link, gpioc_pins, next);
351 			free(pin_link, M_GPIOC);
352 			consistency_b++;
353 		}
354 	}
355 	KASSERT(consistency_a == consistency_b,
356 	    ("inconsistent links between pin config and cdevpriv"));
357 	mtx_unlock(&priv->mtx);
358 
359 	return (0);
360 }
361 
362 static bool
363 gpioc_intr_reconfig_allowed(struct gpioc_cdevpriv *priv,
364     struct gpioc_pin_intr *intr_conf)
365 {
366 	struct gpioc_privs	*priv_link;
367 
368 	mtx_assert(&intr_conf->mtx, MA_OWNED);
369 
370 	if (SLIST_EMPTY(&intr_conf->privs))
371 		return (true);
372 
373 	SLIST_FOREACH(priv_link, &intr_conf->privs, next) {
374 		if (priv_link->priv != priv)
375 			return (false);
376 	}
377 
378 	return (true);
379 }
380 
381 
382 static uint32_t
383 gpioc_get_intr_config(struct gpioc_softc *sc, struct gpioc_cdevpriv *priv,
384     uint32_t pin)
385 {
386 	struct gpioc_pin_intr	*intr_conf = &sc->sc_pin_intr[pin];
387 	struct gpioc_privs	*priv_link;
388 	uint32_t		flags;
389 
390 	flags = intr_conf->pin->flags;
391 
392 	if (flags == 0)
393 		return (0);
394 
395 	mtx_lock(&intr_conf->mtx);
396 	SLIST_FOREACH(priv_link, &intr_conf->privs, next) {
397 		if (priv_link->priv == priv) {
398 			flags |= GPIO_INTR_ATTACHED;
399 			break;
400 		}
401 	}
402 	mtx_unlock(&intr_conf->mtx);
403 
404 	return (flags);
405 }
406 
407 static int
408 gpioc_set_intr_config(struct gpioc_softc *sc, struct gpioc_cdevpriv *priv,
409     uint32_t pin, uint32_t flags)
410 {
411 	struct gpioc_pin_intr *intr_conf = &sc->sc_pin_intr[pin];
412 	int res;
413 
414 	res = 0;
415 	if (intr_conf->pin->flags == 0 && flags == 0) {
416 		/* No interrupt configured and none requested: Do nothing. */
417 		return (0);
418 	}
419 	mtx_lock(&intr_conf->mtx);
420 	while (intr_conf->config_locked == true)
421 		mtx_sleep(&intr_conf->config_locked, &intr_conf->mtx, 0,
422 		    "gpicfg", 0);
423 	if (intr_conf->pin->flags == 0 && flags != 0) {
424 		/*
425 		 * No interrupt is configured, but one is requested: Allocate
426 		 * and setup interrupt on the according pin.
427 		 */
428 		res = gpioc_allocate_pin_intr(intr_conf, flags);
429 		if (res == 0)
430 			res = gpioc_attach_priv_pin(priv, intr_conf);
431 		if (res == EEXIST)
432 			res = 0;
433 	} else if (intr_conf->pin->flags == flags) {
434 		/*
435 		 * Same interrupt requested as already configured: Attach the
436 		 * cdevpriv to the corresponding pin.
437 		 */
438 		res = gpioc_attach_priv_pin(priv, intr_conf);
439 		if (res == EEXIST)
440 			res = 0;
441 	} else if (intr_conf->pin->flags != 0 && flags == 0) {
442 		/*
443 		 * Interrupt configured, but none requested: Teardown and
444 		 * release the pin when no other cdevpriv is attached. Otherwise
445 		 * just detach pin and cdevpriv from each other.
446 		 */
447 		if (gpioc_intr_reconfig_allowed(priv, intr_conf)) {
448 			res = gpioc_release_pin_intr(intr_conf);
449 		}
450 		if (res == 0)
451 			res = gpioc_detach_priv_pin(priv, intr_conf);
452 	} else {
453 		/*
454 		 * Other flag requested than configured: Reconfigure when no
455 		 * other cdevpriv is are attached to the pin.
456 		 */
457 		if (!gpioc_intr_reconfig_allowed(priv, intr_conf))
458 			res = EBUSY;
459 		else {
460 			res = gpioc_release_pin_intr(intr_conf);
461 			if (res == 0)
462 				res = gpioc_allocate_pin_intr(intr_conf, flags);
463 			if (res == 0)
464 				res = gpioc_attach_priv_pin(priv, intr_conf);
465 			if (res == EEXIST)
466 				res = 0;
467 		}
468 	}
469 	mtx_unlock(&intr_conf->mtx);
470 
471 	return (res);
472 }
473 
474 static void
475 gpioc_interrupt_handler(void *arg)
476 {
477 	struct gpioc_pin_intr *intr_conf;
478 	struct gpioc_privs *privs;
479 	struct gpioc_softc *sc;
480 	sbintime_t evtime;
481 	uint32_t pin_state;
482 
483 	intr_conf = arg;
484 	sc = intr_conf->sc;
485 
486 	/* Capture time and pin state first. */
487 	evtime = sbinuptime();
488 	if (intr_conf->pin->flags & GPIO_INTR_EDGE_BOTH)
489 		GPIO_PIN_GET(sc->sc_pdev, intr_conf->pin->pin, &pin_state);
490 	else if (intr_conf->pin->flags & GPIO_INTR_EDGE_RISING)
491 		pin_state = true;
492 	else
493 		pin_state = false;
494 
495 	mtx_lock(&intr_conf->mtx);
496 
497 	if (intr_conf->config_locked == true) {
498 		ddevice_printf(sc->sc_dev, "Interrupt configuration in "
499 		    "progress. Discarding interrupt on pin %d.\n",
500 		    intr_conf->pin->pin);
501 		mtx_unlock(&intr_conf->mtx);
502 		return;
503 	}
504 
505 	if (SLIST_EMPTY(&intr_conf->privs)) {
506 		ddevice_printf(sc->sc_dev, "No file descriptor associated with "
507 		    "occurred interrupt on pin %d.\n", intr_conf->pin->pin);
508 		mtx_unlock(&intr_conf->mtx);
509 		return;
510 	}
511 
512 	SLIST_FOREACH(privs, &intr_conf->privs, next) {
513 		struct gpioc_cdevpriv *priv = privs->priv;
514 		struct gpioc_pins *privpin;
515 		struct gpioc_pin_event *event;
516 		mtx_lock(&priv->mtx);
517 		SLIST_FOREACH(privpin, &priv->pins, next) {
518 			if (privpin->pin == intr_conf)
519 				break;
520 		}
521 		if (privpin == NULL) {
522 			/* Should be impossible. */
523 			ddevice_printf(sc->sc_dev, "Cannot find privpin\n");
524 			mtx_unlock(&priv->mtx);
525 			continue;
526 		}
527 
528 		if (priv->report_option == GPIO_EVENT_REPORT_DETAIL) {
529 			event = next_head_event(priv);
530 			/* If head is overtaking tail, advance tail. */
531 			if (priv->evidx_head == priv->evidx_tail)
532 				next_tail_event(priv);
533 		} else {
534 			if (privpin->eventcount > 0)
535 				event = &priv->events[privpin->firstevent + 1];
536 			else {
537 				privpin->firstevent = priv->evidx_head;
538 				event = next_head_event(priv);
539 				event->privpin = privpin;
540 				event->event_time = evtime;
541 				event->event_pin_state = pin_state;
542 				event = next_head_event(priv);
543 			}
544 			++privpin->eventcount;
545 		}
546 		event->privpin = privpin;
547 		event->event_time = evtime;
548 		event->event_pin_state = pin_state;
549 		wakeup(priv);
550 		selwakeup(&priv->selinfo);
551 		KNOTE_LOCKED(&priv->selinfo.si_note, 0);
552 		if (priv->async == true && priv->sigio != NULL)
553 			pgsigio(&priv->sigio, SIGIO, 0);
554 		mtx_unlock(&priv->mtx);
555 	}
556 
557 	mtx_unlock(&intr_conf->mtx);
558 }
559 
560 static int
561 gpioc_probe(device_t dev)
562 {
563 	device_set_desc(dev, "GPIO controller");
564 	return (0);
565 }
566 
567 static int
568 gpioc_attach(device_t dev)
569 {
570 	int err;
571 	struct gpioc_softc *sc;
572 	struct make_dev_args devargs;
573 
574 	sc = device_get_softc(dev);
575 	sc->sc_dev = dev;
576 	sc->sc_pdev = device_get_parent(dev);
577 	sc->sc_unit = device_get_unit(dev);
578 
579 	err = GPIO_PIN_MAX(sc->sc_pdev, &sc->sc_npins);
580 	sc->sc_npins++; /* Number of pins is one more than max pin number. */
581 	if (err != 0)
582 		return (err);
583 	sc->sc_pin_intr = malloc(sizeof(struct gpioc_pin_intr) * sc->sc_npins,
584 	    M_GPIOC, M_WAITOK | M_ZERO);
585 	for (int i = 0; i < sc->sc_npins; i++) {
586 		sc->sc_pin_intr[i].pin = malloc(sizeof(struct gpiobus_pin),
587 		    M_GPIOC, M_WAITOK | M_ZERO);
588 		sc->sc_pin_intr[i].sc = sc;
589 		sc->sc_pin_intr[i].pin->pin = i;
590 		sc->sc_pin_intr[i].pin->dev = sc->sc_pdev;
591 		mtx_init(&sc->sc_pin_intr[i].mtx, "gpioc pin", NULL, MTX_DEF);
592 		SLIST_INIT(&sc->sc_pin_intr[i].privs);
593 	}
594 
595 	make_dev_args_init(&devargs);
596 	devargs.mda_devsw = &gpioc_cdevsw;
597 	devargs.mda_uid = UID_ROOT;
598 	devargs.mda_gid = GID_WHEEL;
599 	devargs.mda_mode = 0600;
600 	devargs.mda_si_drv1 = sc;
601 	err = make_dev_s(&devargs, &sc->sc_ctl_dev, "gpioc%d", sc->sc_unit);
602 	if (err != 0) {
603 		device_printf(dev, "Failed to create gpioc%d", sc->sc_unit);
604 		return (ENXIO);
605 	}
606 
607 	return (0);
608 }
609 
610 static int
611 gpioc_detach(device_t dev)
612 {
613 	struct gpioc_softc *sc = device_get_softc(dev);
614 	int err;
615 
616 	if (sc->sc_ctl_dev)
617 		destroy_dev(sc->sc_ctl_dev);
618 
619 	for (int i = 0; i < sc->sc_npins; i++) {
620 		mtx_destroy(&sc->sc_pin_intr[i].mtx);
621 		free(sc->sc_pin_intr[i].pin, M_GPIOC);
622 	}
623 	free(sc->sc_pin_intr, M_GPIOC);
624 
625 	if ((err = bus_generic_detach(dev)) != 0)
626 		return (err);
627 
628 	return (0);
629 }
630 
631 static void
632 gpioc_cdevpriv_dtor(void *data)
633 {
634 	struct gpioc_cdevpriv	*priv;
635 	struct gpioc_privs	*priv_link, *priv_link_temp;
636 	struct gpioc_pins	*pin_link, *pin_link_temp;
637 	unsigned int		consistency __diagused;
638 
639 	priv = data;
640 
641 	SLIST_FOREACH_SAFE(pin_link, &priv->pins, next, pin_link_temp) {
642 		consistency = 0;
643 		mtx_lock(&pin_link->pin->mtx);
644 		while (pin_link->pin->config_locked == true)
645 			mtx_sleep(&pin_link->pin->config_locked,
646 			    &pin_link->pin->mtx, 0, "gpicfg", 0);
647 		SLIST_FOREACH_SAFE(priv_link, &pin_link->pin->privs, next,
648 		    priv_link_temp) {
649 			if (priv_link->priv == priv) {
650 				SLIST_REMOVE(&pin_link->pin->privs, priv_link,
651 				    gpioc_privs, next);
652 				free(priv_link, M_GPIOC);
653 				consistency++;
654 			}
655 		}
656 		KASSERT(consistency == 1,
657 		    ("inconsistent links between pin config and cdevpriv"));
658 		if (gpioc_intr_reconfig_allowed(priv, pin_link->pin)) {
659 			gpioc_release_pin_intr(pin_link->pin);
660 		}
661 		mtx_unlock(&pin_link->pin->mtx);
662 		SLIST_REMOVE(&priv->pins, pin_link, gpioc_pins, next);
663 		free(pin_link, M_GPIOC);
664 	}
665 
666 	wakeup(&priv);
667 	knlist_clear(&priv->selinfo.si_note, 0);
668 	seldrain(&priv->selinfo);
669 	knlist_destroy(&priv->selinfo.si_note);
670 	funsetown(&priv->sigio);
671 
672 	mtx_destroy(&priv->mtx);
673 	free(priv->events, M_GPIOC);
674 	free(data, M_GPIOC);
675 }
676 
677 static int
678 gpioc_open(struct cdev *dev, int oflags, int devtype, struct thread *td)
679 {
680 	struct gpioc_cdevpriv *priv;
681 	int err;
682 
683 	priv = malloc(sizeof(*priv), M_GPIOC, M_WAITOK | M_ZERO);
684 	priv->sc = dev->si_drv1;
685 	priv->report_option = GPIO_EVENT_REPORT_DETAIL;
686 	err = devfs_set_cdevpriv(priv, gpioc_cdevpriv_dtor);
687 	if (err != 0) {
688 		gpioc_cdevpriv_dtor(priv);
689 		return (err);
690 	}
691 	mtx_init(&priv->mtx, "gpioc priv", NULL, MTX_DEF);
692 	knlist_init_mtx(&priv->selinfo.si_note, &priv->mtx);
693 
694 	/*
695 	 * Allocate a circular buffer for events.  The scheme we use for summary
696 	 * reporting assumes there will always be a pair of events available to
697 	 * record the first/last events on any pin, so we allocate 2 * npins.
698 	 * Even though we actually default to detailed event reporting, 2 *
699 	 * npins isn't a horrible fifo size for that either.
700 	 */
701 	priv->numevents = priv->sc->sc_npins * 2;
702 	priv->events = malloc(priv->numevents * sizeof(struct gpio_event_detail),
703 	    M_GPIOC, M_WAITOK | M_ZERO);
704 
705 	return (0);
706 }
707 
708 static int
709 gpioc_read(struct cdev *dev, struct uio *uio, int ioflag)
710 {
711 	struct gpioc_cdevpriv *priv;
712 	struct gpioc_pin_event *event;
713 	union {
714 		struct gpio_event_summary sum;
715 		struct gpio_event_detail  evt;
716 		uint8_t 		  data[1];
717 	} recbuf;
718 	size_t recsize;
719 	int err;
720 
721 	if ((err = devfs_get_cdevpriv((void **)&priv)) != 0)
722 		return (err);
723 
724 	if (priv->report_option == GPIO_EVENT_REPORT_SUMMARY)
725 		recsize = sizeof(struct gpio_event_summary);
726 	else
727 		recsize = sizeof(struct gpio_event_detail);
728 
729 	if (uio->uio_resid < recsize)
730 		return (EINVAL);
731 
732 	mtx_lock(&priv->mtx);
733 	while (priv->evidx_head == priv->evidx_tail) {
734 		if (SLIST_EMPTY(&priv->pins)) {
735 			err = ENXIO;
736 			break;
737 		} else if (ioflag & O_NONBLOCK) {
738 			err = EWOULDBLOCK;
739 			break;
740 		} else {
741 			err = mtx_sleep(priv, &priv->mtx, PCATCH, "gpintr", 0);
742 			if (err != 0)
743 				break;
744 		}
745 	}
746 
747 	while (err == 0 && uio->uio_resid >= recsize &&
748            priv->evidx_tail != priv->evidx_head) {
749 		event = next_tail_event(priv);
750 		if (priv->report_option == GPIO_EVENT_REPORT_SUMMARY) {
751 			recbuf.sum.gp_first_time = event->event_time;
752 			recbuf.sum.gp_pin = event->privpin->pin->pin->pin;
753 			recbuf.sum.gp_count = event->privpin->eventcount;
754 			recbuf.sum.gp_first_state = event->event_pin_state;
755 			event = next_tail_event(priv);
756 			recbuf.sum.gp_last_time = event->event_time;
757 			recbuf.sum.gp_last_state = event->event_pin_state;
758 			event->privpin->eventcount = 0;
759 			event->privpin->firstevent = 0;
760 		} else {
761 			recbuf.evt.gp_time = event->event_time;
762 			recbuf.evt.gp_pin = event->privpin->pin->pin->pin;
763 			recbuf.evt.gp_pinstate = event->event_pin_state;
764 		}
765 		mtx_unlock(&priv->mtx);
766 		err = uiomove(recbuf.data, recsize, uio);
767 		mtx_lock(&priv->mtx);
768 	}
769 	mtx_unlock(&priv->mtx);
770 	return (err);
771 }
772 
773 static int
774 gpioc_ioctl(struct cdev *cdev, u_long cmd, caddr_t arg, int fflag,
775     struct thread *td)
776 {
777 	device_t bus;
778 	int max_pin, res;
779 	struct gpioc_softc *sc = cdev->si_drv1;
780 	struct gpioc_cdevpriv *priv;
781 	struct gpio_pin pin;
782 	struct gpio_req req;
783 	struct gpio_access_32 *a32;
784 	struct gpio_config_32 *c32;
785 	struct gpio_event_config *evcfg;
786 	uint32_t caps, intrflags;
787 
788 	bus = GPIO_GET_BUS(sc->sc_pdev);
789 	if (bus == NULL)
790 		return (EINVAL);
791 	switch (cmd) {
792 	case GPIOMAXPIN:
793 		max_pin = -1;
794 		res = GPIO_PIN_MAX(sc->sc_pdev, &max_pin);
795 		bcopy(&max_pin, arg, sizeof(max_pin));
796 		break;
797 	case GPIOGETCONFIG:
798 		bcopy(arg, &pin, sizeof(pin));
799 		dprintf("get config pin %d\n", pin.gp_pin);
800 		res = GPIO_PIN_GETFLAGS(sc->sc_pdev, pin.gp_pin,
801 		    &pin.gp_flags);
802 		/* Fail early */
803 		if (res)
804 			break;
805 		res = devfs_get_cdevpriv((void **)&priv);
806 		if (res)
807 			break;
808 		pin.gp_flags |= gpioc_get_intr_config(sc, priv,
809 		    pin.gp_pin);
810 		GPIO_PIN_GETCAPS(sc->sc_pdev, pin.gp_pin, &pin.gp_caps);
811 		GPIOBUS_PIN_GETNAME(bus, pin.gp_pin, pin.gp_name);
812 		bcopy(&pin, arg, sizeof(pin));
813 		break;
814 	case GPIOSETCONFIG:
815 		bcopy(arg, &pin, sizeof(pin));
816 		dprintf("set config pin %d\n", pin.gp_pin);
817 		res = devfs_get_cdevpriv((void **)&priv);
818 		if (res != 0)
819 			break;
820 		res = GPIO_PIN_GETCAPS(sc->sc_pdev, pin.gp_pin, &caps);
821 		if (res != 0)
822 			break;
823 		res = gpio_check_flags(caps, pin.gp_flags);
824 		if (res != 0)
825 			break;
826 		intrflags = pin.gp_flags & GPIO_INTR_MASK;
827 		/*
828 		 * We can do only edge interrupts, and only if the
829 		 * hardware supports that interrupt type on that pin.
830 		 */
831 		switch (intrflags) {
832 		case GPIO_INTR_NONE:
833 			break;
834 		case GPIO_INTR_EDGE_RISING:
835 		case GPIO_INTR_EDGE_FALLING:
836 		case GPIO_INTR_EDGE_BOTH:
837 			if ((intrflags & caps) == 0)
838 				res = EOPNOTSUPP;
839 			break;
840 		default:
841 			res = EINVAL;
842 			break;
843 		}
844 		if (res != 0)
845 			break;
846 		res = GPIO_PIN_SETFLAGS(sc->sc_pdev, pin.gp_pin,
847 		    (pin.gp_flags & ~GPIO_INTR_MASK));
848 		if (res != 0)
849 			break;
850 		res = gpioc_set_intr_config(sc, priv, pin.gp_pin,
851 		    intrflags);
852 		break;
853 	case GPIOGET:
854 		bcopy(arg, &req, sizeof(req));
855 		res = GPIO_PIN_GET(sc->sc_pdev, req.gp_pin,
856 		    &req.gp_value);
857 		dprintf("read pin %d -> %d\n",
858 		    req.gp_pin, req.gp_value);
859 		bcopy(&req, arg, sizeof(req));
860 		break;
861 	case GPIOSET:
862 		bcopy(arg, &req, sizeof(req));
863 		res = GPIO_PIN_SET(sc->sc_pdev, req.gp_pin,
864 		    req.gp_value);
865 		dprintf("write pin %d -> %d\n",
866 		    req.gp_pin, req.gp_value);
867 		break;
868 	case GPIOTOGGLE:
869 		bcopy(arg, &req, sizeof(req));
870 		dprintf("toggle pin %d\n",
871 		    req.gp_pin);
872 		res = GPIO_PIN_TOGGLE(sc->sc_pdev, req.gp_pin);
873 		break;
874 	case GPIOSETNAME:
875 		bcopy(arg, &pin, sizeof(pin));
876 		dprintf("set name on pin %d\n", pin.gp_pin);
877 		res = GPIOBUS_PIN_SETNAME(bus, pin.gp_pin,
878 		    pin.gp_name);
879 		break;
880 	case GPIOACCESS32:
881 		a32 = (struct gpio_access_32 *)arg;
882 		res = GPIO_PIN_ACCESS_32(sc->sc_pdev, a32->first_pin,
883 		    a32->clear_pins, a32->change_pins, &a32->orig_pins);
884 		break;
885 	case GPIOCONFIG32:
886 		c32 = (struct gpio_config_32 *)arg;
887 		res = GPIO_PIN_CONFIG_32(sc->sc_pdev, c32->first_pin,
888 		    c32->num_pins, c32->pin_flags);
889 		break;
890 	case GPIOCONFIGEVENTS:
891 		evcfg = (struct gpio_event_config *)arg;
892 		res = devfs_get_cdevpriv((void **)&priv);
893 		if (res != 0)
894 			break;
895 		/* If any pins have been configured, changes aren't allowed. */
896 		if (!SLIST_EMPTY(&priv->pins)) {
897 			res = EINVAL;
898 			break;
899 		}
900 		if (evcfg->gp_report_type != GPIO_EVENT_REPORT_DETAIL &&
901 		    evcfg->gp_report_type != GPIO_EVENT_REPORT_SUMMARY) {
902 			res = EINVAL;
903 			break;
904 		}
905 		priv->report_option = evcfg->gp_report_type;
906 		/* Reallocate the events buffer if the user wants it bigger. */
907 		if (priv->report_option == GPIO_EVENT_REPORT_DETAIL &&
908 		    priv->numevents < evcfg->gp_fifo_size) {
909 			free(priv->events, M_GPIOC);
910 			priv->numevents = evcfg->gp_fifo_size;
911 			priv->events = malloc(priv->numevents *
912 			    sizeof(struct gpio_event_detail), M_GPIOC,
913 			    M_WAITOK | M_ZERO);
914 			priv->evidx_head = priv->evidx_tail = 0;
915 		}
916 		break;
917 	case FIONBIO:
918 		/*
919 		 * This dummy handler is necessary to prevent fcntl()
920 		 * from failing. The actual handling of non-blocking IO
921 		 * is done using the O_NONBLOCK ioflag passed to the
922 		 * read() syscall.
923 		 */
924 		res = 0;
925 		break;
926 	case FIOASYNC:
927 		res = devfs_get_cdevpriv((void **)&priv);
928 		if (res == 0) {
929 			if (*(int *)arg == FASYNC)
930 				priv->async = true;
931 			else
932 				priv->async = false;
933 		}
934 		break;
935 	case FIOGETOWN:
936 		res = devfs_get_cdevpriv((void **)&priv);
937 		if (res == 0)
938 			*(int *)arg = fgetown(&priv->sigio);
939 		break;
940 	case FIOSETOWN:
941 		res = devfs_get_cdevpriv((void **)&priv);
942 		if (res == 0)
943 			res = fsetown(*(int *)arg, &priv->sigio);
944 		break;
945 	default:
946 		return (ENOTTY);
947 		break;
948 	}
949 
950 	return (res);
951 }
952 
953 static int
954 gpioc_poll(struct cdev *dev, int events, struct thread *td)
955 {
956 	struct gpioc_cdevpriv *priv;
957 	int err;
958 	int revents;
959 
960 	revents = 0;
961 
962 	err = devfs_get_cdevpriv((void **)&priv);
963 	if (err != 0) {
964 		revents = POLLERR;
965 		return (revents);
966 	}
967 
968 	if (SLIST_EMPTY(&priv->pins)) {
969 		revents = POLLHUP;
970 		return (revents);
971 	}
972 
973 	if (events & (POLLIN | POLLRDNORM)) {
974 		if (priv->evidx_head != priv->evidx_tail)
975 			revents |= events & (POLLIN | POLLRDNORM);
976 		else
977 			selrecord(td, &priv->selinfo);
978 	}
979 
980 	return (revents);
981 }
982 
983 static int
984 gpioc_kqfilter(struct cdev *dev, struct knote *kn)
985 {
986 	struct gpioc_cdevpriv *priv;
987 	struct knlist *knlist;
988 	int err;
989 
990 	err = devfs_get_cdevpriv((void **)&priv);
991 	if (err != 0)
992 		return err;
993 
994 	if (SLIST_EMPTY(&priv->pins))
995 		return (ENXIO);
996 
997 	switch(kn->kn_filter) {
998 	case EVFILT_READ:
999 		kn->kn_fop = &gpioc_read_filterops;
1000 		kn->kn_hook = (void *)priv;
1001 		break;
1002 	default:
1003 		return (EOPNOTSUPP);
1004 	}
1005 
1006 	knlist = &priv->selinfo.si_note;
1007 	knlist_add(knlist, kn, 0);
1008 
1009 	return (0);
1010 }
1011 
1012 static int
1013 gpioc_kqread(struct knote *kn, long hint)
1014 {
1015 	struct gpioc_cdevpriv *priv = kn->kn_hook;
1016 	size_t recsize;
1017 
1018 
1019 	if (SLIST_EMPTY(&priv->pins)) {
1020 		kn->kn_flags |= EV_EOF;
1021 		return (1);
1022 	} else {
1023 		if (priv->evidx_head != priv->evidx_tail) {
1024 			if (priv->report_option == GPIO_EVENT_REPORT_SUMMARY)
1025 				recsize = sizeof(struct gpio_event_summary);
1026 			else
1027 				recsize = sizeof(struct gpio_event_detail);
1028 			kn->kn_data = recsize * number_of_events(priv);
1029 			return (1);
1030 		}
1031 	}
1032 	return (0);
1033 }
1034 
1035 static void
1036 gpioc_kqdetach(struct knote *kn)
1037 {
1038 	struct gpioc_cdevpriv *priv = kn->kn_hook;
1039 	struct knlist *knlist = &priv->selinfo.si_note;
1040 
1041 	knlist_remove(knlist, kn, 0);
1042 }
1043 
1044 static device_method_t gpioc_methods[] = {
1045 	/* Device interface */
1046 	DEVMETHOD(device_probe,		gpioc_probe),
1047 	DEVMETHOD(device_attach,	gpioc_attach),
1048 	DEVMETHOD(device_detach,	gpioc_detach),
1049 	DEVMETHOD(device_shutdown,	bus_generic_shutdown),
1050 	DEVMETHOD(device_suspend,	bus_generic_suspend),
1051 	DEVMETHOD(device_resume,	bus_generic_resume),
1052 
1053 	DEVMETHOD_END
1054 };
1055 
1056 driver_t gpioc_driver = {
1057 	"gpioc",
1058 	gpioc_methods,
1059 	sizeof(struct gpioc_softc)
1060 };
1061 
1062 DRIVER_MODULE(gpioc, gpio, gpioc_driver, 0, 0);
1063 MODULE_VERSION(gpioc, 1);
1064