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