示例#1
0
static int
uart_octeon_probe(device_t dev)
{
	struct uart_softc *sc;
	int unit;

	unit = device_get_unit(dev);
	sc = device_get_softc(dev);
	sc->sc_class = &uart_oct16550_class;

	/*
	 * We inherit the settings from the systme console.  Note, the bst
	 * bad bus_space_map are bogus here, but obio doesn't yet support
	 * them, it seems.
	 */
	sc->sc_sysdev = SLIST_FIRST(&uart_sysdevs);
	bcopy(&sc->sc_sysdev->bas, &sc->sc_bas, sizeof(sc->sc_bas));
	sc->sc_bas.bst = uart_bus_space_mem;
	/*
	 * XXX
	 * RBR isn't really a great base address.
	 */
	if (bus_space_map(sc->sc_bas.bst, CVMX_MIO_UARTX_RBR(0),
	    uart_getrange(sc->sc_class), 0, &sc->sc_bas.bsh) != 0)
		return (ENXIO);
	return (uart_bus_probe(dev, sc->sc_bas.regshft, 0, 0, unit));
}
示例#2
0
文件: ewx_uart.c 项目: zliu/libewx
/**
 * Get a single byte from serial port.
 *
 * @param uart_index Uart to read from (0 or 1)
 * @return The byte read
 */
inline uint8_t uart_read_byte_wait( int uart_index )
{
	/* Read and return the data. Will not be returned if there is
	no data */
	if( !pci_console )
	{
		cvmx_uart_lsr_t lsrval;
		while ( 1 )
		{
			lsrval.u64 = cvmx_read_csr( CVMX_MIO_UARTX_LSR( uart_index ) );
			if ( lsrval.s.dr )
			{
				return cvmx_read_csr( CVMX_MIO_UARTX_RBR( uart_index ) );
			}
			return getchar();
		}
	}
	else
	{
		char c;
		while ( 1 )
		{
			if ( !pci_cons_desc_addr )
			{
				return 0;
			}
			octeon_pci_console_read(pci_cons_desc_addr, 0,	&c, 1, 1);
			return c;
		}
	}
}
示例#3
0
文件: ewx_uart.c 项目: zliu/libewx
int uart_read_byte_nowait( int uart_index )
{
	/* Read and return the data. Zero will be returned if there is
	no data */
	if( !pci_console )
	{
		cvmx_uart_lsr_t lsrval;
		lsrval.u64 = cvmx_read_csr( CVMX_MIO_UARTX_LSR( uart_index ) );
		if ( lsrval.s.dr )
		{
			return cvmx_read_csr( CVMX_MIO_UARTX_RBR( uart_index ) );
		}
		else
		{
			return -1;
		}
	}
	else
	{
		char c;
		if ( !pci_cons_desc_addr )
		{
			return 0;
		}
		octeon_pci_console_read(pci_cons_desc_addr, 0,	&c, 1, 1);
		return c;
	}
}
示例#4
0
static struct resource *
obio_alloc_resource(device_t bus, device_t child, int type, int *rid,
    u_long start, u_long end, u_long count, u_int flags)
{
	struct resource *rv;
	struct rman *rm;
	bus_space_tag_t bt = 0;
	bus_space_handle_t bh = 0;
	struct obio_softc *sc = device_get_softc(bus);

	switch (type) {
	case SYS_RES_IRQ:
		switch (device_get_unit(child)) {
		case 0:
			start = end = OCTEON_IRQ_UART0;
			break;
		case 1:
			start = end = OCTEON_IRQ_UART1;
			break;
		default:
			return (NULL);
		}
		rm = &sc->oba_irq_rman;
		break;
	case SYS_RES_MEMORY:
		return (NULL);
	case SYS_RES_IOPORT:
		rm = &sc->oba_rman;
		bt = &octeon_uart_tag;
		bh = CVMX_MIO_UARTX_RBR(device_get_unit(child));
		start = bh;
		break;
	default:
		return (NULL);
	}

	rv = rman_reserve_resource(rm, start, end, count, flags, child);
	if (rv == NULL)  {
		return (NULL);
        }
	if (type == SYS_RES_IRQ) {
		return (rv);
        }
	rman_set_rid(rv, *rid);
	rman_set_bustag(rv, bt);
	rman_set_bushandle(rv, bh);
	
	if (0) {
		if (bus_activate_resource(child, type, *rid, rv)) {
			rman_release_resource(rv);
			return (NULL);
		}
	}
	return (rv);

}
示例#5
0
/**
 * Get a single byte from serial port.
 *
 * @param uart_index Uart to read from (0 or 1)
 * @return The byte read
 */
