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