1 /*-
2 * Copyright (c) 2012, 2013 The FreeBSD Foundation
3 * All rights reserved.
4 *
5 * This software was developed by Oleksandr Rybalko under sponsorship
6 * from the FreeBSD Foundation.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 */
29
30 /*
31 * Freescale i.MX515 GPIO driver.
32 */
33
34 #include <sys/cdefs.h>
35 __FBSDID("$FreeBSD$");
36
37 #include "opt_platform.h"
38
39 #include <sys/param.h>
40 #include <sys/systm.h>
41 #include <sys/bus.h>
42
43 #include <sys/kernel.h>
44 #include <sys/module.h>
45 #include <sys/rman.h>
46 #include <sys/lock.h>
47 #include <sys/mutex.h>
48 #include <sys/gpio.h>
49 #include <sys/proc.h>
50
51 #include <machine/bus.h>
52 #include <machine/intr.h>
53 #include <machine/resource.h>
54
55 #include <dev/fdt/fdt_common.h>
56 #include <dev/gpio/gpiobusvar.h>
57 #include <dev/ofw/openfirm.h>
58 #include <dev/ofw/ofw_bus.h>
59 #include <dev/ofw/ofw_bus_subr.h>
60
61 #include "gpio_if.h"
62
63 #ifdef ARM_INTRNG
64 #include "pic_if.h"
65 #endif
66
67 #define WRITE4(_sc, _r, _v) \
68 bus_space_write_4((_sc)->sc_iot, (_sc)->sc_ioh, (_r), (_v))
69 #define READ4(_sc, _r) \
70 bus_space_read_4((_sc)->sc_iot, (_sc)->sc_ioh, (_r))
71 #define SET4(_sc, _r, _m) \
72 WRITE4((_sc), (_r), READ4((_sc), (_r)) | (_m))
73 #define CLEAR4(_sc, _r, _m) \
74 WRITE4((_sc), (_r), READ4((_sc), (_r)) & ~(_m))
75
76 /* Registers definition for Freescale i.MX515 GPIO controller */
77
78 #define IMX_GPIO_DR_REG 0x000 /* Pin Data */
79 #define IMX_GPIO_OE_REG 0x004 /* Set Pin Output */
80 #define IMX_GPIO_PSR_REG 0x008 /* Pad Status */
81 #define IMX_GPIO_ICR1_REG 0x00C /* Interrupt Configuration */
82 #define IMX_GPIO_ICR2_REG 0x010 /* Interrupt Configuration */
83 #define GPIO_ICR_COND_LOW 0
84 #define GPIO_ICR_COND_HIGH 1
85 #define GPIO_ICR_COND_RISE 2
86 #define GPIO_ICR_COND_FALL 3
87 #define IMX_GPIO_IMR_REG 0x014 /* Interrupt Mask Register */
88 #define IMX_GPIO_ISR_REG 0x018 /* Interrupt Status Register */
89 #define IMX_GPIO_EDGE_REG 0x01C /* Edge Detect Register */
90
91 #define DEFAULT_CAPS (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT)
92 #define NGPIO 32
93
94 struct imx51_gpio_softc {
95 device_t dev;
96 device_t sc_busdev;
97 struct mtx sc_mtx;
98 struct resource *sc_res[3]; /* 1 x mem, 2 x IRQ */
99 void *gpio_ih[2];
100 bus_space_tag_t sc_iot;
101 bus_space_handle_t sc_ioh;
102 int gpio_npins;
103 struct gpio_pin gpio_pins[NGPIO];
104 struct intr_irqsrc *gpio_pic_irqsrc[NGPIO];
105 };
106
107 static struct ofw_compat_data compat_data[] = {
108 {"fsl,imx6q-gpio", 1},
109 {"fsl,imx53-gpio", 1},
110 {"fsl,imx51-gpio", 1},
111 {NULL, 0}
112 };
113
114 static struct resource_spec imx_gpio_spec[] = {
115 { SYS_RES_MEMORY, 0, RF_ACTIVE },
116 { SYS_RES_IRQ, 0, RF_ACTIVE },
117 { SYS_RES_IRQ, 1, RF_ACTIVE },
118 { -1, 0 }
119 };
120
121 /*
122 * Helpers
123 */
124 static void imx51_gpio_pin_configure(struct imx51_gpio_softc *,
125 struct gpio_pin *, uint32_t);
126
127 /*
128 * Driver stuff
129 */
130 static int imx51_gpio_probe(device_t);
131 static int imx51_gpio_attach(device_t);
132 static int imx51_gpio_detach(device_t);
133
134 /*
135 * GPIO interface
136 */
137 static device_t imx51_gpio_get_bus(device_t);
138 static int imx51_gpio_pin_max(device_t, int *);
139 static int imx51_gpio_pin_getcaps(device_t, uint32_t, uint32_t *);
140 static int imx51_gpio_pin_getflags(device_t, uint32_t, uint32_t *);
141 static int imx51_gpio_pin_getname(device_t, uint32_t, char *);
142 static int imx51_gpio_pin_setflags(device_t, uint32_t, uint32_t);
143 static int imx51_gpio_pin_set(device_t, uint32_t, unsigned int);
144 static int imx51_gpio_pin_get(device_t, uint32_t, unsigned int *);
145 static int imx51_gpio_pin_toggle(device_t, uint32_t pin);
146
147 #ifdef ARM_INTRNG
148 /*
149 * this is teardown_intr
150 */
151 static void
gpio_pic_disable_intr(device_t dev,struct intr_irqsrc * isrc)152 gpio_pic_disable_intr(device_t dev, struct intr_irqsrc *isrc)
153 {
154 struct imx51_gpio_softc *sc;
155 u_int irq;
156
157 sc = device_get_softc(dev);
158 irq = isrc->isrc_data;
159
160 // XXX Not sure this is necessary
161 mtx_lock_spin(&sc->sc_mtx);
162 CLEAR4(sc, IMX_GPIO_IMR_REG, (1U << irq));
163 WRITE4(sc, IMX_GPIO_ISR_REG, (1U << irq));
164 mtx_unlock_spin(&sc->sc_mtx);
165 }
166
167 /*
168 * this is mask_intr
169 */
170 static void
gpio_pic_disable_source(device_t dev,struct intr_irqsrc * isrc)171 gpio_pic_disable_source(device_t dev, struct intr_irqsrc *isrc)
172 {
173 struct imx51_gpio_softc *sc;
174
175 sc = device_get_softc(dev);
176
177 mtx_lock_spin(&sc->sc_mtx);
178 CLEAR4(sc, IMX_GPIO_IMR_REG, (1U << isrc->isrc_data));
179 mtx_unlock_spin(&sc->sc_mtx);
180 }
181
182 /*
183 * this is setup_intr
184 */
185 static void
gpio_pic_enable_intr(device_t dev,struct intr_irqsrc * isrc)186 gpio_pic_enable_intr(device_t dev, struct intr_irqsrc *isrc)
187 {
188 struct imx51_gpio_softc *sc;
189 int icfg;
190 u_int irq, reg, shift, wrk;
191
192 sc = device_get_softc(dev);
193
194 if (isrc->isrc_trig == INTR_TRIGGER_LEVEL) {
195 if (isrc->isrc_pol == INTR_POLARITY_LOW)
196 icfg = GPIO_ICR_COND_LOW;
197 else
198 icfg = GPIO_ICR_COND_HIGH;
199 } else {
200 if (isrc->isrc_pol == INTR_POLARITY_HIGH)
201 icfg = GPIO_ICR_COND_FALL;
202 else
203 icfg = GPIO_ICR_COND_RISE;
204 }
205
206 irq = isrc->isrc_data;
207 if (irq < 16) {
208 reg = IMX_GPIO_ICR1_REG;
209 shift = 2 * irq;
210 } else {
211 reg = IMX_GPIO_ICR2_REG;
212 shift = 2 * (irq - 16);
213 }
214
215 mtx_lock_spin(&sc->sc_mtx);
216 CLEAR4(sc, IMX_GPIO_IMR_REG, (1U << irq));
217 WRITE4(sc, IMX_GPIO_ISR_REG, (1U << irq));
218 wrk = READ4(sc, reg);
219 wrk &= ~(0x03 << shift);
220 wrk |= icfg << shift;
221 WRITE4(sc, reg, wrk);
222 mtx_unlock_spin(&sc->sc_mtx);
223 }
224
225 /*
226 * this is unmask_intr
227 */
228 static void
gpio_pic_enable_source(device_t dev,struct intr_irqsrc * isrc)229 gpio_pic_enable_source(device_t dev, struct intr_irqsrc *isrc)
230 {
231 struct imx51_gpio_softc *sc;
232
233 sc = device_get_softc(dev);
234
235 mtx_lock_spin(&sc->sc_mtx);
236 SET4(sc, IMX_GPIO_IMR_REG, (1U << isrc->isrc_data));
237 mtx_unlock_spin(&sc->sc_mtx);
238 }
239
240 static void
gpio_pic_post_filter(device_t dev,struct intr_irqsrc * isrc)241 gpio_pic_post_filter(device_t dev, struct intr_irqsrc *isrc)
242 {
243 struct imx51_gpio_softc *sc;
244
245 sc = device_get_softc(dev);
246
247 arm_irq_memory_barrier(0);
248 /* EOI. W1C reg so no r-m-w, no locking needed. */
249 WRITE4(sc, IMX_GPIO_ISR_REG, (1U << isrc->isrc_data));
250 }
251
252 static void
gpio_pic_post_ithread(device_t dev,struct intr_irqsrc * isrc)253 gpio_pic_post_ithread(device_t dev, struct intr_irqsrc *isrc)
254 {
255
256 arm_irq_memory_barrier(0);
257 gpio_pic_enable_source(dev, isrc);
258 }
259
260 static void
gpio_pic_pre_ithread(device_t dev,struct intr_irqsrc * isrc)261 gpio_pic_pre_ithread(device_t dev, struct intr_irqsrc *isrc)
262 {
263
264 gpio_pic_disable_source(dev, isrc);
265 }
266
267 /*
268 * intrng calls this to make a new isrc known to us.
269 */
270 static int
gpio_pic_register(device_t dev,struct intr_irqsrc * isrc,boolean_t * is_percpu)271 gpio_pic_register(device_t dev, struct intr_irqsrc *isrc, boolean_t *is_percpu)
272 {
273 struct imx51_gpio_softc *sc;
274 u_int irq, tripol;
275
276 sc = device_get_softc(dev);
277
278 /*
279 * From devicetree/bindings/gpio/fsl-imx-gpio.txt:
280 * #interrupt-cells: 2. The first cell is the GPIO number. The second
281 * cell bits[3:0] is used to specify trigger type and level flags:
282 * 1 = low-to-high edge triggered.
283 * 2 = high-to-low edge triggered.
284 * 4 = active high level-sensitive.
285 * 8 = active low level-sensitive.
286 * We can do any single one of these modes, but nothing in combo.
287 */
288
289 if (isrc->isrc_ncells != 2) {
290 device_printf(sc->dev, "Invalid #interrupt-cells");
291 return (EINVAL);
292 }
293
294 irq = isrc->isrc_cells[0];
295 tripol = isrc->isrc_cells[1];
296 if (irq >= sc->gpio_npins) {
297 device_printf(sc->dev, "Invalid interrupt number %d", irq);
298 return (EINVAL);
299 }
300 switch (tripol)
301 {
302 case 1:
303 isrc->isrc_trig = INTR_TRIGGER_EDGE;
304 isrc->isrc_pol = INTR_POLARITY_HIGH;
305 break;
306 case 2:
307 isrc->isrc_trig = INTR_TRIGGER_EDGE;
308 isrc->isrc_pol = INTR_POLARITY_LOW;
309 break;
310 case 4:
311 isrc->isrc_trig = INTR_TRIGGER_LEVEL;
312 isrc->isrc_pol = INTR_POLARITY_HIGH;
313 break;
314 case 8:
315 isrc->isrc_trig = INTR_TRIGGER_LEVEL;
316 isrc->isrc_pol = INTR_POLARITY_LOW;
317 break;
318 default:
319 device_printf(sc->dev, "unsupported trigger/polarity 0x%2x\n",
320 tripol);
321 return (ENOTSUP);
322 }
323 isrc->isrc_nspc_type = INTR_IRQ_NSPC_PLAIN;
324 isrc->isrc_nspc_num = irq;
325
326 /*
327 * 1. The link between ISRC and controller must be set atomically.
328 * 2. Just do things only once in rare case when consumers
329 * of shared interrupt came here at the same moment.
330 */
331 mtx_lock_spin(&sc->sc_mtx);
332 if (sc->gpio_pic_irqsrc[irq] != NULL) {
333 mtx_unlock_spin(&sc->sc_mtx);
334 return (sc->gpio_pic_irqsrc[irq] == isrc ? 0 : EEXIST);
335 }
336 sc->gpio_pic_irqsrc[irq] = isrc;
337 isrc->isrc_data = irq;
338 mtx_unlock_spin(&sc->sc_mtx);
339
340 intr_irq_set_name(isrc, "%s,%u", device_get_nameunit(sc->dev), irq);
341 return (0);
342 }
343
344 static int
gpio_pic_unregister(device_t dev,struct intr_irqsrc * isrc)345 gpio_pic_unregister(device_t dev, struct intr_irqsrc *isrc)
346 {
347 struct imx51_gpio_softc *sc;
348 u_int irq;
349
350 sc = device_get_softc(dev);
351
352 mtx_lock_spin(&sc->sc_mtx);
353 irq = isrc->isrc_data;
354 if (sc->gpio_pic_irqsrc[irq] != isrc) {
355 mtx_unlock_spin(&sc->sc_mtx);
356 return (sc->gpio_pic_irqsrc[irq] == NULL ? 0 : EINVAL);
357 }
358 sc->gpio_pic_irqsrc[irq] = NULL;
359 isrc->isrc_data = 0;
360 mtx_unlock_spin(&sc->sc_mtx);
361
362 intr_irq_set_name(isrc, "");
363 return (0);
364 }
365
366 static int
gpio_pic_filter(void * arg)367 gpio_pic_filter(void *arg)
368 {
369 struct imx51_gpio_softc *sc;
370 uint32_t i, interrupts;
371
372 sc = arg;
373 mtx_lock_spin(&sc->sc_mtx);
374 interrupts = READ4(sc, IMX_GPIO_ISR_REG) & READ4(sc, IMX_GPIO_IMR_REG);
375 mtx_unlock_spin(&sc->sc_mtx);
376
377 for (i = 0; interrupts != 0; i++, interrupts >>= 1) {
378 if ((interrupts & 0x1) == 0)
379 continue;
380 if (sc->gpio_pic_irqsrc[i])
381 intr_irq_dispatch(sc->gpio_pic_irqsrc[i], curthread->td_intr_frame);
382 else
383 device_printf(sc->dev, "spurious interrupt %d\n", i);
384 }
385
386 return (FILTER_HANDLED);
387 }
388 #endif
389
390 /*
391 *
392 */
393 static void
imx51_gpio_pin_configure(struct imx51_gpio_softc * sc,struct gpio_pin * pin,unsigned int flags)394 imx51_gpio_pin_configure(struct imx51_gpio_softc *sc, struct gpio_pin *pin,
395 unsigned int flags)
396 {
397
398 mtx_lock_spin(&sc->sc_mtx);
399
400 /*
401 * Manage input/output
402 */
403 if (flags & (GPIO_PIN_INPUT|GPIO_PIN_OUTPUT)) {
404 pin->gp_flags &= ~(GPIO_PIN_INPUT|GPIO_PIN_OUTPUT);
405 if (flags & GPIO_PIN_OUTPUT) {
406 pin->gp_flags |= GPIO_PIN_OUTPUT;
407 SET4(sc, IMX_GPIO_OE_REG, (1U << pin->gp_pin));
408 }
409 else {
410 pin->gp_flags |= GPIO_PIN_INPUT;
411 CLEAR4(sc, IMX_GPIO_OE_REG, (1U << pin->gp_pin));
412 }
413 }
414
415 mtx_unlock_spin(&sc->sc_mtx);
416 }
417
418 static device_t
imx51_gpio_get_bus(device_t dev)419 imx51_gpio_get_bus(device_t dev)
420 {
421 struct imx51_gpio_softc *sc;
422
423 sc = device_get_softc(dev);
424
425 return (sc->sc_busdev);
426 }
427
428 static int
imx51_gpio_pin_max(device_t dev,int * maxpin)429 imx51_gpio_pin_max(device_t dev, int *maxpin)
430 {
431 struct imx51_gpio_softc *sc;
432
433 sc = device_get_softc(dev);
434 *maxpin = sc->gpio_npins - 1;
435
436 return (0);
437 }
438
439 static int
imx51_gpio_pin_getcaps(device_t dev,uint32_t pin,uint32_t * caps)440 imx51_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps)
441 {
442 struct imx51_gpio_softc *sc;
443 int i;
444
445 sc = device_get_softc(dev);
446 for (i = 0; i < sc->gpio_npins; i++) {
447 if (sc->gpio_pins[i].gp_pin == pin)
448 break;
449 }
450
451 if (i >= sc->gpio_npins)
452 return (EINVAL);
453
454 mtx_lock_spin(&sc->sc_mtx);
455 *caps = sc->gpio_pins[i].gp_caps;
456 mtx_unlock_spin(&sc->sc_mtx);
457
458 return (0);
459 }
460
461 static int
imx51_gpio_pin_getflags(device_t dev,uint32_t pin,uint32_t * flags)462 imx51_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t *flags)
463 {
464 struct imx51_gpio_softc *sc;
465 int i;
466
467 sc = device_get_softc(dev);
468 for (i = 0; i < sc->gpio_npins; i++) {
469 if (sc->gpio_pins[i].gp_pin == pin)
470 break;
471 }
472
473 if (i >= sc->gpio_npins)
474 return (EINVAL);
475
476 mtx_lock_spin(&sc->sc_mtx);
477 *flags = sc->gpio_pins[i].gp_flags;
478 mtx_unlock_spin(&sc->sc_mtx);
479
480 return (0);
481 }
482
483 static int
imx51_gpio_pin_getname(device_t dev,uint32_t pin,char * name)484 imx51_gpio_pin_getname(device_t dev, uint32_t pin, char *name)
485 {
486 struct imx51_gpio_softc *sc;
487 int i;
488
489 sc = device_get_softc(dev);
490 for (i = 0; i < sc->gpio_npins; i++) {
491 if (sc->gpio_pins[i].gp_pin == pin)
492 break;
493 }
494
495 if (i >= sc->gpio_npins)
496 return (EINVAL);
497
498 mtx_lock_spin(&sc->sc_mtx);
499 memcpy(name, sc->gpio_pins[i].gp_name, GPIOMAXNAME);
500 mtx_unlock_spin(&sc->sc_mtx);
501
502 return (0);
503 }
504
505 static int
imx51_gpio_pin_setflags(device_t dev,uint32_t pin,uint32_t flags)506 imx51_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags)
507 {
508 struct imx51_gpio_softc *sc;
509 int i;
510
511 sc = device_get_softc(dev);
512 for (i = 0; i < sc->gpio_npins; i++) {
513 if (sc->gpio_pins[i].gp_pin == pin)
514 break;
515 }
516
517 if (i >= sc->gpio_npins)
518 return (EINVAL);
519
520 imx51_gpio_pin_configure(sc, &sc->gpio_pins[i], flags);
521
522 return (0);
523 }
524
525 static int
imx51_gpio_pin_set(device_t dev,uint32_t pin,unsigned int value)526 imx51_gpio_pin_set(device_t dev, uint32_t pin, unsigned int value)
527 {
528 struct imx51_gpio_softc *sc;
529 int i;
530
531 sc = device_get_softc(dev);
532 for (i = 0; i < sc->gpio_npins; i++) {
533 if (sc->gpio_pins[i].gp_pin == pin)
534 break;
535 }
536
537 if (i >= sc->gpio_npins)
538 return (EINVAL);
539
540 mtx_lock_spin(&sc->sc_mtx);
541 if (value)
542 SET4(sc, IMX_GPIO_DR_REG, (1U << i));
543 else
544 CLEAR4(sc, IMX_GPIO_DR_REG, (1U << i));
545 mtx_unlock_spin(&sc->sc_mtx);
546
547 return (0);
548 }
549
550 static int
imx51_gpio_pin_get(device_t dev,uint32_t pin,unsigned int * val)551 imx51_gpio_pin_get(device_t dev, uint32_t pin, unsigned int *val)
552 {
553 struct imx51_gpio_softc *sc;
554 int i;
555
556 sc = device_get_softc(dev);
557 for (i = 0; i < sc->gpio_npins; i++) {
558 if (sc->gpio_pins[i].gp_pin == pin)
559 break;
560 }
561
562 if (i >= sc->gpio_npins)
563 return (EINVAL);
564
565 mtx_lock_spin(&sc->sc_mtx);
566 *val = (READ4(sc, IMX_GPIO_DR_REG) >> i) & 1;
567 mtx_unlock_spin(&sc->sc_mtx);
568
569 return (0);
570 }
571
572 static int
imx51_gpio_pin_toggle(device_t dev,uint32_t pin)573 imx51_gpio_pin_toggle(device_t dev, uint32_t pin)
574 {
575 struct imx51_gpio_softc *sc;
576 int i;
577
578 sc = device_get_softc(dev);
579 for (i = 0; i < sc->gpio_npins; i++) {
580 if (sc->gpio_pins[i].gp_pin == pin)
581 break;
582 }
583
584 if (i >= sc->gpio_npins)
585 return (EINVAL);
586
587 mtx_lock_spin(&sc->sc_mtx);
588 WRITE4(sc, IMX_GPIO_DR_REG,
589 (READ4(sc, IMX_GPIO_DR_REG) ^ (1U << i)));
590 mtx_unlock_spin(&sc->sc_mtx);
591
592 return (0);
593 }
594
595 static int
imx51_gpio_probe(device_t dev)596 imx51_gpio_probe(device_t dev)
597 {
598
599 if (!ofw_bus_status_okay(dev))
600 return (ENXIO);
601
602 if (ofw_bus_search_compatible(dev, compat_data)->ocd_data != 0) {
603 device_set_desc(dev, "Freescale i.MX GPIO Controller");
604 return (BUS_PROBE_DEFAULT);
605 }
606
607 return (ENXIO);
608 }
609
610 static int
imx51_gpio_attach(device_t dev)611 imx51_gpio_attach(device_t dev)
612 {
613 struct imx51_gpio_softc *sc;
614 int i, irq, unit;
615
616 sc = device_get_softc(dev);
617 sc->dev = dev;
618 sc->gpio_npins = NGPIO;
619
620 mtx_init(&sc->sc_mtx, device_get_nameunit(sc->dev), NULL, MTX_SPIN);
621
622 if (bus_alloc_resources(dev, imx_gpio_spec, sc->sc_res)) {
623 device_printf(dev, "could not allocate resources\n");
624 bus_release_resources(dev, imx_gpio_spec, sc->sc_res);
625 mtx_destroy(&sc->sc_mtx);
626 return (ENXIO);
627 }
628
629 sc->sc_iot = rman_get_bustag(sc->sc_res[0]);
630 sc->sc_ioh = rman_get_bushandle(sc->sc_res[0]);
631 /*
632 * Mask off all interrupts in hardware, then set up interrupt handling.
633 */
634 WRITE4(sc, IMX_GPIO_IMR_REG, 0);
635 for (irq = 0; irq < 2; irq++) {
636 #ifdef ARM_INTRNG
637 if ((bus_setup_intr(dev, sc->sc_res[1 + irq], INTR_TYPE_CLK,
638 gpio_pic_filter, NULL, sc, &sc->gpio_ih[irq]))) {
639 device_printf(dev,
640 "WARNING: unable to register interrupt handler\n");
641 imx51_gpio_detach(dev);
642 return (ENXIO);
643 }
644 #endif
645 }
646
647 unit = device_get_unit(dev);
648 for (i = 0; i < sc->gpio_npins; i++) {
649 sc->gpio_pins[i].gp_pin = i;
650 sc->gpio_pins[i].gp_caps = DEFAULT_CAPS;
651 sc->gpio_pins[i].gp_flags =
652 (READ4(sc, IMX_GPIO_OE_REG) & (1U << i)) ? GPIO_PIN_OUTPUT :
653 GPIO_PIN_INPUT;
654 snprintf(sc->gpio_pins[i].gp_name, GPIOMAXNAME,
655 "imx_gpio%d.%d", unit, i);
656 }
657
658 #ifdef ARM_INTRNG
659 intr_pic_register(dev, OF_xref_from_node(ofw_bus_get_node(dev)));
660 #endif
661 sc->sc_busdev = gpiobus_attach_bus(dev);
662
663 if (sc->sc_busdev == NULL) {
664 imx51_gpio_detach(dev);
665 return (ENXIO);
666 }
667
668 return (0);
669 }
670
671 static int
imx51_gpio_detach(device_t dev)672 imx51_gpio_detach(device_t dev)
673 {
674 int irq;
675 struct imx51_gpio_softc *sc;
676
677 sc = device_get_softc(dev);
678
679 gpiobus_detach_bus(dev);
680 for (irq = 1; irq <= 2; irq++) {
681 if (sc->gpio_ih[irq])
682 bus_teardown_intr(dev, sc->sc_res[irq], sc->gpio_ih[irq]);
683 }
684 bus_release_resources(dev, imx_gpio_spec, sc->sc_res);
685 mtx_destroy(&sc->sc_mtx);
686
687 return(0);
688 }
689
690 static device_method_t imx51_gpio_methods[] = {
691 DEVMETHOD(device_probe, imx51_gpio_probe),
692 DEVMETHOD(device_attach, imx51_gpio_attach),
693 DEVMETHOD(device_detach, imx51_gpio_detach),
694
695 #ifdef ARM_INTRNG
696 /* Interrupt controller interface */
697 DEVMETHOD(pic_disable_intr, gpio_pic_disable_intr),
698 DEVMETHOD(pic_disable_source, gpio_pic_disable_source),
699 DEVMETHOD(pic_enable_intr, gpio_pic_enable_intr),
700 DEVMETHOD(pic_enable_source, gpio_pic_enable_source),
701 DEVMETHOD(pic_post_filter, gpio_pic_post_filter),
702 DEVMETHOD(pic_post_ithread, gpio_pic_post_ithread),
703 DEVMETHOD(pic_pre_ithread, gpio_pic_pre_ithread),
704 DEVMETHOD(pic_register, gpio_pic_register),
705 DEVMETHOD(pic_unregister, gpio_pic_unregister),
706 #endif
707
708 /* GPIO protocol */
709 DEVMETHOD(gpio_get_bus, imx51_gpio_get_bus),
710 DEVMETHOD(gpio_pin_max, imx51_gpio_pin_max),
711 DEVMETHOD(gpio_pin_getname, imx51_gpio_pin_getname),
712 DEVMETHOD(gpio_pin_getflags, imx51_gpio_pin_getflags),
713 DEVMETHOD(gpio_pin_getcaps, imx51_gpio_pin_getcaps),
714 DEVMETHOD(gpio_pin_setflags, imx51_gpio_pin_setflags),
715 DEVMETHOD(gpio_pin_get, imx51_gpio_pin_get),
716 DEVMETHOD(gpio_pin_set, imx51_gpio_pin_set),
717 DEVMETHOD(gpio_pin_toggle, imx51_gpio_pin_toggle),
718 {0, 0},
719 };
720
721 static driver_t imx51_gpio_driver = {
722 "gpio",
723 imx51_gpio_methods,
724 sizeof(struct imx51_gpio_softc),
725 };
726 static devclass_t imx51_gpio_devclass;
727
728 DRIVER_MODULE(imx51_gpio, simplebus, imx51_gpio_driver, imx51_gpio_devclass,
729 0, 0);
730