static inline uint8_t uart_read_byte(int uart)
{
    cvmx_uart_lsr_t lsrval;
    uint8_t uart_index = GET_UART_INDEX(uart);
    uint8_t node = GET_UART_NODE(uart);

    /* Spin until data is available */
    do {
        lsrval.u64 = cvmx_read_csr_node(node,
                                        CVMX_MIO_UARTX_LSR(uart_index));
        WATCHDOG_RESET();
        octeon_board_poll();
    } while (!lsrval.s.dr);

    /* Read and return the data */
    return cvmx_read_csr_node(node, CVMX_MIO_UARTX_RBR(uart_index));
}
示例#6
0
static int
obio_attach(device_t dev)
{
	struct obio_softc *sc = device_get_softc(dev);

	sc->oba_st = mips_bus_space_generic;
	/*
	 * XXX
	 * Here and elsewhere using RBR as a base address because it kind of
	 * is, but that feels pretty sloppy.  Should consider adding a define
	 * that's more semantic, at least.
	 */
	sc->oba_addr = CVMX_MIO_UARTX_RBR(0);
	sc->oba_size = 0x10000;
	sc->oba_rman.rm_type = RMAN_ARRAY;
	sc->oba_rman.rm_descr = "OBIO I/O";
	if (rman_init(&sc->oba_rman) != 0 ||
	    rman_manage_region(&sc->oba_rman,
	    sc->oba_addr, sc->oba_addr + sc->oba_size) != 0)
		panic("obio_attach: failed to set up I/O rman");
	sc->oba_irq_rman.rm_type = RMAN_ARRAY;
	sc->oba_irq_rman.rm_descr = "OBIO IRQ";

	/* 
	 * This module is intended for UART purposes only and
	 * manages IRQs for UART0 and UART1.
	 */
	if (rman_init(&sc->oba_irq_rman) != 0 ||
	    rman_manage_region(&sc->oba_irq_rman, OCTEON_IRQ_UART0, OCTEON_IRQ_UART1) != 0)
		panic("obio_attach: failed to set up IRQ rman");

	device_add_child(dev, "uart", 1);  /* Setup Uart-1 first. */
	device_add_child(dev, "uart", 0);  /* Uart-0 next. So it is first in console list */
	bus_generic_probe(dev);
	bus_generic_attach(dev);
	return (0);
}
static int __init octeon_serial_init(void)
{
	int enable_uart0;
	int enable_uart1;
	int enable_uart2;
	struct plat_serial8250_port *p;

#ifdef CONFIG_CAVIUM_OCTEON_2ND_KERNEL
	/*
	 * If we are configured to run as the second of two kernels,
	 * disable uart0 and enable uart1. Uart0 is owned by the first
	 * kernel
	 */
	enable_uart0 = 0;
	enable_uart1 = 1;
#else
	/*
	 * We are configured for the first kernel. We'll enable uart0
	 * if the bootloader told us to use 0, otherwise will enable
	 * uart 1.
	 */
	enable_uart0 = (octeon_get_boot_uart() == 0);
	enable_uart1 = (octeon_get_boot_uart() == 1);
#ifdef CONFIG_KGDB
	enable_uart1 = 1;
#endif
#endif

	/* Right now CN52XX is the only chip with a third uart */
	enable_uart2 = OCTEON_IS_MODEL(OCTEON_CN52XX);

	p = octeon_uart8250_data;
	if (enable_uart0) {
		/* Add a ttyS device for hardware uart 0 */
		octeon_uart_set_common(p);
		p->membase = (void *) CVMX_MIO_UARTX_RBR(0);
		p->mapbase = CVMX_MIO_UARTX_RBR(0) & ((1ull << 49) - 1);
		p->irq = OCTEON_IRQ_UART0;
		p++;
	}

	if (enable_uart1) {
		/* Add a ttyS device for hardware uart 1 */
		octeon_uart_set_common(p);
		p->membase = (void *) CVMX_MIO_UARTX_RBR(1);
		p->mapbase = CVMX_MIO_UARTX_RBR(1) & ((1ull << 49) - 1);
		p->irq = OCTEON_IRQ_UART1;
		p++;
	}
	if (enable_uart2) {
		/* Add a ttyS device for hardware uart 2 */
		octeon_uart_set_common(p);
		p->membase = (void *) CVMX_MIO_UART2_RBR;
		p->mapbase = CVMX_MIO_UART2_RBR & ((1ull << 49) - 1);
		p->irq = OCTEON_IRQ_UART2;
		p++;
	}

	BUG_ON(p > &octeon_uart8250_data[OCTEON_MAX_UARTS]);

	return platform_device_register(&octeon_uart8250_device);
}