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