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", ®_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; }
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; }