Esempio n. 1
0
static int omap_uart_driver_probe(struct vmm_device *dev,
				  const struct vmm_devtree_nodeid *devid)
{
	int rc;
	u32 reg_offset;
	struct omap_uart_port *port;
	
	port = vmm_zalloc(sizeof(struct omap_uart_port));
	if(!port) {
		rc = VMM_ENOMEM;
		goto free_nothing;
	}

	if (strlcpy(port->cd.name, dev->name, sizeof(port->cd.name)) >=
	    sizeof(port->cd.name)) {
		rc = VMM_EOVERFLOW;
		goto free_port;
	}

	port->cd.dev.parent = dev;
	port->cd.ioctl = NULL;
	port->cd.read = omap_uart_read;
	port->cd.write = omap_uart_write;
	port->cd.priv = port;

	INIT_COMPLETION(&port->read_possible);
	INIT_COMPLETION(&port->write_possible);

	rc = vmm_devtree_regmap(dev->node, &port->base, 0);
	if(rc) {
		goto free_port;
	}

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

	if (vmm_devtree_read_u32(dev->node, "reg_offset",
				 &reg_offset) == VMM_OK) {
		port->base += reg_offset;
	}

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

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

	omap_uart_startup_configure(port);

	rc = vmm_devtree_irq_get(dev->node, &port->irq, 0);
	if (rc) {
		goto free_reg;
	}
	if ((rc = vmm_host_irq_register(port->irq, dev->name,
					omap_uart_irq_handler, port))) {
		goto free_reg;
	}

	rc = vmm_chardev_register(&port->cd);
	if (rc) {
		goto free_irq;
	}

	dev->priv = port;

	return VMM_OK;

free_irq:
	vmm_host_irq_unregister(port->irq, port);
free_reg:
	vmm_devtree_regunmap(dev->node, port->base, 0);
free_port:
	vmm_free(port);
free_nothing:
	return rc;
}
Esempio n. 2
0
static int omap_uart_driver_probe(struct vmm_device *dev,
				  const struct vmm_devtree_nodeid *devid)
{
	int rc;
	struct omap_uart_port *port;
	
	port = vmm_zalloc(sizeof(struct omap_uart_port));
	if (!port) {
		rc = VMM_ENOMEM;
		goto free_nothing;
	}

	rc = vmm_devtree_request_regmap(dev->of_node, &port->base, 0,
					"omap-uart");
	if (rc) {
		goto free_port;
	}

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

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

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

	omap_uart_startup_configure(port);

	port->irq = vmm_devtree_irq_parse_map(dev->of_node, 0);
	if (!port->irq) {
		rc = VMM_ENODEV;
		goto free_reg;
	}
	if ((rc = vmm_host_irq_register(port->irq, dev->name,
					omap_uart_irq_handler, port))) {
		goto free_reg;
	}

	/* Create Serial Port */
	port->p = serial_create(dev, 256, omap_uart_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_RDI | UART_IER_RLSI);
	omap_serial_out(port, UART_IER, port->ier);

	return VMM_OK;

free_irq:
	vmm_host_irq_unregister(port->irq, port);
free_reg:
	vmm_devtree_regunmap_release(dev->of_node, port->base, 0);
free_port:
	vmm_free(port);
free_nothing:
	return rc;
}