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