1139749Simp/*- 2119815Smarcel * Copyright (c) 2003 Marcel Moolenaar 3119815Smarcel * All rights reserved. 4119815Smarcel * 5119815Smarcel * Redistribution and use in source and binary forms, with or without 6119815Smarcel * modification, are permitted provided that the following conditions 7119815Smarcel * are met: 8119815Smarcel * 9119815Smarcel * 1. Redistributions of source code must retain the above copyright 10119815Smarcel * notice, this list of conditions and the following disclaimer. 11119815Smarcel * 2. Redistributions in binary form must reproduce the above copyright 12119815Smarcel * notice, this list of conditions and the following disclaimer in the 13119815Smarcel * documentation and/or other materials provided with the distribution. 14119815Smarcel * 15119815Smarcel * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16119815Smarcel * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17119815Smarcel * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18119815Smarcel * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19119815Smarcel * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20119815Smarcel * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21119815Smarcel * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22119815Smarcel * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23119815Smarcel * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24119815Smarcel * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25119815Smarcel */ 26119815Smarcel 27119815Smarcel#include <sys/cdefs.h> 28119815Smarcel__FBSDID("$FreeBSD: stable/11/sys/dev/uart/uart_core.c 365480 2020-09-08 22:50:24Z jhb $"); 29119815Smarcel 30119815Smarcel#include <sys/param.h> 31119815Smarcel#include <sys/systm.h> 32119815Smarcel#include <sys/bus.h> 33119815Smarcel#include <sys/conf.h> 34119815Smarcel#include <sys/cons.h> 35119815Smarcel#include <sys/fcntl.h> 36119815Smarcel#include <sys/interrupt.h> 37131921Smarcel#include <sys/kdb.h> 38119815Smarcel#include <sys/kernel.h> 39119815Smarcel#include <sys/malloc.h> 40119815Smarcel#include <sys/queue.h> 41119815Smarcel#include <sys/reboot.h> 42285619Sneel#include <sys/sysctl.h> 43119815Smarcel#include <machine/bus.h> 44119815Smarcel#include <sys/rman.h> 45119815Smarcel#include <machine/resource.h> 46119815Smarcel#include <machine/stdarg.h> 47119815Smarcel 48119815Smarcel#include <dev/uart/uart.h> 49119815Smarcel#include <dev/uart/uart_bus.h> 50119815Smarcel#include <dev/uart/uart_cpu.h> 51293781Sian#include <dev/uart/uart_ppstypes.h> 52119815Smarcel 53119815Smarcel#include "uart_if.h" 54119815Smarcel 55119815Smarceldevclass_t uart_devclass; 56285843Smariusconst char uart_driver_name[] = "uart"; 57119815Smarcel 58119815SmarcelSLIST_HEAD(uart_devinfo_list, uart_devinfo) uart_sysdevs = 59119815Smarcel SLIST_HEAD_INITIALIZER(uart_sysdevs); 60119815Smarcel 61227293Sedstatic MALLOC_DEFINE(M_UART, "UART", "UART driver"); 62119815Smarcel 63234194Sgrehan#ifndef UART_POLL_FREQ 64234194Sgrehan#define UART_POLL_FREQ 50 65234194Sgrehan#endif 66234194Sgrehanstatic int uart_poll_freq = UART_POLL_FREQ; 67285619SneelSYSCTL_INT(_debug, OID_AUTO, uart_poll_freq, CTLFLAG_RDTUN, &uart_poll_freq, 68285619Sneel 0, "UART poll frequency"); 69234194Sgrehan 70285619Sneelstatic int uart_force_poll; 71285619SneelSYSCTL_INT(_debug, OID_AUTO, uart_force_poll, CTLFLAG_RDTUN, &uart_force_poll, 72285619Sneel 0, "Force UART polling"); 73285619Sneel 74286591Sianstatic inline int 75293781Sianuart_pps_mode_valid(int pps_mode) 76286591Sian{ 77293781Sian int opt; 78286591Sian 79293781Sian switch(pps_mode & UART_PPS_SIGNAL_MASK) { 80293781Sian case UART_PPS_DISABLED: 81293781Sian case UART_PPS_CTS: 82293781Sian case UART_PPS_DCD: 83293781Sian break; 84293781Sian default: 85293781Sian return (false); 86286591Sian } 87286591Sian 88293781Sian opt = pps_mode & UART_PPS_OPTION_MASK; 89293781Sian if ((opt & ~(UART_PPS_INVERT_PULSE | UART_PPS_NARROW_PULSE)) != 0) 90293781Sian return (false); 91293781Sian 92293781Sian return (true); 93286591Sian} 94286591Sian 95293781Sianstatic void 96293781Sianuart_pps_print_mode(struct uart_softc *sc) 97286591Sian{ 98293781Sian 99293781Sian device_printf(sc->sc_dev, "PPS capture mode: "); 100293781Sian switch(sc->sc_pps_mode) { 101293781Sian case UART_PPS_DISABLED: 102293781Sian printf("disabled"); 103293781Sian case UART_PPS_CTS: 104293781Sian printf("CTS"); 105293781Sian case UART_PPS_DCD: 106293781Sian printf("DCD"); 107293781Sian default: 108293781Sian printf("invalid"); 109286591Sian } 110293781Sian if (sc->sc_pps_mode & UART_PPS_INVERT_PULSE) 111293781Sian printf("-Inverted"); 112293781Sian if (sc->sc_pps_mode & UART_PPS_NARROW_PULSE) 113293781Sian printf("-NarrowPulse"); 114293781Sian printf("\n"); 115286591Sian} 116286591Sian 117286591Sianstatic int 118286591Sianuart_pps_mode_sysctl(SYSCTL_HANDLER_ARGS) 119286591Sian{ 120286591Sian struct uart_softc *sc; 121286591Sian int err, tmp; 122286591Sian 123286591Sian sc = arg1; 124286591Sian tmp = sc->sc_pps_mode; 125286591Sian err = sysctl_handle_int(oidp, &tmp, 0, req); 126286591Sian if (err != 0 || req->newptr == NULL) 127286591Sian return (err); 128286591Sian if (!uart_pps_mode_valid(tmp)) 129286591Sian return (EINVAL); 130286591Sian sc->sc_pps_mode = tmp; 131286591Sian return(0); 132286591Sian} 133286591Sian 134286591Sianstatic void 135293781Sianuart_pps_process(struct uart_softc *sc, int ser_sig) 136293781Sian{ 137293781Sian sbintime_t now; 138293781Sian int is_assert, pps_sig; 139293781Sian 140293781Sian /* Which signal is configured as PPS? Early out if none. */ 141293781Sian switch(sc->sc_pps_mode & UART_PPS_SIGNAL_MASK) { 142293781Sian case UART_PPS_CTS: 143293781Sian pps_sig = SER_CTS; 144293781Sian break; 145293781Sian case UART_PPS_DCD: 146293781Sian pps_sig = SER_DCD; 147293781Sian break; 148293781Sian default: 149293781Sian return; 150293781Sian } 151293781Sian 152293781Sian /* Early out if there is no change in the signal configured as PPS. */ 153293781Sian if ((ser_sig & SER_DELTA(pps_sig)) == 0) 154293781Sian return; 155293781Sian 156293781Sian /* 157293781Sian * In narrow-pulse mode we need to synthesize both capture and clear 158293781Sian * events from a single "delta occurred" indication from the uart 159293781Sian * hardware because the pulse width is too narrow to reliably detect 160293781Sian * both edges. However, when the pulse width is close to our interrupt 161293781Sian * processing latency we might intermittantly catch both edges. To 162293781Sian * guard against generating spurious events when that happens, we use a 163293781Sian * separate timer to ensure at least half a second elapses before we 164293781Sian * generate another event. 165293781Sian */ 166293781Sian pps_capture(&sc->sc_pps); 167293781Sian if (sc->sc_pps_mode & UART_PPS_NARROW_PULSE) { 168293781Sian now = getsbinuptime(); 169293781Sian if (now > sc->sc_pps_captime + 500 * SBT_1MS) { 170293781Sian sc->sc_pps_captime = now; 171293781Sian pps_event(&sc->sc_pps, PPS_CAPTUREASSERT); 172293781Sian pps_event(&sc->sc_pps, PPS_CAPTURECLEAR); 173293781Sian } 174293781Sian } else { 175293781Sian is_assert = ser_sig & pps_sig; 176293781Sian if (sc->sc_pps_mode & UART_PPS_INVERT_PULSE) 177293781Sian is_assert = !is_assert; 178293781Sian pps_event(&sc->sc_pps, is_assert ? PPS_CAPTUREASSERT : 179293781Sian PPS_CAPTURECLEAR); 180293781Sian } 181293781Sian} 182293781Sian 183293781Sianstatic void 184286591Sianuart_pps_init(struct uart_softc *sc) 185286591Sian{ 186286591Sian struct sysctl_ctx_list *ctx; 187286591Sian struct sysctl_oid *tree; 188286591Sian 189286591Sian ctx = device_get_sysctl_ctx(sc->sc_dev); 190286591Sian tree = device_get_sysctl_tree(sc->sc_dev); 191286591Sian 192286591Sian /* 193286591Sian * The historical default for pps capture mode is either DCD or CTS, 194286591Sian * depending on the UART_PPS_ON_CTS kernel option. Start with that, 195286591Sian * then try to fetch the tunable that overrides the mode for all uart 196286591Sian * devices, then try to fetch the sysctl-tunable that overrides the mode 197286591Sian * for one specific device. 198286591Sian */ 199286591Sian#ifdef UART_PPS_ON_CTS 200293781Sian sc->sc_pps_mode = UART_PPS_CTS; 201286591Sian#else 202293781Sian sc->sc_pps_mode = UART_PPS_DCD; 203286591Sian#endif 204286591Sian TUNABLE_INT_FETCH("hw.uart.pps_mode", &sc->sc_pps_mode); 205286591Sian SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, "pps_mode", 206286591Sian CTLTYPE_INT | CTLFLAG_RWTUN, sc, 0, uart_pps_mode_sysctl, "I", 207293781Sian "pulse mode: 0/1/2=disabled/CTS/DCD; " 208293781Sian "add 0x10 to invert, 0x20 for narrow pulse"); 209286591Sian 210286591Sian if (!uart_pps_mode_valid(sc->sc_pps_mode)) { 211286591Sian device_printf(sc->sc_dev, 212293781Sian "Invalid pps_mode 0x%02x configured; disabling PPS capture\n", 213286591Sian sc->sc_pps_mode); 214293781Sian sc->sc_pps_mode = UART_PPS_DISABLED; 215286591Sian } else if (bootverbose) { 216293781Sian uart_pps_print_mode(sc); 217286591Sian } 218286591Sian 219286591Sian sc->sc_pps.ppscap = PPS_CAPTUREBOTH; 220286591Sian sc->sc_pps.driver_mtx = uart_tty_getlock(sc); 221286591Sian sc->sc_pps.driver_abi = PPS_ABI_VERSION; 222286591Sian pps_init_abi(&sc->sc_pps); 223286591Sian} 224286591Sian 225119815Smarcelvoid 226119815Smarceluart_add_sysdev(struct uart_devinfo *di) 227119815Smarcel{ 228119815Smarcel SLIST_INSERT_HEAD(&uart_sysdevs, di, next); 229119815Smarcel} 230119815Smarcel 231168281Smarcelconst char * 232168281Smarceluart_getname(struct uart_class *uc) 233168281Smarcel{ 234168281Smarcel return ((uc != NULL) ? uc->name : NULL); 235168281Smarcel} 236168281Smarcel 237168281Smarcelstruct uart_ops * 238168281Smarceluart_getops(struct uart_class *uc) 239168281Smarcel{ 240168281Smarcel return ((uc != NULL) ? uc->uc_ops : NULL); 241168281Smarcel} 242168281Smarcel 243168281Smarcelint 244168281Smarceluart_getrange(struct uart_class *uc) 245168281Smarcel{ 246168281Smarcel return ((uc != NULL) ? uc->uc_range : 0); 247168281Smarcel} 248168281Smarcel 249281438Sandrewu_int 250281438Sandrewuart_getregshift(struct uart_class *uc) 251281438Sandrew{ 252281438Sandrew return ((uc != NULL) ? uc->uc_rshift : 0); 253281438Sandrew} 254281438Sandrew 255340145Smmacyu_int 256340145Smmacyuart_getregiowidth(struct uart_class *uc) 257340145Smmacy{ 258340145Smmacy return ((uc != NULL) ? uc->uc_riowidth : 0); 259340145Smmacy} 260340145Smmacy 261119815Smarcel/* 262157300Smarcel * Schedule a soft interrupt. We do this on the 0 to !0 transition 263157300Smarcel * of the TTY pending interrupt status. 264157300Smarcel */ 265197721Smarcelvoid 266157300Smarceluart_sched_softih(struct uart_softc *sc, uint32_t ipend) 267157300Smarcel{ 268157300Smarcel uint32_t new, old; 269157300Smarcel 270157300Smarcel do { 271157300Smarcel old = sc->sc_ttypend; 272157300Smarcel new = old | ipend; 273157300Smarcel } while (!atomic_cmpset_32(&sc->sc_ttypend, old, new)); 274157300Smarcel 275157300Smarcel if ((old & SER_INT_MASK) == 0) 276157300Smarcel swi_sched(sc->sc_softih, 0); 277157300Smarcel} 278157300Smarcel 279157300Smarcel/* 280119815Smarcel * A break condition has been detected. We treat the break condition as 281119815Smarcel * a special case that should not happen during normal operation. When 282119815Smarcel * the break condition is to be passed to higher levels in the form of 283119815Smarcel * a NUL character, we really want the break to be in the right place in 284119815Smarcel * the input stream. The overhead to achieve that is not in relation to 285119815Smarcel * the exceptional nature of the break condition, so we permit ourselves 286119815Smarcel * to be sloppy. 287119815Smarcel */ 288157300Smarcelstatic __inline int 289157300Smarceluart_intr_break(void *arg) 290119815Smarcel{ 291157300Smarcel struct uart_softc *sc = arg; 292119815Smarcel 293225203Srwatson#if defined(KDB) 294119815Smarcel if (sc->sc_sysdev != NULL && sc->sc_sysdev->type == UART_DEV_CONSOLE) { 295225203Srwatson if (kdb_break()) 296225203Srwatson return (0); 297119815Smarcel } 298119815Smarcel#endif 299119815Smarcel if (sc->sc_opened) 300157300Smarcel uart_sched_softih(sc, SER_INT_BREAK); 301157300Smarcel return (0); 302119815Smarcel} 303119815Smarcel 304119815Smarcel/* 305119815Smarcel * Handle a receiver overrun situation. We lost at least 1 byte in the 306119815Smarcel * input stream and it's our job to contain the situation. We grab as 307119815Smarcel * much of the data we can, but otherwise flush the receiver FIFO to 308119815Smarcel * create some breathing room. The net effect is that we avoid the 309119815Smarcel * overrun condition to happen for the next X characters, where X is 310250576Seadler * related to the FIFO size at the cost of losing data right away. 311119815Smarcel * So, instead of having multiple overrun interrupts in close proximity 312119815Smarcel * to each other and possibly pessimizing UART interrupt latency for 313119815Smarcel * other UARTs in a multiport configuration, we create a longer segment 314119815Smarcel * of missing characters by freeing up the FIFO. 315119815Smarcel * Each overrun condition is marked in the input buffer by a token. The 316119815Smarcel * token represents the loss of at least one, but possible more bytes in 317119815Smarcel * the input stream. 318119815Smarcel */ 319157300Smarcelstatic __inline int 320157300Smarceluart_intr_overrun(void *arg) 321119815Smarcel{ 322157300Smarcel struct uart_softc *sc = arg; 323119815Smarcel 324119815Smarcel if (sc->sc_opened) { 325119815Smarcel UART_RECEIVE(sc); 326119815Smarcel if (uart_rx_put(sc, UART_STAT_OVERRUN)) 327119815Smarcel sc->sc_rxbuf[sc->sc_rxput] = UART_STAT_OVERRUN; 328157300Smarcel uart_sched_softih(sc, SER_INT_RXREADY); 329119815Smarcel } 330365480Sjhb sc->sc_rxoverruns++; 331119815Smarcel UART_FLUSH(sc, UART_FLUSH_RECEIVER); 332157300Smarcel return (0); 333119815Smarcel} 334119815Smarcel 335119815Smarcel/* 336119815Smarcel * Received data ready. 337119815Smarcel */ 338157300Smarcelstatic __inline int 339157300Smarceluart_intr_rxready(void *arg) 340119815Smarcel{ 341157300Smarcel struct uart_softc *sc = arg; 342119815Smarcel int rxp; 343119815Smarcel 344119815Smarcel rxp = sc->sc_rxput; 345119815Smarcel UART_RECEIVE(sc); 346225203Srwatson#if defined(KDB) 347119815Smarcel if (sc->sc_sysdev != NULL && sc->sc_sysdev->type == UART_DEV_CONSOLE) { 348119815Smarcel while (rxp != sc->sc_rxput) { 349225203Srwatson kdb_alt_break(sc->sc_rxbuf[rxp++], &sc->sc_altbrk); 350119815Smarcel if (rxp == sc->sc_rxbufsz) 351119815Smarcel rxp = 0; 352119815Smarcel } 353119815Smarcel } 354119815Smarcel#endif 355119815Smarcel if (sc->sc_opened) 356157300Smarcel uart_sched_softih(sc, SER_INT_RXREADY); 357119815Smarcel else 358119815Smarcel sc->sc_rxput = sc->sc_rxget; /* Ignore received data. */ 359157300Smarcel return (1); 360119815Smarcel} 361119815Smarcel 362119815Smarcel/* 363119815Smarcel * Line or modem status change (OOB signalling). 364119815Smarcel * We pass the signals to the software interrupt handler for further 365119815Smarcel * processing. Note that we merge the delta bits, but set the state 366250576Seadler * bits. This is to avoid losing state transitions due to having more 367119815Smarcel * than 1 hardware interrupt between software interrupts. 368119815Smarcel */ 369157300Smarcelstatic __inline int 370157300Smarceluart_intr_sigchg(void *arg) 371119815Smarcel{ 372157300Smarcel struct uart_softc *sc = arg; 373293781Sian int new, old, sig; 374119815Smarcel 375119815Smarcel sig = UART_GETSIG(sc); 376119996Smarcel 377286595Sian /* 378293781Sian * Time pulse counting support, invoked whenever the PPS parameters are 379293781Sian * currently set to capture either edge of the signal. 380286595Sian */ 381119996Smarcel if (sc->sc_pps.ppsparam.mode & PPS_CAPTUREBOTH) { 382293781Sian uart_pps_process(sc, sig); 383119996Smarcel } 384119996Smarcel 385157300Smarcel /* 386157300Smarcel * Keep track of signal changes, even when the device is not 387157300Smarcel * opened. This allows us to inform upper layers about a 388157300Smarcel * possible loss of DCD and thus the existence of a (possibly) 389157300Smarcel * different connection when we have DCD back, during the time 390157300Smarcel * that the device was closed. 391157300Smarcel */ 392119815Smarcel do { 393119815Smarcel old = sc->sc_ttypend; 394155973Smarcel new = old & ~SER_MASK_STATE; 395155971Smarcel new |= sig & SER_INT_SIGMASK; 396119815Smarcel } while (!atomic_cmpset_32(&sc->sc_ttypend, old, new)); 397157300Smarcel 398157300Smarcel if (sc->sc_opened) 399157300Smarcel uart_sched_softih(sc, SER_INT_SIGCHG); 400157300Smarcel return (1); 401119815Smarcel} 402119815Smarcel 403119815Smarcel/* 404119815Smarcel * The transmitter can accept more data. 405119815Smarcel */ 406157300Smarcelstatic __inline int 407157300Smarceluart_intr_txidle(void *arg) 408119815Smarcel{ 409157300Smarcel struct uart_softc *sc = arg; 410157300Smarcel 411119815Smarcel if (sc->sc_txbusy) { 412119815Smarcel sc->sc_txbusy = 0; 413157300Smarcel uart_sched_softih(sc, SER_INT_TXIDLE); 414119815Smarcel } 415157300Smarcel return (0); 416119815Smarcel} 417119815Smarcel 418166901Spisostatic int 419119815Smarceluart_intr(void *arg) 420119815Smarcel{ 421119815Smarcel struct uart_softc *sc = arg; 422285843Smarius int cnt, ipend, testintr; 423119815Smarcel 424253161Smarcel if (sc->sc_leaving) 425253161Smarcel return (FILTER_STRAY); 426253161Smarcel 427253161Smarcel cnt = 0; 428285843Smarius testintr = sc->sc_testintr; 429285843Smarius while ((!testintr || cnt < 20) && (ipend = UART_IPEND(sc)) != 0) { 430253161Smarcel cnt++; 431155971Smarcel if (ipend & SER_INT_OVERRUN) 432120146Smarcel uart_intr_overrun(sc); 433155971Smarcel if (ipend & SER_INT_BREAK) 434120146Smarcel uart_intr_break(sc); 435155971Smarcel if (ipend & SER_INT_RXREADY) 436120146Smarcel uart_intr_rxready(sc); 437155971Smarcel if (ipend & SER_INT_SIGCHG) 438120146Smarcel uart_intr_sigchg(sc); 439155971Smarcel if (ipend & SER_INT_TXIDLE) 440285843Smarius uart_intr_txidle(sc); 441157300Smarcel } 442234194Sgrehan 443234194Sgrehan if (sc->sc_polled) { 444234194Sgrehan callout_reset(&sc->sc_timer, hz / uart_poll_freq, 445234194Sgrehan (timeout_t *)uart_intr, sc); 446234194Sgrehan } 447234194Sgrehan 448253161Smarcel return ((cnt == 0) ? FILTER_STRAY : 449285843Smarius ((testintr && cnt == 20) ? FILTER_SCHEDULE_THREAD : 450285843Smarius FILTER_HANDLED)); 451157300Smarcel} 452119815Smarcel 453157300Smarcelserdev_intr_t * 454157300Smarceluart_bus_ihand(device_t dev, int ipend) 455157300Smarcel{ 456157300Smarcel 457157300Smarcel switch (ipend) { 458157300Smarcel case SER_INT_BREAK: 459157300Smarcel return (uart_intr_break); 460157300Smarcel case SER_INT_OVERRUN: 461157300Smarcel return (uart_intr_overrun); 462157300Smarcel case SER_INT_RXREADY: 463157300Smarcel return (uart_intr_rxready); 464157300Smarcel case SER_INT_SIGCHG: 465157300Smarcel return (uart_intr_sigchg); 466157300Smarcel case SER_INT_TXIDLE: 467157300Smarcel return (uart_intr_txidle); 468157300Smarcel } 469157300Smarcel return (NULL); 470119815Smarcel} 471119815Smarcel 472119815Smarcelint 473158119Smarceluart_bus_ipend(device_t dev) 474158119Smarcel{ 475158119Smarcel struct uart_softc *sc; 476158119Smarcel 477158119Smarcel sc = device_get_softc(dev); 478158119Smarcel return (UART_IPEND(sc)); 479158119Smarcel} 480158119Smarcel 481158119Smarcelint 482157300Smarceluart_bus_sysdev(device_t dev) 483157300Smarcel{ 484157300Smarcel struct uart_softc *sc; 485157300Smarcel 486157300Smarcel sc = device_get_softc(dev); 487157300Smarcel return ((sc->sc_sysdev != NULL) ? 1 : 0); 488157300Smarcel} 489157300Smarcel 490157300Smarcelint 491340145Smmacyuart_bus_probe(device_t dev, int regshft, int regiowidth, int rclk, int rid, int chan, int quirks) 492119815Smarcel{ 493119815Smarcel struct uart_softc *sc; 494119815Smarcel struct uart_devinfo *sysdev; 495119815Smarcel int error; 496119815Smarcel 497168281Smarcel sc = device_get_softc(dev); 498168281Smarcel 499119815Smarcel /* 500168281Smarcel * All uart_class references are weak. Check that the needed 501168281Smarcel * class has been compiled-in. Fail if not. 502168281Smarcel */ 503168281Smarcel if (sc->sc_class == NULL) 504168281Smarcel return (ENXIO); 505168281Smarcel 506168281Smarcel /* 507119815Smarcel * Initialize the instance. Note that the instance (=softc) does 508119815Smarcel * not necessarily match the hardware specific softc. We can't do 509119815Smarcel * anything about it now, because we may not attach to the device. 510119815Smarcel * Hardware drivers cannot use any of the class specific fields 511119815Smarcel * while probing. 512119815Smarcel */ 513119815Smarcel kobj_init((kobj_t)sc, (kobj_class_t)sc->sc_class); 514119815Smarcel sc->sc_dev = dev; 515119815Smarcel if (device_get_desc(dev) == NULL) 516168281Smarcel device_set_desc(dev, uart_getname(sc->sc_class)); 517119815Smarcel 518119815Smarcel /* 519119815Smarcel * Allocate the register resource. We assume that all UARTs have 520119815Smarcel * a single register window in either I/O port space or memory 521119815Smarcel * mapped I/O space. Any UART that needs multiple windows will 522119815Smarcel * consequently not be supported by this driver as-is. We try I/O 523119815Smarcel * port space first because that's the common case. 524119815Smarcel */ 525119815Smarcel sc->sc_rrid = rid; 526119815Smarcel sc->sc_rtype = SYS_RES_IOPORT; 527286653Smarcel sc->sc_rres = bus_alloc_resource_any(dev, sc->sc_rtype, &sc->sc_rrid, 528286653Smarcel RF_ACTIVE); 529119815Smarcel if (sc->sc_rres == NULL) { 530119815Smarcel sc->sc_rrid = rid; 531119815Smarcel sc->sc_rtype = SYS_RES_MEMORY; 532286653Smarcel sc->sc_rres = bus_alloc_resource_any(dev, sc->sc_rtype, 533286653Smarcel &sc->sc_rrid, RF_ACTIVE); 534119815Smarcel if (sc->sc_rres == NULL) 535119815Smarcel return (ENXIO); 536119815Smarcel } 537119815Smarcel 538119815Smarcel /* 539119815Smarcel * Fill in the bus access structure and compare this device with 540119815Smarcel * a possible console device and/or a debug port. We set the flags 541119815Smarcel * in the softc so that the hardware dependent probe can adjust 542119815Smarcel * accordingly. In general, you don't want to permanently disrupt 543119815Smarcel * console I/O. 544119815Smarcel */ 545119815Smarcel sc->sc_bas.bsh = rman_get_bushandle(sc->sc_rres); 546119815Smarcel sc->sc_bas.bst = rman_get_bustag(sc->sc_rres); 547120452Smarcel sc->sc_bas.chan = chan; 548119815Smarcel sc->sc_bas.regshft = regshft; 549340145Smmacy sc->sc_bas.regiowidth = regiowidth; 550119815Smarcel sc->sc_bas.rclk = (rclk == 0) ? sc->sc_class->uc_rclk : rclk; 551340145Smmacy sc->sc_bas.busy_detect = !!(quirks & UART_F_BUSY_DETECT); 552119815Smarcel 553119815Smarcel SLIST_FOREACH(sysdev, &uart_sysdevs, next) { 554120452Smarcel if (chan == sysdev->bas.chan && 555120452Smarcel uart_cpu_eqres(&sc->sc_bas, &sysdev->bas)) { 556119815Smarcel /* XXX check if ops matches class. */ 557119815Smarcel sc->sc_sysdev = sysdev; 558167999Smarcel sysdev->bas.rclk = sc->sc_bas.rclk; 559119815Smarcel } 560119815Smarcel } 561119815Smarcel 562119815Smarcel error = UART_PROBE(sc); 563119815Smarcel bus_release_resource(dev, sc->sc_rtype, sc->sc_rrid, sc->sc_rres); 564151792Smarcel return ((error) ? error : BUS_PROBE_DEFAULT); 565119815Smarcel} 566119815Smarcel 567119815Smarcelint 568119815Smarceluart_bus_attach(device_t dev) 569119815Smarcel{ 570119815Smarcel struct uart_softc *sc, *sc0; 571119815Smarcel const char *sep; 572253161Smarcel int error, filt; 573119815Smarcel 574119815Smarcel /* 575119815Smarcel * The sc_class field defines the type of UART we're going to work 576119815Smarcel * with and thus the size of the softc. Replace the generic softc 577119815Smarcel * with one that matches the UART now that we're certain we handle 578119815Smarcel * the device. 579119815Smarcel */ 580119815Smarcel sc0 = device_get_softc(dev); 581119815Smarcel if (sc0->sc_class->size > sizeof(*sc)) { 582119815Smarcel sc = malloc(sc0->sc_class->size, M_UART, M_WAITOK|M_ZERO); 583119815Smarcel bcopy(sc0, sc, sizeof(*sc)); 584119815Smarcel device_set_softc(dev, sc); 585119815Smarcel } else 586119815Smarcel sc = sc0; 587119815Smarcel 588119815Smarcel /* 589260890Simp * Now that we know the softc for this device, connect the back 590260890Simp * pointer from the sysdev for this device, if any 591260890Simp */ 592260890Simp if (sc->sc_sysdev != NULL) 593260890Simp sc->sc_sysdev->sc = sc; 594260890Simp 595260890Simp /* 596119815Smarcel * Protect ourselves against interrupts while we're not completely 597119815Smarcel * finished attaching and initializing. We don't expect interrupts 598285843Smarius * until after UART_ATTACH(), though. 599119815Smarcel */ 600119815Smarcel sc->sc_leaving = 1; 601119815Smarcel 602157300Smarcel mtx_init(&sc->sc_hwmtx_s, "uart_hwmtx", NULL, MTX_SPIN); 603157300Smarcel if (sc->sc_hwmtx == NULL) 604157300Smarcel sc->sc_hwmtx = &sc->sc_hwmtx_s; 605120143Smarcel 606119815Smarcel /* 607119815Smarcel * Re-allocate. We expect that the softc contains the information 608119815Smarcel * collected by uart_bus_probe() intact. 609119815Smarcel */ 610286653Smarcel sc->sc_rres = bus_alloc_resource_any(dev, sc->sc_rtype, &sc->sc_rrid, 611286653Smarcel RF_ACTIVE); 612143025Smarius if (sc->sc_rres == NULL) { 613157300Smarcel mtx_destroy(&sc->sc_hwmtx_s); 614119815Smarcel return (ENXIO); 615143025Smarius } 616120380Snyan sc->sc_bas.bsh = rman_get_bushandle(sc->sc_rres); 617120380Snyan sc->sc_bas.bst = rman_get_bustag(sc->sc_rres); 618120380Snyan 619248963Sian /* 620248963Sian * Ensure there is room for at least three full FIFOs of data in the 621248963Sian * receive buffer (handles the case of low-level drivers with huge 622248963Sian * FIFOs), and also ensure that there is no less than the historical 623248963Sian * size of 384 bytes (handles the typical small-FIFO case). 624248963Sian */ 625248963Sian sc->sc_rxbufsz = MAX(384, sc->sc_rxfifosz * 3); 626119815Smarcel sc->sc_rxbuf = malloc(sc->sc_rxbufsz * sizeof(*sc->sc_rxbuf), 627119815Smarcel M_UART, M_WAITOK); 628119815Smarcel sc->sc_txbuf = malloc(sc->sc_txfifosz * sizeof(*sc->sc_txbuf), 629119815Smarcel M_UART, M_WAITOK); 630119815Smarcel 631119815Smarcel error = UART_ATTACH(sc); 632119815Smarcel if (error) 633119815Smarcel goto fail; 634119815Smarcel 635119815Smarcel if (sc->sc_hwiflow || sc->sc_hwoflow) { 636119815Smarcel sep = ""; 637119815Smarcel device_print_prettyname(dev); 638119815Smarcel if (sc->sc_hwiflow) { 639119815Smarcel printf("%sRTS iflow", sep); 640119815Smarcel sep = ", "; 641119815Smarcel } 642119815Smarcel if (sc->sc_hwoflow) { 643119815Smarcel printf("%sCTS oflow", sep); 644119815Smarcel sep = ", "; 645119815Smarcel } 646119815Smarcel printf("\n"); 647119815Smarcel } 648119815Smarcel 649119815Smarcel if (sc->sc_sysdev != NULL) { 650262932Simp if (sc->sc_sysdev->baudrate == 0) { 651137706Smarcel if (UART_IOCTL(sc, UART_IOCTL_BAUD, 652137706Smarcel (intptr_t)&sc->sc_sysdev->baudrate) != 0) 653137706Smarcel sc->sc_sysdev->baudrate = -1; 654137706Smarcel } 655119815Smarcel switch (sc->sc_sysdev->type) { 656119815Smarcel case UART_DEV_CONSOLE: 657119815Smarcel device_printf(dev, "console"); 658119815Smarcel break; 659119815Smarcel case UART_DEV_DBGPORT: 660119815Smarcel device_printf(dev, "debug port"); 661119815Smarcel break; 662119815Smarcel case UART_DEV_KEYBOARD: 663119815Smarcel device_printf(dev, "keyboard"); 664119815Smarcel break; 665119815Smarcel default: 666119815Smarcel device_printf(dev, "unknown system device"); 667119815Smarcel break; 668119815Smarcel } 669119815Smarcel printf(" (%d,%c,%d,%d)\n", sc->sc_sysdev->baudrate, 670119815Smarcel "noems"[sc->sc_sysdev->parity], sc->sc_sysdev->databits, 671119815Smarcel sc->sc_sysdev->stopbits); 672119815Smarcel } 673119815Smarcel 674253161Smarcel sc->sc_leaving = 0; 675285843Smarius sc->sc_testintr = 1; 676253161Smarcel filt = uart_intr(sc); 677285843Smarius sc->sc_testintr = 0; 678253161Smarcel 679253161Smarcel /* 680253161Smarcel * Don't use interrupts if we couldn't clear any pending interrupt 681253161Smarcel * conditions. We may have broken H/W and polling is probably the 682253161Smarcel * safest thing to do. 683253161Smarcel */ 684285619Sneel if (filt != FILTER_SCHEDULE_THREAD && !uart_force_poll) { 685253161Smarcel sc->sc_irid = 0; 686253161Smarcel sc->sc_ires = bus_alloc_resource_any(dev, SYS_RES_IRQ, 687253161Smarcel &sc->sc_irid, RF_ACTIVE | RF_SHAREABLE); 688253161Smarcel } 689253161Smarcel if (sc->sc_ires != NULL) { 690253161Smarcel error = bus_setup_intr(dev, sc->sc_ires, INTR_TYPE_TTY, 691253161Smarcel uart_intr, NULL, sc, &sc->sc_icookie); 692253161Smarcel sc->sc_fastintr = (error == 0) ? 1 : 0; 693253161Smarcel 694253161Smarcel if (!sc->sc_fastintr) 695253161Smarcel error = bus_setup_intr(dev, sc->sc_ires, 696253161Smarcel INTR_TYPE_TTY | INTR_MPSAFE, NULL, 697253161Smarcel (driver_intr_t *)uart_intr, sc, &sc->sc_icookie); 698253161Smarcel 699253161Smarcel if (error) { 700253161Smarcel device_printf(dev, "could not activate interrupt\n"); 701253161Smarcel bus_release_resource(dev, SYS_RES_IRQ, sc->sc_irid, 702253161Smarcel sc->sc_ires); 703253161Smarcel sc->sc_ires = NULL; 704253161Smarcel } 705253161Smarcel } 706253161Smarcel if (sc->sc_ires == NULL) { 707253161Smarcel /* No interrupt resource. Force polled mode. */ 708253161Smarcel sc->sc_polled = 1; 709253161Smarcel callout_init(&sc->sc_timer, 1); 710285619Sneel callout_reset(&sc->sc_timer, hz / uart_poll_freq, 711285619Sneel (timeout_t *)uart_intr, sc); 712253161Smarcel } 713253161Smarcel 714253161Smarcel if (bootverbose && (sc->sc_fastintr || sc->sc_polled)) { 715253161Smarcel sep = ""; 716253161Smarcel device_print_prettyname(dev); 717253161Smarcel if (sc->sc_fastintr) { 718253161Smarcel printf("%sfast interrupt", sep); 719253161Smarcel sep = ", "; 720253161Smarcel } 721253161Smarcel if (sc->sc_polled) { 722254534Sian printf("%spolled mode (%dHz)", sep, uart_poll_freq); 723253161Smarcel sep = ", "; 724253161Smarcel } 725253161Smarcel printf("\n"); 726253161Smarcel } 727253161Smarcel 728286469Sian if (sc->sc_sysdev != NULL && sc->sc_sysdev->attach != NULL) { 729286469Sian if ((error = sc->sc_sysdev->attach(sc)) != 0) 730286469Sian goto fail; 731286469Sian } else { 732286469Sian if ((error = uart_tty_attach(sc)) != 0) 733286469Sian goto fail; 734286591Sian uart_pps_init(sc); 735286469Sian } 736119815Smarcel 737157300Smarcel if (sc->sc_sysdev != NULL) 738157300Smarcel sc->sc_sysdev->hwmtx = sc->sc_hwmtx; 739157300Smarcel 740365480Sjhb if (sc->sc_rxfifosz > 1) 741365480Sjhb SYSCTL_ADD_INT(device_get_sysctl_ctx(dev), 742365480Sjhb SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, 743365480Sjhb "rx_overruns", CTLFLAG_RD, &sc->sc_rxoverruns, 0, 744365480Sjhb "Receive overruns"); 745365480Sjhb 746119815Smarcel return (0); 747119815Smarcel 748119815Smarcel fail: 749119815Smarcel free(sc->sc_txbuf, M_UART); 750119815Smarcel free(sc->sc_rxbuf, M_UART); 751119815Smarcel 752119815Smarcel if (sc->sc_ires != NULL) { 753119815Smarcel bus_teardown_intr(dev, sc->sc_ires, sc->sc_icookie); 754119815Smarcel bus_release_resource(dev, SYS_RES_IRQ, sc->sc_irid, 755119815Smarcel sc->sc_ires); 756119815Smarcel } 757119815Smarcel bus_release_resource(dev, sc->sc_rtype, sc->sc_rrid, sc->sc_rres); 758119815Smarcel 759157300Smarcel mtx_destroy(&sc->sc_hwmtx_s); 760143025Smarius 761119815Smarcel return (error); 762119815Smarcel} 763119815Smarcel 764119815Smarcelint 765119815Smarceluart_bus_detach(device_t dev) 766119815Smarcel{ 767119815Smarcel struct uart_softc *sc; 768119815Smarcel 769119815Smarcel sc = device_get_softc(dev); 770119815Smarcel 771119815Smarcel sc->sc_leaving = 1; 772119815Smarcel 773157300Smarcel if (sc->sc_sysdev != NULL) 774157300Smarcel sc->sc_sysdev->hwmtx = NULL; 775157300Smarcel 776119815Smarcel UART_DETACH(sc); 777119815Smarcel 778119815Smarcel if (sc->sc_sysdev != NULL && sc->sc_sysdev->detach != NULL) 779119815Smarcel (*sc->sc_sysdev->detach)(sc); 780119815Smarcel else 781119815Smarcel uart_tty_detach(sc); 782119815Smarcel 783119815Smarcel free(sc->sc_txbuf, M_UART); 784119815Smarcel free(sc->sc_rxbuf, M_UART); 785119815Smarcel 786119815Smarcel if (sc->sc_ires != NULL) { 787119815Smarcel bus_teardown_intr(dev, sc->sc_ires, sc->sc_icookie); 788119815Smarcel bus_release_resource(dev, SYS_RES_IRQ, sc->sc_irid, 789119815Smarcel sc->sc_ires); 790119815Smarcel } 791119815Smarcel bus_release_resource(dev, sc->sc_rtype, sc->sc_rrid, sc->sc_rres); 792119815Smarcel 793157300Smarcel mtx_destroy(&sc->sc_hwmtx_s); 794143025Smarius 795119815Smarcel if (sc->sc_class->size > sizeof(*sc)) { 796119815Smarcel device_set_softc(dev, NULL); 797119815Smarcel free(sc, M_UART); 798119815Smarcel } else 799119815Smarcel device_set_softc(dev, NULL); 800119815Smarcel 801119815Smarcel return (0); 802119815Smarcel} 803246243Savg 804246243Savgint 805246243Savguart_bus_resume(device_t dev) 806246243Savg{ 807246243Savg struct uart_softc *sc; 808246243Savg 809246243Savg sc = device_get_softc(dev); 810246243Savg return (UART_ATTACH(sc)); 811246243Savg} 812260890Simp 813260890Simpvoid 814260890Simpuart_grab(struct uart_devinfo *di) 815260890Simp{ 816260890Simp 817260890Simp if (di->sc) 818260890Simp UART_GRAB(di->sc); 819260890Simp} 820260890Simp 821260890Simpvoid 822260890Simpuart_ungrab(struct uart_devinfo *di) 823260890Simp{ 824260890Simp 825260890Simp if (di->sc) 826260890Simp UART_UNGRAB(di->sc); 827260890Simp} 828