Esempio n. 1
0
static int __init uart8250_defterm_init(struct vmm_devtree_node *node)
{
	int rc;

	rc = vmm_devtree_regmap(node, &uart8250_port.base, 0);
	if (rc) {
		return rc;
	}

	rc = vmm_devtree_clock_frequency(node,
				&uart8250_port.input_clock);
	if (rc) {
		return rc;
	}

	if (vmm_devtree_read_u32(node, "baudrate",
				 &uart8250_port.baudrate)) {
		uart8250_port.baudrate = 115200;
	}

	if (vmm_devtree_read_u32(node, "reg-shift",
				 &uart8250_port.reg_shift)) {
		uart8250_port.reg_shift = 2;
	}

	if (vmm_devtree_read_u32(node, "reg-io-width",
				 &uart8250_port.reg_width)) {
		uart8250_port.reg_width = 1;
	}

	uart_8250_lowlevel_init(&uart8250_port);

	return VMM_OK;
}
Esempio n. 2
0
int __init arch_defterm_init(void)
{
	int rc;
	u32 *val;
	struct vmm_devtree_node *node;

	node = vmm_devtree_getnode(VMM_DEVTREE_PATH_SEPARATOR_STRING
				   VMM_DEVTREE_HOSTINFO_NODE_NAME
				   VMM_DEVTREE_PATH_SEPARATOR_STRING "soc"
				   VMM_DEVTREE_PATH_SEPARATOR_STRING "uart0");
	if (!node) {
		return VMM_ENODEV;
	}
	rc = vmm_devtree_regmap(node, &sun4i_uart_port.base, 0);
	if (rc) {
		return rc;
	}

	val = vmm_devtree_attrval(node, VMM_DEVTREE_CLOCK_RATE_ATTR_NAME);
	sun4i_uart_port.input_clock = (val) ? *val : 24000000;

	val = vmm_devtree_attrval(node, "baudrate");
	sun4i_uart_port.baudrate = (val) ? *val : 115200;

	val = vmm_devtree_attrval(node, "reg_align");
	sun4i_uart_port.reg_align = (val) ? *val : 4;

	uart_8250_lowlevel_init(&sun4i_uart_port);
	return VMM_OK;
}
Esempio n. 3
0
static int uart_8250_driver_probe(struct vmm_device *dev,
				  const struct vmm_devtree_nodeid *devid)
{
	int rc;
	struct uart_8250_port *port;
	physical_addr_t ioport;
	const char *aval;

	port = vmm_zalloc(sizeof(struct uart_8250_port));
	if(!port) {
		rc = VMM_ENOMEM;
		goto free_nothing;
	}

	if (vmm_devtree_read_string(dev->node,
				    VMM_DEVTREE_ADDRESS_TYPE_ATTR_NAME,
				    &aval)) {
		aval = NULL;
	}
	if (aval && !strcmp(aval, VMM_DEVTREE_ADDRESS_TYPE_VAL_IO)) {
		port->use_ioport = TRUE;
	} else {
		port->use_ioport = FALSE;
	}

	if (port->use_ioport) {
		rc = vmm_devtree_regaddr(dev->node, &ioport, 0);
		if (rc) {
			goto free_port;
		}
		port->base = ioport;
	} else {
		rc = vmm_devtree_request_regmap(dev->node, &port->base, 0,
						"UART 8250");
		if (rc) {
			goto free_port;
		}
	}

	if (vmm_devtree_read_u32(dev->node, "reg-shift",
				 &port->reg_shift)) {
		port->reg_shift = 0;
	}

	if (vmm_devtree_read_u32(dev->node, "reg-io-width",
				 &port->reg_width)) {
		port->reg_width = 1;
	}

	if (vmm_devtree_read_u32(dev->node, "baudrate",
				 &port->baudrate)) {
		port->baudrate = 115200;
	}

	rc = vmm_devtree_clock_frequency(dev->node, &port->input_clock);
	if (rc) {
		goto free_reg;
	}

	/* Call low-level init function
	 * Note: low-level init will make sure that
	 * interrupts are disabled in IER register.
	 */
	uart_8250_lowlevel_init(port);

	/* Setup interrupt handler */
	port->irq = vmm_devtree_irq_parse_map(dev->node, 0);
	if (!port->irq) {
		rc = VMM_ENODEV;
		goto free_reg;
	}
	if ((rc = vmm_host_irq_register(port->irq, dev->name,
					uart_8250_irq_handler, port))) {
		goto free_reg;
	}

	/* Create Serial Port */
	port->p = serial_create(dev, 256, uart_8250_tx, port);
	if (VMM_IS_ERR_OR_NULL(port->p)) {
		rc = VMM_PTR_ERR(port->p);
		goto free_irq;
	}

	/* Save port pointer */
	dev->priv = port;

	/* Unmask Rx interrupt */
	port->ier |= (UART_IER_RLSI | UART_IER_RDI);
	uart_8250_out(port, UART_IER_OFFSET, port->ier);

	return VMM_OK;

free_irq:
	vmm_host_irq_unregister(port->irq, port);
free_reg:
	if (!port->use_ioport) {
		vmm_devtree_regunmap_release(dev->node, port->base, 0);
	}
free_port:
	vmm_free(port);
free_nothing:
	return rc;
}