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