1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright (c) 2004-2006 Marcel Moolenaar 5 * All rights reserved. 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 * 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 ``AS IS'' AND ANY EXPRESS OR 18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 #include <sys/cdefs.h> 30 #include <sys/param.h> 31 #include <sys/systm.h> 32 #include <sys/bus.h> 33 #include <sys/conf.h> 34 #include <sys/lock.h> 35 #include <sys/kernel.h> 36 #include <sys/malloc.h> 37 #include <sys/mutex.h> 38 #include <sys/queue.h> 39 #include <sys/serial.h> 40 41 #include <machine/bus.h> 42 #include <machine/resource.h> 43 #include <sys/rman.h> 44 45 #include <dev/scc/scc_bfe.h> 46 #include <dev/scc/scc_bus.h> 47 48 #include "scc_if.h" 49 50 const char scc_driver_name[] = "scc"; 51 52 static MALLOC_DEFINE(M_SCC, "SCC", "SCC driver"); 53 54 static int 55 scc_bfe_intr(void *arg) 56 { 57 struct scc_softc *sc = arg; 58 struct scc_chan *ch; 59 struct scc_class *cl; 60 struct scc_mode *m; 61 int c, i, ipend, isrc; 62 63 cl = sc->sc_class; 64 while (!sc->sc_leaving && (ipend = SCC_IPEND(sc)) != 0) { 65 i = 0, isrc = SER_INT_OVERRUN; 66 while (ipend) { 67 while (i < SCC_ISRCCNT && !(ipend & isrc)) 68 i++, isrc <<= 1; 69 KASSERT(i < SCC_ISRCCNT, ("%s", __func__)); 70 ipend &= ~isrc; 71 for (c = 0; c < cl->cl_channels; c++) { 72 ch = &sc->sc_chan[c]; 73 if (!(ch->ch_ipend & isrc)) 74 continue; 75 m = &ch->ch_mode[0]; 76 if (m->ih_src[i] == NULL) 77 continue; 78 if ((*m->ih_src[i])(m->ih_arg)) 79 ch->ch_ipend &= ~isrc; 80 } 81 } 82 for (c = 0; c < cl->cl_channels; c++) { 83 ch = &sc->sc_chan[c]; 84 if (!ch->ch_ipend) 85 continue; 86 m = &ch->ch_mode[0]; 87 if (m->ih != NULL) 88 (*m->ih)(m->ih_arg); 89 else 90 SCC_ICLEAR(sc, ch); 91 } 92 return (FILTER_HANDLED); 93 } 94 return (FILTER_STRAY); 95 } 96 97 int 98 scc_bfe_attach(device_t dev, u_int ipc) 99 { 100 struct resource_list_entry *rle; 101 struct scc_chan *ch; 102 struct scc_class *cl; 103 struct scc_mode *m; 104 struct scc_softc *sc, *sc0; 105 const char *sep; 106 bus_space_handle_t bh; 107 rman_res_t base, size, start, sz; 108 int c, error, mode, sysdev; 109 110 /* 111 * The sc_class field defines the type of SCC we're going to work 112 * with and thus the size of the softc. Replace the generic softc 113 * with one that matches the SCC now that we're certain we handle 114 * the device. 115 */ 116 sc0 = device_get_softc(dev); 117 cl = sc0->sc_class; 118 if (cl->size > sizeof(*sc)) { 119 sc = malloc(cl->size, M_SCC, M_WAITOK|M_ZERO); 120 bcopy(sc0, sc, sizeof(*sc)); 121 device_set_softc(dev, sc); 122 } else 123 sc = sc0; 124 125 size = abs(cl->cl_range) << sc->sc_bas.regshft; 126 127 mtx_init(&sc->sc_hwmtx, "scc_hwmtx", NULL, MTX_SPIN); 128 129 /* 130 * Re-allocate. We expect that the softc contains the information 131 * collected by scc_bfe_probe() intact. 132 */ 133 sc->sc_rres = bus_alloc_resource_anywhere(dev, sc->sc_rtype, 134 &sc->sc_rrid, cl->cl_channels * size, RF_ACTIVE); 135 if (sc->sc_rres == NULL) 136 return (ENXIO); 137 sc->sc_bas.bsh = rman_get_bushandle(sc->sc_rres); 138 sc->sc_bas.bst = rman_get_bustag(sc->sc_rres); 139 140 /* 141 * Allocate interrupt resources. There may be a different interrupt 142 * per channel. We allocate them all... 143 */ 144 sc->sc_chan = malloc(sizeof(struct scc_chan) * cl->cl_channels, 145 M_SCC, M_WAITOK | M_ZERO); 146 for (c = 0; c < cl->cl_channels; c++) { 147 ch = &sc->sc_chan[c]; 148 /* 149 * XXX temporary hack. If we have more than 1 interrupt 150 * per channel, allocate the first for the channel. At 151 * this time only the macio bus front-end has more than 152 * 1 interrupt per channel and we don't use the 2nd and 153 * 3rd, because we don't support DMA yet. 154 */ 155 ch->ch_irid = c * ipc; 156 ch->ch_ires = bus_alloc_resource_any(dev, SYS_RES_IRQ, 157 &ch->ch_irid, RF_ACTIVE | RF_SHAREABLE); 158 if (ipc == 0) 159 break; 160 } 161 162 /* 163 * Create the control structures for our children. Probe devices 164 * and query them to see if we can reset the hardware. 165 */ 166 sysdev = 0; 167 base = rman_get_start(sc->sc_rres); 168 sz = (size != 0) ? size : rman_get_size(sc->sc_rres); 169 start = base + ((cl->cl_range < 0) ? size * (cl->cl_channels - 1) : 0); 170 for (c = 0; c < cl->cl_channels; c++) { 171 ch = &sc->sc_chan[c]; 172 resource_list_init(&ch->ch_rlist); 173 ch->ch_nr = c + 1; 174 175 if (!SCC_ENABLED(sc, ch)) 176 goto next; 177 178 ch->ch_enabled = 1; 179 resource_list_add(&ch->ch_rlist, sc->sc_rtype, 0, start, 180 start + sz - 1, sz); 181 rle = resource_list_find(&ch->ch_rlist, sc->sc_rtype, 0); 182 rle->res = &ch->ch_rres; 183 bus_space_subregion(rman_get_bustag(sc->sc_rres), 184 rman_get_bushandle(sc->sc_rres), start - base, sz, &bh); 185 rman_set_bushandle(rle->res, bh); 186 rman_set_bustag(rle->res, rman_get_bustag(sc->sc_rres)); 187 188 resource_list_add(&ch->ch_rlist, SYS_RES_IRQ, 0, c, c, 1); 189 rle = resource_list_find(&ch->ch_rlist, SYS_RES_IRQ, 0); 190 rle->res = (ch->ch_ires != NULL) ? ch->ch_ires : 191 sc->sc_chan[0].ch_ires; 192 193 for (mode = 0; mode < SCC_NMODES; mode++) { 194 m = &ch->ch_mode[mode]; 195 m->m_chan = ch; 196 m->m_mode = 1U << mode; 197 if ((cl->cl_modes & m->m_mode) == 0 || ch->ch_sysdev) 198 continue; 199 m->m_dev = device_add_child(dev, NULL, -1); 200 device_set_ivars(m->m_dev, (void *)m); 201 error = device_probe_child(dev, m->m_dev); 202 if (!error) { 203 m->m_probed = 1; 204 m->m_sysdev = SERDEV_SYSDEV(m->m_dev) ? 1 : 0; 205 ch->ch_sysdev |= m->m_sysdev; 206 } 207 } 208 209 next: 210 start += (cl->cl_range < 0) ? -size : size; 211 sysdev |= ch->ch_sysdev; 212 } 213 214 /* 215 * Have the hardware driver initialize the hardware. Tell it 216 * whether or not a hardware reset should be performed. 217 */ 218 if (bootverbose) { 219 device_printf(dev, "%sresetting hardware\n", 220 (sysdev) ? "not " : ""); 221 } 222 error = SCC_ATTACH(sc, !sysdev); 223 if (error) 224 goto fail; 225 226 /* 227 * Setup our interrupt handler. Make it FAST under the assumption 228 * that our children's are fast as well. We make it MPSAFE as soon 229 * as a child sets up a MPSAFE interrupt handler. 230 * Of course, if we can't setup a fast handler, we make it MPSAFE 231 * right away. 232 */ 233 for (c = 0; c < cl->cl_channels; c++) { 234 ch = &sc->sc_chan[c]; 235 if (ch->ch_ires == NULL) 236 continue; 237 error = bus_setup_intr(dev, ch->ch_ires, 238 INTR_TYPE_TTY, scc_bfe_intr, NULL, sc, 239 &ch->ch_icookie); 240 if (error) { 241 error = bus_setup_intr(dev, ch->ch_ires, 242 INTR_TYPE_TTY | INTR_MPSAFE, NULL, 243 (driver_intr_t *)scc_bfe_intr, sc, &ch->ch_icookie); 244 } else 245 sc->sc_fastintr = 1; 246 247 if (error) { 248 device_printf(dev, "could not activate interrupt\n"); 249 bus_release_resource(dev, SYS_RES_IRQ, ch->ch_irid, 250 ch->ch_ires); 251 ch->ch_ires = NULL; 252 } 253 } 254 sc->sc_polled = 1; 255 for (c = 0; c < cl->cl_channels; c++) { 256 if (sc->sc_chan[0].ch_ires != NULL) 257 sc->sc_polled = 0; 258 } 259 260 /* 261 * Attach all child devices that were probed successfully. 262 */ 263 for (c = 0; c < cl->cl_channels; c++) { 264 ch = &sc->sc_chan[c]; 265 for (mode = 0; mode < SCC_NMODES; mode++) { 266 m = &ch->ch_mode[mode]; 267 if (!m->m_probed) 268 continue; 269 error = device_attach(m->m_dev); 270 if (error) 271 continue; 272 m->m_attached = 1; 273 } 274 } 275 276 if (bootverbose && (sc->sc_fastintr || sc->sc_polled)) { 277 sep = ""; 278 device_print_prettyname(dev); 279 if (sc->sc_fastintr) { 280 printf("%sfast interrupt", sep); 281 sep = ", "; 282 } 283 if (sc->sc_polled) { 284 printf("%spolled mode", sep); 285 sep = ", "; 286 } 287 printf("\n"); 288 } 289 290 return (0); 291 292 fail: 293 for (c = 0; c < cl->cl_channels; c++) { 294 ch = &sc->sc_chan[c]; 295 if (ch->ch_ires == NULL) 296 continue; 297 bus_release_resource(dev, SYS_RES_IRQ, ch->ch_irid, 298 ch->ch_ires); 299 } 300 bus_release_resource(dev, sc->sc_rtype, sc->sc_rrid, sc->sc_rres); 301 return (error); 302 } 303 304 int 305 scc_bfe_detach(device_t dev) 306 { 307 struct scc_chan *ch; 308 struct scc_class *cl; 309 struct scc_mode *m; 310 struct scc_softc *sc; 311 int chan, error, mode; 312 313 sc = device_get_softc(dev); 314 cl = sc->sc_class; 315 316 /* Detach our children. */ 317 error = 0; 318 for (chan = 0; chan < cl->cl_channels; chan++) { 319 ch = &sc->sc_chan[chan]; 320 for (mode = 0; mode < SCC_NMODES; mode++) { 321 m = &ch->ch_mode[mode]; 322 if (!m->m_attached) 323 continue; 324 if (device_detach(m->m_dev) != 0) 325 error = ENXIO; 326 else 327 m->m_attached = 0; 328 } 329 } 330 331 if (error) 332 return (error); 333 334 for (chan = 0; chan < cl->cl_channels; chan++) { 335 ch = &sc->sc_chan[chan]; 336 if (ch->ch_ires == NULL) 337 continue; 338 bus_teardown_intr(dev, ch->ch_ires, ch->ch_icookie); 339 bus_release_resource(dev, SYS_RES_IRQ, ch->ch_irid, 340 ch->ch_ires); 341 } 342 bus_release_resource(dev, sc->sc_rtype, sc->sc_rrid, sc->sc_rres); 343 344 free(sc->sc_chan, M_SCC); 345 346 mtx_destroy(&sc->sc_hwmtx); 347 return (0); 348 } 349 350 int 351 scc_bfe_probe(device_t dev, u_int regshft, u_int rclk, u_int rid) 352 { 353 struct scc_softc *sc; 354 struct scc_class *cl; 355 u_long size, sz; 356 int error; 357 358 /* 359 * Initialize the instance. Note that the instance (=softc) does 360 * not necessarily match the hardware specific softc. We can't do 361 * anything about it now, because we may not attach to the device. 362 * Hardware drivers cannot use any of the class specific fields 363 * while probing. 364 */ 365 sc = device_get_softc(dev); 366 cl = sc->sc_class; 367 kobj_init((kobj_t)sc, (kobj_class_t)cl); 368 sc->sc_dev = dev; 369 if (device_get_desc(dev) == NULL) 370 device_set_desc(dev, cl->name); 371 372 size = abs(cl->cl_range) << regshft; 373 374 /* 375 * Allocate the register resource. We assume that all SCCs have a 376 * single register window in either I/O port space or memory mapped 377 * I/O space. Any SCC that needs multiple windows will consequently 378 * not be supported by this driver as-is. 379 */ 380 sc->sc_rrid = rid; 381 sc->sc_rtype = SYS_RES_MEMORY; 382 sc->sc_rres = bus_alloc_resource_anywhere(dev, sc->sc_rtype, 383 &sc->sc_rrid, cl->cl_channels * size, RF_ACTIVE); 384 if (sc->sc_rres == NULL) { 385 sc->sc_rrid = rid; 386 sc->sc_rtype = SYS_RES_IOPORT; 387 sc->sc_rres = bus_alloc_resource_anywhere(dev, sc->sc_rtype, 388 &sc->sc_rrid, cl->cl_channels * size, RF_ACTIVE); 389 if (sc->sc_rres == NULL) 390 return (ENXIO); 391 } 392 393 /* 394 * Fill in the bus access structure and call the hardware specific 395 * probe method. 396 */ 397 sz = (size != 0) ? size : rman_get_size(sc->sc_rres); 398 sc->sc_bas.bsh = rman_get_bushandle(sc->sc_rres); 399 sc->sc_bas.bst = rman_get_bustag(sc->sc_rres); 400 sc->sc_bas.range = sz; 401 sc->sc_bas.rclk = rclk; 402 sc->sc_bas.regshft = regshft; 403 404 error = SCC_PROBE(sc); 405 bus_release_resource(dev, sc->sc_rtype, sc->sc_rrid, sc->sc_rres); 406 return ((error == 0) ? BUS_PROBE_DEFAULT : error); 407 } 408 409 struct resource * 410 scc_bus_alloc_resource(device_t dev, device_t child, int type, int *rid, 411 rman_res_t start, rman_res_t end, rman_res_t count, u_int flags) 412 { 413 struct resource_list_entry *rle; 414 struct scc_chan *ch; 415 struct scc_mode *m; 416 417 if (device_get_parent(child) != dev) 418 return (NULL); 419 420 /* We only support default allocations. */ 421 if (!RMAN_IS_DEFAULT_RANGE(start, end)) 422 return (NULL); 423 424 m = device_get_ivars(child); 425 ch = m->m_chan; 426 rle = resource_list_find(&ch->ch_rlist, type, 0); 427 if (rle == NULL) 428 return (NULL); 429 *rid = 0; 430 return (rle->res); 431 } 432 433 int 434 scc_bus_get_resource(device_t dev, device_t child, int type, int rid, 435 rman_res_t *startp, rman_res_t *countp) 436 { 437 struct resource_list_entry *rle; 438 struct scc_chan *ch; 439 struct scc_mode *m; 440 441 if (device_get_parent(child) != dev) 442 return (EINVAL); 443 444 m = device_get_ivars(child); 445 ch = m->m_chan; 446 rle = resource_list_find(&ch->ch_rlist, type, rid); 447 if (rle == NULL) 448 return (EINVAL); 449 450 if (startp != NULL) 451 *startp = rle->start; 452 if (countp != NULL) 453 *countp = rle->count; 454 return (0); 455 } 456 457 int 458 scc_bus_read_ivar(device_t dev, device_t child, int index, uintptr_t *result) 459 { 460 struct scc_chan *ch; 461 struct scc_class *cl; 462 struct scc_mode *m; 463 struct scc_softc *sc; 464 465 if (device_get_parent(child) != dev) 466 return (EINVAL); 467 468 sc = device_get_softc(dev); 469 cl = sc->sc_class; 470 m = device_get_ivars(child); 471 ch = m->m_chan; 472 473 switch (index) { 474 case SCC_IVAR_CHANNEL: 475 *result = ch->ch_nr; 476 break; 477 case SCC_IVAR_CLASS: 478 *result = cl->cl_class; 479 break; 480 case SCC_IVAR_CLOCK: 481 *result = sc->sc_bas.rclk; 482 break; 483 case SCC_IVAR_MODE: 484 *result = m->m_mode; 485 break; 486 case SCC_IVAR_REGSHFT: 487 *result = sc->sc_bas.regshft; 488 break; 489 case SCC_IVAR_HWMTX: 490 *result = (uintptr_t)&sc->sc_hwmtx; 491 break; 492 default: 493 return (EINVAL); 494 } 495 return (0); 496 } 497 498 int 499 scc_bus_release_resource(device_t dev, device_t child, int type, int rid, 500 struct resource *res) 501 { 502 struct resource_list_entry *rle; 503 struct scc_chan *ch; 504 struct scc_mode *m; 505 506 if (device_get_parent(child) != dev) 507 return (EINVAL); 508 509 m = device_get_ivars(child); 510 ch = m->m_chan; 511 rle = resource_list_find(&ch->ch_rlist, type, rid); 512 return ((rle == NULL) ? EINVAL : 0); 513 } 514 515 int 516 scc_bus_setup_intr(device_t dev, device_t child, struct resource *r, int flags, 517 driver_filter_t *filt, void (*ihand)(void *), void *arg, void **cookiep) 518 { 519 struct scc_chan *ch; 520 struct scc_mode *m; 521 struct scc_softc *sc; 522 int c, i, isrc; 523 524 if (device_get_parent(child) != dev) 525 return (EINVAL); 526 527 /* Interrupt handlers must be FAST or MPSAFE. */ 528 if (filt == NULL && !(flags & INTR_MPSAFE)) 529 return (EINVAL); 530 531 sc = device_get_softc(dev); 532 if (sc->sc_polled) 533 return (ENXIO); 534 535 if (sc->sc_fastintr && filt == NULL) { 536 sc->sc_fastintr = 0; 537 for (c = 0; c < sc->sc_class->cl_channels; c++) { 538 ch = &sc->sc_chan[c]; 539 if (ch->ch_ires == NULL) 540 continue; 541 bus_teardown_intr(dev, ch->ch_ires, ch->ch_icookie); 542 bus_setup_intr(dev, ch->ch_ires, 543 INTR_TYPE_TTY | INTR_MPSAFE, NULL, 544 (driver_intr_t *)scc_bfe_intr, sc, &ch->ch_icookie); 545 } 546 } 547 548 m = device_get_ivars(child); 549 m->m_hasintr = 1; 550 m->m_fastintr = (filt != NULL) ? 1 : 0; 551 m->ih = (filt != NULL) ? filt : (driver_filter_t *)ihand; 552 m->ih_arg = arg; 553 554 i = 0, isrc = SER_INT_OVERRUN; 555 while (i < SCC_ISRCCNT) { 556 m->ih_src[i] = SERDEV_IHAND(child, isrc); 557 if (m->ih_src[i] != NULL) 558 m->ih = NULL; 559 i++, isrc <<= 1; 560 } 561 return (0); 562 } 563 564 int 565 scc_bus_teardown_intr(device_t dev, device_t child, struct resource *r, 566 void *cookie) 567 { 568 struct scc_mode *m; 569 int i; 570 571 if (device_get_parent(child) != dev) 572 return (EINVAL); 573 574 m = device_get_ivars(child); 575 if (!m->m_hasintr) 576 return (EINVAL); 577 578 m->m_hasintr = 0; 579 m->m_fastintr = 0; 580 m->ih = NULL; 581 m->ih_arg = NULL; 582 for (i = 0; i < SCC_ISRCCNT; i++) 583 m->ih_src[i] = NULL; 584 return (0); 585 } 586