Sun Mar 28 20:40:30 2021 UTC ()
No need to pass interface attribute or locators to config_search().


(thorpej)
diff -r1.64.10.4 -r1.64.10.5 src/sys/dev/gpio/gpio.c

cvs diff -r1.64.10.4 -r1.64.10.5 src/sys/dev/gpio/gpio.c (switch to unified diff)

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