static void sscom_attach(struct device *parent, struct device *self, void *aux) { struct sscom_softc *sc = (struct sscom_softc *)self; struct s3c2xx0_attach_args *sa = aux; int unit = sa->sa_index; bus_addr_t iobase = s3c2410_uart_config[unit].iobase; printf( ": UART%d addr=%lx", sa->sa_index, iobase ); sc->sc_iot = s3c2xx0_softc->sc_iot; sc->sc_unit = unit; sc->sc_frequency = s3c2xx0_softc->sc_pclk; sc->sc_rx_irqno = s3c2410_uart_config[sa->sa_index].rx_int; sc->sc_tx_irqno = s3c2410_uart_config[sa->sa_index].tx_int; if (bus_space_map(sc->sc_iot, iobase, SSCOM_SIZE, 0, &sc->sc_ioh)) { printf( ": failed to map registers\n" ); return; } printf("\n"); s3c24x0_intr_establish(s3c2410_uart_config[unit].tx_int, IPL_SERIAL, IST_LEVEL, sscomtxintr, sc); s3c24x0_intr_establish(s3c2410_uart_config[unit].rx_int, IPL_SERIAL, IST_LEVEL, sscomrxintr, sc); s3c24x0_intr_establish(s3c2410_uart_config[unit].err_int, IPL_SERIAL, IST_LEVEL, sscomrxintr, sc); sscom_disable_txrxint(sc); sscom_attach_subr(sc); }
static void sscom_attach(device_t parent, device_t self, void *aux) { struct sscom_softc *sc = device_private(self); struct s3c2xx0_attach_args *sa = aux; int unit; bus_addr_t iobase; found = 1; unit = (sa->sa_index == SSIOCF_INDEX_DEFAULT) ? 0 : sa->sa_index; iobase = s3c2440_uart_config[unit].iobase; sc->sc_dev = self; sc->sc_iot = s3c2xx0_softc->sc_iot; sc->sc_unit = unit; sc->sc_frequency = s3c2xx0_softc->sc_pclk; sc->sc_change_txrx_interrupts = s3c2440_change_txrx_interrupts; sc->sc_rx_irqno = s3c2440_uart_config[unit].rx_int; sc->sc_tx_irqno = s3c2440_uart_config[unit].tx_int; if (bus_space_map(sc->sc_iot, iobase, SSCOM_SIZE, 0, &sc->sc_ioh)) { printf( ": failed to map registers\n" ); return; } printf("\n"); s3c24x0_intr_establish(s3c2440_uart_config[unit].tx_int, IPL_SERIAL, IST_LEVEL, sscomtxintr, sc); s3c24x0_intr_establish(s3c2440_uart_config[unit].rx_int, IPL_SERIAL, IST_LEVEL, sscomrxintr, sc); s3c24x0_intr_establish(s3c2440_uart_config[unit].err_int, IPL_SERIAL, IST_LEVEL, sscomrxintr, sc); sscom_disable_txrxint(sc); sscom_attach_subr(sc); }
void sscom_attach_subr(struct sscom_softc *sc) { int unit = sc->sc_unit; bus_space_tag_t iot = sc->sc_iot; bus_space_handle_t ioh = sc->sc_ioh; struct tty *tp; callout_init(&sc->sc_diag_callout, 0); #if (defined(MULTIPROCESSOR) || defined(LOCKDEBUG)) && defined(SSCOM_MPLOCK) sc->sc_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_SERIAL); #endif sc->sc_ucon = UCON_RXINT_ENABLE|UCON_TXINT_ENABLE; /* * set default for modem control hook */ if (sc->sc_set_modem_control == NULL) sc->sc_set_modem_control = sscom_set_modem_control; if (sc->sc_read_modem_status == NULL) sc->sc_read_modem_status = sscom_read_modem_status; /* Disable interrupts before configuring the device. */ KASSERT(sc->sc_change_txrx_interrupts != NULL); KASSERT(sc->sc_clear_interrupts != NULL); sscom_disable_txrxint(sc); #ifdef KGDB /* * Allow kgdb to "take over" this port. If this is * the kgdb device, it has exclusive use. */ if (unit == sscom_kgdb_unit) { SET(sc->sc_hwflags, SSCOM_HW_KGDB); sc->sc_ucon = UCON_DEBUGPORT; } #endif if (unit == sscomconsunit) { uint32_t stat; int timo; sscomconsattached = 1; sscomconstag = iot; sscomconsioh = ioh; /* wait for this transmission to complete */ timo = 1500000; do { stat = bus_space_read_4(iot, ioh, SSCOM_UTRSTAT); } while ((stat & UTRSTAT_TXEMPTY) == 0 && --timo > 0); /* Make sure the console is always "hardwired". */ SET(sc->sc_hwflags, SSCOM_HW_CONSOLE); SET(sc->sc_swflags, TIOCFLAG_SOFTCAR); sc->sc_ucon = UCON_DEBUGPORT; } /* set RX/TX trigger to half values */ bus_space_write_4(iot, ioh, SSCOM_UFCON, __SHIFTIN(4, UFCON_TXTRIGGER) | __SHIFTIN(4, UFCON_RXTRIGGER) | UFCON_FIFO_ENABLE | UFCON_TXFIFO_RESET| UFCON_RXFIFO_RESET); /* tx/rx fifo reset are auto-cleared */ bus_space_write_4(iot, ioh, SSCOM_UCON, sc->sc_ucon); #ifdef KGDB if (ISSET(sc->sc_hwflags, SSCOM_HW_KGDB)) { sscom_kgdb_attached = 1; printf("%s: kgdb\n", device_xname(sc->sc_dev)); sscom_enable_debugport(sc); return; } #endif tp = tty_alloc(); tp->t_oproc = sscomstart; tp->t_param = sscomparam; tp->t_hwiflow = sscomhwiflow; sc->sc_tty = tp; sc->sc_rbuf = malloc(sscom_rbuf_size << 1, M_DEVBUF, M_NOWAIT); sc->sc_rbput = sc->sc_rbget = sc->sc_rbuf; sc->sc_rbavail = sscom_rbuf_size; if (sc->sc_rbuf == NULL) { printf("%s: unable to allocate ring buffer\n", device_xname(sc->sc_dev)); return; } sc->sc_ebuf = sc->sc_rbuf + (sscom_rbuf_size << 1); tty_attach(tp); if (ISSET(sc->sc_hwflags, SSCOM_HW_CONSOLE)) { int maj; /* locate the major number */ maj = cdevsw_lookup_major(&sscom_cdevsw); cn_tab->cn_dev = makedev(maj, device_unit(sc->sc_dev)); printf("%s: console (major=%d)\n", device_xname(sc->sc_dev), maj); } sc->sc_si = softint_establish(SOFTINT_SERIAL, sscomsoft, sc); #ifdef RND_COM rnd_attach_source(&sc->rnd_source, device_xname(sc->sc_dev), RND_TYPE_TTY, RND_FLAG_DEFAULT); #endif /* if there are no enable/disable functions, assume the device is always enabled */ if (ISSET(sc->sc_hwflags, SSCOM_HW_CONSOLE)) sscom_enable_debugport(sc); else sscom_disable_txrxint(sc); SET(sc->sc_hwflags, SSCOM_HW_DEV_OK); }