1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3 * 4 * Copyright (c) 2021 Alstom Group. 5 * Copyright (c) 2021 Semihalf. 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 ``AS IS'' AND ANY EXPRESS OR 17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28 #include <sys/cdefs.h> 29 __FBSDID("$FreeBSD$"); 30 31 #include <sys/param.h> 32 #include <sys/systm.h> 33 #include <sys/conf.h> 34 #include <sys/bus.h> 35 #include <sys/kernel.h> 36 #include <sys/module.h> 37 #include <sys/mutex.h> 38 #include <sys/proc.h> 39 #include <sys/rman.h> 40 #include <sys/gpio.h> 41 42 #include <machine/bus.h> 43 #include <machine/resource.h> 44 #include <machine/stdarg.h> 45 46 #include <dev/gpio/gpiobusvar.h> 47 #include <dev/gpio/qoriq_gpio.h> 48 #include <dev/ofw/ofw_bus.h> 49 #include <dev/ofw/ofw_bus_subr.h> 50 51 #include <dt-bindings/interrupt-controller/irq.h> 52 53 #include "gpio_if.h" 54 #include "pic_if.h" 55 56 struct qoriq_gpio_pic_irqsrc { 57 struct intr_irqsrc isrc; 58 int pin; 59 }; 60 61 struct qoriq_gpio_pic_softc { 62 struct qoriq_gpio_softc base; 63 64 struct resource *res_irq; 65 void *irq_cookie; 66 struct qoriq_gpio_pic_irqsrc isrcs[MAXPIN + 1]; 67 struct intr_map_data_gpio gdata; 68 }; 69 70 #define RD4(sc, off) bus_read_4((sc)->base.sc_mem, (off)) 71 #define WR4(sc, off, data) bus_write_4((sc)->base.sc_mem, (off), (data)) 72 73 static device_probe_t qoriq_gpio_pic_probe; 74 static device_attach_t qoriq_gpio_pic_attach; 75 static device_detach_t qoriq_gpio_pic_detach; 76 77 static void 78 qoriq_gpio_pic_set_intr(struct qoriq_gpio_pic_softc *sc, int pin, bool enable) 79 { 80 uint32_t reg; 81 82 reg = RD4(sc, GPIO_GPIMR); 83 if (enable) 84 reg |= BIT(31 - pin); 85 else 86 reg &= ~BIT(31 - pin); 87 WR4(sc, GPIO_GPIMR, reg); 88 } 89 90 static void 91 qoriq_gpio_pic_ack_intr(struct qoriq_gpio_pic_softc *sc, int pin) 92 { 93 uint32_t reg; 94 95 reg = BIT(31 - pin); 96 WR4(sc, GPIO_GPIER, reg); 97 } 98 99 static int 100 qoriq_gpio_pic_intr(void *arg) 101 { 102 struct qoriq_gpio_pic_softc *sc; 103 struct trapframe *tf; 104 uint32_t status; 105 int pin; 106 107 sc = (struct qoriq_gpio_pic_softc *)arg; 108 tf = curthread->td_intr_frame; 109 110 status = RD4(sc, GPIO_GPIER); 111 status &= RD4(sc, GPIO_GPIMR); 112 while (status != 0) { 113 pin = ffs(status) - 1; 114 status &= ~BIT(pin); 115 pin = 31 - pin; 116 117 if (intr_isrc_dispatch(&sc->isrcs[pin].isrc, tf) != 0) { 118 GPIO_LOCK(&sc->base); 119 qoriq_gpio_pic_set_intr(sc, pin, false); 120 qoriq_gpio_pic_ack_intr(sc, pin); 121 GPIO_UNLOCK(&sc->base); 122 device_printf(sc->base.dev, 123 "Masking spurious pin interrupt %d\n", 124 pin); 125 } 126 } 127 128 return (FILTER_HANDLED); 129 } 130 131 static void 132 qoriq_gpio_pic_disable_intr(device_t dev, struct intr_irqsrc *isrc) 133 { 134 struct qoriq_gpio_pic_softc *sc; 135 struct qoriq_gpio_pic_irqsrc *qisrc; 136 137 sc = device_get_softc(dev); 138 qisrc = (struct qoriq_gpio_pic_irqsrc *)isrc; 139 140 GPIO_LOCK(&sc->base); 141 qoriq_gpio_pic_set_intr(sc, qisrc->pin, false); 142 GPIO_UNLOCK(&sc->base); 143 } 144 145 static void 146 qoriq_gpio_pic_enable_intr(device_t dev, struct intr_irqsrc *isrc) 147 { 148 struct qoriq_gpio_pic_softc *sc; 149 struct qoriq_gpio_pic_irqsrc *qisrc; 150 151 sc = device_get_softc(dev); 152 qisrc = (struct qoriq_gpio_pic_irqsrc *)isrc; 153 154 GPIO_LOCK(&sc->base); 155 qoriq_gpio_pic_set_intr(sc, qisrc->pin, true); 156 GPIO_UNLOCK(&sc->base); 157 } 158 159 static struct intr_map_data_gpio* 160 qoriq_gpio_pic_convert_map_data(struct qoriq_gpio_pic_softc *sc, struct intr_map_data *data) 161 { 162 struct intr_map_data_gpio *gdata; 163 struct intr_map_data_fdt *daf; 164 165 switch (data->type) { 166 case INTR_MAP_DATA_GPIO: 167 gdata = (struct intr_map_data_gpio *)data; 168 break; 169 case INTR_MAP_DATA_FDT: 170 daf = (struct intr_map_data_fdt *)data; 171 if (daf->ncells != 2) 172 return (NULL); 173 174 gdata = &sc->gdata; 175 gdata->gpio_pin_num = daf->cells[0]; 176 switch (daf->cells[1]) { 177 case IRQ_TYPE_LEVEL_LOW: 178 gdata->gpio_intr_mode = GPIO_INTR_LEVEL_LOW; 179 break; 180 case IRQ_TYPE_LEVEL_HIGH: 181 gdata->gpio_intr_mode = GPIO_INTR_LEVEL_HIGH; 182 break; 183 case IRQ_TYPE_EDGE_RISING: 184 gdata->gpio_intr_mode = GPIO_INTR_EDGE_RISING; 185 break; 186 case IRQ_TYPE_EDGE_FALLING: 187 gdata->gpio_intr_mode = GPIO_INTR_EDGE_FALLING; 188 break; 189 case IRQ_TYPE_EDGE_BOTH: 190 gdata->gpio_intr_mode = GPIO_INTR_EDGE_BOTH; 191 break; 192 default: 193 return (NULL); 194 } 195 break; 196 default: 197 return (NULL); 198 } 199 200 return (gdata); 201 } 202 203 204 static int 205 qoriq_gpio_pic_map_intr(device_t dev, struct intr_map_data *data, 206 struct intr_irqsrc **isrcp) 207 { 208 struct qoriq_gpio_pic_softc *sc; 209 struct intr_map_data_gpio *gdata; 210 int pin; 211 212 sc = device_get_softc(dev); 213 214 gdata = qoriq_gpio_pic_convert_map_data(sc, data); 215 if (gdata == NULL) 216 return (EINVAL); 217 218 pin = gdata->gpio_pin_num; 219 if (pin > MAXPIN) 220 return (EINVAL); 221 222 *isrcp = &sc->isrcs[pin].isrc; 223 return (0); 224 } 225 226 static int 227 qoriq_gpio_pic_setup_intr(device_t dev, struct intr_irqsrc *isrc, 228 struct resource *res, struct intr_map_data *data) 229 { 230 struct qoriq_gpio_pic_softc *sc; 231 struct intr_map_data_gpio *gdata; 232 struct qoriq_gpio_pic_irqsrc *qisrc; 233 bool falling; 234 uint32_t reg; 235 236 sc = device_get_softc(dev); 237 qisrc = (struct qoriq_gpio_pic_irqsrc *)isrc; 238 239 gdata = qoriq_gpio_pic_convert_map_data(sc, data); 240 if (gdata == NULL) 241 return (EINVAL); 242 243 if (gdata->gpio_intr_mode & GPIO_INTR_EDGE_BOTH) 244 falling = false; 245 else if (gdata->gpio_intr_mode & GPIO_INTR_EDGE_FALLING) 246 falling = true; 247 else 248 return (EOPNOTSUPP); 249 250 GPIO_LOCK(&sc->base); 251 reg = RD4(sc, GPIO_GPICR); 252 if (falling) 253 reg |= BIT(31 - qisrc->pin); 254 else 255 reg &= ~BIT(31 - qisrc->pin); 256 WR4(sc, GPIO_GPICR, reg); 257 GPIO_UNLOCK(&sc->base); 258 259 return (0); 260 } 261 262 static int 263 qoriq_gpio_pic_teardown_intr(device_t dev, struct intr_irqsrc *isrc, 264 struct resource *res, struct intr_map_data *data) 265 { 266 struct qoriq_gpio_pic_softc *sc; 267 struct qoriq_gpio_pic_irqsrc *qisrc; 268 269 sc = device_get_softc(dev); 270 qisrc = (struct qoriq_gpio_pic_irqsrc *)isrc; 271 272 if (isrc->isrc_handlers > 0) 273 return (0); 274 275 GPIO_LOCK(&sc->base); 276 qoriq_gpio_pic_set_intr(sc, qisrc->pin, false); 277 GPIO_UNLOCK(&sc->base); 278 return (0); 279 } 280 281 static void 282 qoriq_gpio_pic_post_filter(device_t dev, struct intr_irqsrc *isrc) 283 { 284 struct qoriq_gpio_pic_softc *sc; 285 struct qoriq_gpio_pic_irqsrc *qisrc; 286 287 sc = device_get_softc(dev); 288 qisrc = (struct qoriq_gpio_pic_irqsrc *)isrc; 289 290 GPIO_LOCK(&sc->base); 291 qoriq_gpio_pic_ack_intr(sc, qisrc->pin); 292 GPIO_UNLOCK(&sc->base); 293 } 294 295 296 static void 297 qoriq_gpio_pic_post_ithread(device_t dev, struct intr_irqsrc *isrc) 298 { 299 struct qoriq_gpio_pic_softc *sc; 300 struct qoriq_gpio_pic_irqsrc *qisrc; 301 302 sc = device_get_softc(dev); 303 qisrc = (struct qoriq_gpio_pic_irqsrc *)isrc; 304 305 GPIO_LOCK(&sc->base); 306 qoriq_gpio_pic_ack_intr(sc, qisrc->pin); 307 qoriq_gpio_pic_set_intr(sc, qisrc->pin, true); 308 GPIO_UNLOCK(&sc->base); 309 } 310 311 static void 312 qoriq_gpio_pic_pre_ithread(device_t dev, struct intr_irqsrc *isrc) 313 { 314 struct qoriq_gpio_pic_softc *sc; 315 struct qoriq_gpio_pic_irqsrc *qisrc; 316 317 sc = device_get_softc(dev); 318 qisrc = (struct qoriq_gpio_pic_irqsrc *)isrc; 319 320 GPIO_LOCK(&sc->base); 321 qoriq_gpio_pic_set_intr(sc, qisrc->pin, false); 322 GPIO_UNLOCK(&sc->base); 323 324 } 325 static int 326 qoriq_gpio_pic_probe(device_t dev) 327 { 328 if (!ofw_bus_status_okay(dev)) 329 return (ENXIO); 330 331 if (!ofw_bus_is_compatible(dev, "fsl,qoriq-gpio")) 332 return (ENXIO); 333 334 device_set_desc(dev, "Freescale QorIQ GPIO PIC driver"); 335 336 return (BUS_PROBE_DEFAULT); 337 } 338 339 static int 340 qoriq_gpio_pic_attach(device_t dev) 341 { 342 struct qoriq_gpio_pic_softc *sc; 343 int error, rid, i; 344 const char *name; 345 intptr_t xref; 346 347 sc = device_get_softc(dev); 348 349 error = qoriq_gpio_attach(dev); 350 if (error != 0) 351 return (error); 352 353 rid = 0; 354 sc->res_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, 355 RF_ACTIVE | RF_SHAREABLE); 356 if (sc->res_irq == NULL) { 357 device_printf(dev, "Can't allocate interrupt resource.\n"); 358 error = ENOMEM; 359 goto fail; 360 } 361 362 error = bus_setup_intr(dev, sc->res_irq, INTR_TYPE_MISC | INTR_MPSAFE, 363 qoriq_gpio_pic_intr, NULL, sc, &sc->irq_cookie); 364 if (error != 0) { 365 device_printf(dev, "Failed to setup interrupt.\n"); 366 goto fail; 367 } 368 369 name = device_get_nameunit(dev); 370 for (i = 0; i <= MAXPIN; i++) { 371 sc->isrcs[i].pin = i; 372 error = intr_isrc_register(&sc->isrcs[i].isrc, 373 dev, 0, "%s,%u", name, i); 374 if (error != 0) 375 goto fail; 376 } 377 378 xref = OF_xref_from_node(ofw_bus_get_node(dev)); 379 if (intr_pic_register(dev, xref) == NULL) { 380 error = ENXIO; 381 goto fail; 382 } 383 384 /* ACK and mask all interrupts. */ 385 WR4(sc, GPIO_GPIER, 0xffffffff); 386 WR4(sc, GPIO_GPIMR, 0); 387 388 return (0); 389 fail: 390 qoriq_gpio_pic_detach(dev); 391 return (error); 392 } 393 394 static int 395 qoriq_gpio_pic_detach(device_t dev) 396 { 397 struct qoriq_gpio_pic_softc *sc; 398 399 sc = device_get_softc(dev); 400 401 if (sc->irq_cookie != NULL) 402 bus_teardown_intr(dev, sc->res_irq, sc->irq_cookie); 403 404 if (sc->res_irq != NULL) 405 bus_release_resource(dev, SYS_RES_IRQ, 406 rman_get_rid(sc->res_irq), sc->res_irq); 407 408 return (qoriq_gpio_detach(dev)); 409 } 410 411 412 static device_method_t qoriq_gpio_pic_methods[] = { 413 DEVMETHOD(device_probe, qoriq_gpio_pic_probe), 414 DEVMETHOD(device_attach, qoriq_gpio_pic_attach), 415 DEVMETHOD(device_detach, qoriq_gpio_pic_detach), 416 417 DEVMETHOD(bus_setup_intr, bus_generic_setup_intr), 418 DEVMETHOD(bus_activate_resource, bus_generic_activate_resource), 419 DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), 420 421 DEVMETHOD(pic_disable_intr, qoriq_gpio_pic_disable_intr), 422 DEVMETHOD(pic_enable_intr, qoriq_gpio_pic_enable_intr), 423 DEVMETHOD(pic_map_intr, qoriq_gpio_pic_map_intr), 424 DEVMETHOD(pic_setup_intr, qoriq_gpio_pic_setup_intr), 425 DEVMETHOD(pic_teardown_intr, qoriq_gpio_pic_teardown_intr), 426 DEVMETHOD(pic_post_filter, qoriq_gpio_pic_post_filter), 427 DEVMETHOD(pic_post_ithread, qoriq_gpio_pic_post_ithread), 428 DEVMETHOD(pic_pre_ithread, qoriq_gpio_pic_pre_ithread), 429 430 DEVMETHOD_END 431 }; 432 433 static devclass_t qoriq_gpio_pic_devclass; 434 435 DEFINE_CLASS_1(gpio, qoriq_gpio_pic_driver, qoriq_gpio_pic_methods, 436 sizeof(struct qoriq_gpio_pic_softc), qoriq_gpio_driver); 437 EARLY_DRIVER_MODULE(qoriq_gpio_pic, simplebus, qoriq_gpio_pic_driver, 438 qoriq_gpio_pic_devclass, NULL, NULL, 439 BUS_PASS_INTERRUPT + BUS_PASS_ORDER_LATE); 440