Ejemplo n.º 1
0
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);
}
Ejemplo n.º 3
0
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);
}