]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/gpio/gpioc.c
Provide userland notification of gpio pin changes ("userland gpio interrupts").
[FreeBSD/FreeBSD.git] / sys / dev / gpio / gpioc.c
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
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 __FBSDID("$FreeBSD$");
31
32 #include <sys/param.h>
33 #include <sys/systm.h>
34 #include <sys/bus.h>
35 #include <sys/conf.h>
36 #include <sys/gpio.h>
37 #include <sys/ioccom.h>
38 #include <sys/filio.h>
39 #include <sys/fcntl.h>
40 #include <sys/sigio.h>
41 #include <sys/signalvar.h>
42 #include <sys/kernel.h>
43 #include <sys/malloc.h>
44 #include <sys/uio.h>
45 #include <sys/poll.h>
46 #include <sys/selinfo.h>
47 #include <sys/module.h>
48
49 #include <dev/gpio/gpiobusvar.h>
50
51 #include "gpio_if.h"
52 #include "gpiobus_if.h"
53
54 #undef GPIOC_DEBUG
55 #ifdef GPIOC_DEBUG
56 #define dprintf printf
57 #define ddevice_printf device_printf
58 #else
59 #define dprintf(x, arg...)
60 #define ddevice_printf(dev, x, arg...)
61 #endif
62
63 struct gpioc_softc {
64         device_t                sc_dev;         /* gpiocX dev */
65         device_t                sc_pdev;        /* gpioX dev */
66         struct cdev             *sc_ctl_dev;    /* controller device */
67         int                     sc_unit;
68         int                     sc_npins;
69         struct gpioc_pin_intr   *sc_pin_intr;
70 };
71
72 struct gpioc_pin_intr {
73         struct gpioc_softc                              *sc;
74         gpio_pin_t                                      pin;
75         bool                                            config_locked;
76         int                                             intr_rid;
77         struct resource                                 *intr_res;
78         void                                            *intr_cookie;
79         struct mtx                                      mtx;
80         SLIST_HEAD(gpioc_privs_list, gpioc_privs)       privs;
81 };
82
83
84 struct gpioc_cdevpriv {
85         struct gpioc_softc                      *sc;
86         struct selinfo                          selinfo;
87         bool                                    async;
88         uint8_t                                 report_option;
89         struct sigio                            *sigio;
90         struct mtx                              mtx;
91         struct gpioc_pin_event                  *events;
92         int                                     numevents;
93         int                                     evidx_head;
94         int                                     evidx_tail;
95         SLIST_HEAD(gpioc_pins_list, gpioc_pins) pins;
96 };
97
98 struct gpioc_privs {
99         struct gpioc_cdevpriv           *priv;
100         SLIST_ENTRY(gpioc_privs)        next;
101 };
102
103 struct gpioc_pins {
104         struct gpioc_pin_intr   *pin;
105         int                     eventcount;
106         int                     firstevent;
107         SLIST_ENTRY(gpioc_pins) next;
108 };
109
110 struct gpioc_pin_event {
111         struct gpioc_pins       *privpin;
112         sbintime_t              event_time;
113         bool                    event_pin_state;
114 };
115
116 static MALLOC_DEFINE(M_GPIOC, "gpioc", "gpioc device data");
117
118 static int      gpioc_allocate_pin_intr(struct gpioc_pin_intr*, uint32_t);
119 static int      gpioc_release_pin_intr(struct gpioc_pin_intr*);
120 static int      gpioc_attach_priv_pin(struct gpioc_cdevpriv*,
121                     struct gpioc_pin_intr*);
122 static int      gpioc_detach_priv_pin(struct gpioc_cdevpriv*,
123                     struct gpioc_pin_intr*);
124 static bool     gpioc_intr_reconfig_allowed(struct gpioc_cdevpriv*,
125                     struct gpioc_pin_intr *intr_conf);
126 static uint32_t gpioc_get_intr_config(struct gpioc_softc*,
127                     struct gpioc_cdevpriv*, uint32_t pin);
128 static int      gpioc_set_intr_config(struct gpioc_softc*,
129                     struct gpioc_cdevpriv*, uint32_t, uint32_t);
130 static void     gpioc_interrupt_handler(void*);
131
132 static int      gpioc_kqread(struct knote*, long);
133 static void     gpioc_kqdetach(struct knote*);
134
135 static int      gpioc_probe(device_t dev);
136 static int      gpioc_attach(device_t dev);
137 static int      gpioc_detach(device_t dev);
138
139 static void     gpioc_cdevpriv_dtor(void*);
140
141 static d_open_t         gpioc_open;
142 static d_read_t         gpioc_read;
143 static d_ioctl_t        gpioc_ioctl;
144 static d_poll_t         gpioc_poll;
145 static d_kqfilter_t     gpioc_kqfilter;
146
147 static struct cdevsw gpioc_cdevsw = {
148         .d_version      = D_VERSION,
149         .d_open         = gpioc_open,
150         .d_read         = gpioc_read,
151         .d_ioctl        = gpioc_ioctl,
152         .d_poll         = gpioc_poll,
153         .d_kqfilter     = gpioc_kqfilter,
154         .d_name         = "gpioc",
155 };
156
157 static struct filterops gpioc_read_filterops = {
158         .f_isfd =       true,
159         .f_attach =     NULL,
160         .f_detach =     gpioc_kqdetach,
161         .f_event =      gpioc_kqread,
162         .f_touch =      NULL
163 };
164
165 static struct gpioc_pin_event *
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 *
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
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
197 gpioc_allocate_pin_intr(struct gpioc_pin_intr *intr_conf, uint32_t flags)
198 {
199         int err;
200
201         intr_conf->config_locked = true;
202         mtx_unlock(&intr_conf->mtx);
203
204         intr_conf->intr_res = gpio_alloc_intr_resource(intr_conf->pin->dev,
205             &intr_conf->intr_rid, RF_ACTIVE, intr_conf->pin, flags);
206         if (intr_conf->intr_res == NULL) {
207                 err = ENXIO;
208                 goto error_exit;
209         }
210
211         err = bus_setup_intr(intr_conf->pin->dev, intr_conf->intr_res,
212             INTR_TYPE_MISC | INTR_MPSAFE, NULL, gpioc_interrupt_handler,
213             intr_conf, &intr_conf->intr_cookie);
214         if (err != 0)
215                 goto error_exit;
216
217         intr_conf->pin->flags = flags;
218
219 error_exit:
220         mtx_lock(&intr_conf->mtx);
221         intr_conf->config_locked = false;
222         wakeup(&intr_conf->config_locked);
223
224         return (err);
225 }
226
227 static int
228 gpioc_release_pin_intr(struct gpioc_pin_intr *intr_conf)
229 {
230         int err;
231
232         intr_conf->config_locked = true;
233         mtx_unlock(&intr_conf->mtx);
234
235         if (intr_conf->intr_cookie != NULL) {
236                 err = bus_teardown_intr(intr_conf->pin->dev,
237                     intr_conf->intr_res, intr_conf->intr_cookie);
238                 if (err != 0)
239                         goto error_exit;
240                 else
241                         intr_conf->intr_cookie = NULL;
242         }
243
244         if (intr_conf->intr_res != NULL) {
245                 err = bus_release_resource(intr_conf->pin->dev, SYS_RES_IRQ,
246                     intr_conf->intr_rid, intr_conf->intr_res);
247                 if (err != 0)
248                         goto error_exit;
249                 else {
250                         intr_conf->intr_rid = 0;
251                         intr_conf->intr_res = NULL;
252                 }
253         }
254
255         intr_conf->pin->flags = 0;
256         err = 0;
257
258 error_exit:
259         mtx_lock(&intr_conf->mtx);
260         intr_conf->config_locked = false;
261         wakeup(&intr_conf->config_locked);
262
263         return (err);
264 }
265
266 static int
267 gpioc_attach_priv_pin(struct gpioc_cdevpriv *priv,
268     struct gpioc_pin_intr *intr_conf)
269 {
270         struct gpioc_privs      *priv_link;
271         struct gpioc_pins       *pin_link;
272         unsigned int            consistency_a, consistency_b;
273
274         consistency_a = 0;
275         consistency_b = 0;
276         mtx_assert(&intr_conf->mtx, MA_OWNED);
277         mtx_lock(&priv->mtx);
278         SLIST_FOREACH(priv_link, &intr_conf->privs, next) {
279                 if (priv_link->priv == priv)
280                         consistency_a++;
281         }
282         KASSERT(consistency_a <= 1,
283             ("inconsistent links between pin config and cdevpriv"));
284         SLIST_FOREACH(pin_link, &priv->pins, next) {
285                 if (pin_link->pin == intr_conf)
286                         consistency_b++;
287         }
288         KASSERT(consistency_a == consistency_b,
289             ("inconsistent links between pin config and cdevpriv"));
290         if (consistency_a == 1 && consistency_b == 1) {
291                 mtx_unlock(&priv->mtx);
292                 return (EEXIST);
293         }
294         priv_link = malloc(sizeof(struct gpioc_privs), M_GPIOC,
295             M_NOWAIT | M_ZERO);
296         if (priv_link == NULL)
297         {
298                 mtx_unlock(&priv->mtx);
299                 return (ENOMEM);
300         }
301         pin_link = malloc(sizeof(struct gpioc_pins), M_GPIOC,
302             M_NOWAIT | M_ZERO);
303         if (pin_link == NULL) {
304                 mtx_unlock(&priv->mtx);
305                 return (ENOMEM);
306         }
307         priv_link->priv = priv;
308         pin_link->pin = intr_conf;
309         SLIST_INSERT_HEAD(&intr_conf->privs, priv_link, next);
310         SLIST_INSERT_HEAD(&priv->pins, pin_link, next);
311         mtx_unlock(&priv->mtx);
312
313         return (0);
314 }
315
316 static int
317 gpioc_detach_priv_pin(struct gpioc_cdevpriv *priv,
318     struct gpioc_pin_intr *intr_conf)
319 {
320         struct gpioc_privs      *priv_link, *priv_link_temp;
321         struct gpioc_pins       *pin_link, *pin_link_temp;
322         unsigned int            consistency_a, consistency_b;
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;
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 devclass_t      gpioc_devclass;
1063
1064 DRIVER_MODULE(gpioc, gpio, gpioc_driver, gpioc_devclass, 0, 0);
1065 MODULE_VERSION(gpioc, 1);