static int imx_driver_probe(struct vmm_device *dev, const struct vmm_devtree_nodeid *devid) { int rc = VMM_EFAIL; struct imx_port *port = NULL; port = vmm_zalloc(sizeof(struct imx_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 = imx_read; port->cd.write = imx_write; port->cd.priv = port; INIT_COMPLETION(&port->read_possible); #if defined(UART_IMX_USE_TXINTR) INIT_COMPLETION(&port->write_possible); #endif rc = vmm_devtree_regmap(dev->node, &port->base, 0); if (rc) { goto free_port; } port->mask = UCR1_RRDYEN | UCR1_UARTEN; #if defined(UART_IMX_USE_TXINTR) port->mask |= UCR1_TRDYEN; #endif vmm_writel(port->mask, (void *)port->base + UCR1); 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; } 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, imx_irq_handler, port))) { goto free_reg; } /* Call low-level init function */ imx_lowlevel_init(port->base, port->baudrate, port->input_clock); port->mask = vmm_readl((void *)port->base + UCR1); rc = vmm_chardev_register(&port->cd); if (rc) { goto free_irq; } dev->priv = port; return rc; 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 uart_driver_probe(struct vmm_device *dev,const struct vmm_devid *devid) { int rc; const char *attr; struct vmm_chardev *cd; struct uart_port *port; cd = vmm_malloc(sizeof(struct vmm_chardev)); if(!cd) { rc = VMM_EFAIL; goto free_nothing; } vmm_memset(cd, 0, sizeof(struct vmm_chardev)); port = vmm_malloc(sizeof(struct uart_port)); if(!port) { rc = VMM_EFAIL; goto free_chardev; } vmm_memset(port, 0, sizeof(struct uart_port)); vmm_strcpy(cd->name, dev->node->name); cd->dev = dev; cd->ioctl = NULL; cd->read = uart_read; cd->write = uart_write; cd->priv = port; rc = vmm_devdrv_ioremap(dev, &port->base, 0); if(rc) { goto free_port; } attr = vmm_devtree_attrval(dev->node, "reg_align"); if (attr) { port->reg_align = *((u32 *)attr); } else { port->reg_align = 1; } attr = vmm_devtree_attrval(dev->node, "reg_offset"); if (attr) { port->base += *((u32 *)attr); } attr = vmm_devtree_attrval(dev->node, "baudrate"); if(!attr) { rc = VMM_EFAIL; goto free_port; } port->baudrate = *((u32 *)attr); port->input_clock = vmm_devdrv_clock_rate(dev); /* Call low-level init function */ uart_lowlevel_init(port->base, port->reg_align, port->baudrate, port->input_clock); rc = vmm_chardev_register(cd); if(rc) { goto free_port; } return VMM_OK; free_port: vmm_free(port); free_chardev: vmm_free(cd); free_nothing: return rc; }
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; }