Ejemplo n.º 1
0
int clk_bulk_get(struct vmm_device *dev, int num_clks,
		 struct clk_bulk_data *clks)
{
	int ret;
	int i;

	for (i = 0; i < num_clks; i++)
		clks[i].clk = NULL;

	for (i = 0; i < num_clks; i++) {
		clks[i].clk = clk_get(dev, clks[i].id);
		if (VMM_IS_ERR(clks[i].clk)) {
			ret = VMM_PTR_ERR(clks[i].clk);
			vmm_lerror(dev->name, "Failed to get clk '%s': %d\n",
				   clks[i].id, ret);
			clks[i].clk = NULL;
			goto err;
		}
	}

	return 0;

err:
	clk_bulk_put(i, clks);

	return ret;
}
Ejemplo n.º 2
0
static int samsung_driver_probe(struct vmm_device *dev,
                                const struct vmm_devtree_nodeid *devid)
{
    u32 ucon;
    int rc = VMM_EFAIL;
    struct samsung_port *port = NULL;

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

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

    /* Make sure all interrupts except Rx are masked. */
    port->mask = S3C64XX_UINTM_RXD_MSK;
    port->mask = ~port->mask;
    vmm_out_le16((void *)(port->base + S3C64XX_UINTM), port->mask);

    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;
    }

    /* Setup interrupt handler */
    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,
                                    samsung_irq_handler, port))) {
        goto free_reg;
    }

    /* Call low-level init function */
    samsung_lowlevel_init(port->base, port->baudrate, port->input_clock);

    /* Create Serial Port */
    port->p = serial_create(dev, 256, samsung_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 */
    ucon = vmm_in_le32((void *)(port->base + S3C2410_UCON));
    ucon |= S3C2410_UCON_RXIRQMODE;
    vmm_out_le32((void *)(port->base + S3C2410_UCON), ucon);

    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;
}
Ejemplo n.º 3
0
static int imx_driver_probe(struct vmm_device *dev,
			    const struct vmm_devtree_nodeid *devid)
{
	int rc = VMM_EFAIL;
	struct clk *clk_ipg = NULL;
	struct clk *clk_uart = NULL;
	struct imx_port *port = NULL;
	unsigned long old_rate = 0;

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

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

	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;
	}

	/* Setup clocks */
	clk_ipg = of_clk_get(dev->of_node, 0);
	clk_uart = of_clk_get(dev->of_node, 1);
	if (!VMM_IS_ERR_OR_NULL(clk_ipg)) {
		rc = clk_prepare_enable(clk_ipg);
		if (rc) {
			goto free_reg;
		}
	}
	if (!VMM_IS_ERR_OR_NULL(clk_uart)) {
		rc = clk_prepare_enable(clk_uart);
		if (rc) {
			goto clk_disable_unprepare_ipg;
		}
		old_rate = clk_get_rate(clk_uart);
		if (clk_set_rate(clk_uart, port->input_clock)) {
			vmm_printf("Could not set %s clock rate to %u Hz, "
				   "actual rate: %u Hz\n", __clk_get_name(clk_uart),
				   port->input_clock, clk_get_rate(clk_uart));
			rc = VMM_ERANGE;
			goto clk_disable_unprepare_uart;
		}
	}

	/* Register interrupt handler */
	port->irq = vmm_devtree_irq_parse_map(dev->of_node, 0);
	if (!port->irq) {
		rc = VMM_ENODEV;
		goto clk_old_rate;
	}
	if ((rc = vmm_host_irq_register(port->irq, dev->name,
					imx_irq_handler, port))) {
		goto clk_old_rate;
	}

	/* Call low-level init function */
	imx_lowlevel_init(port->base, port->baudrate, port->input_clock);

	/* Create Serial Port */
	port->p = serial_create(dev, 256, imx_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, Mask Tx, and Enable UART */
	port->mask = vmm_readl((void *)port->base + UCR1);
	port->mask |= (UCR1_RRDYEN | UCR1_UARTEN);
	port->mask &= ~(UCR1_TRDYEN);
	vmm_writel(port->mask, (void *)port->base + UCR1);

	return rc;

free_irq:
	vmm_host_irq_unregister(port->irq, port);
clk_old_rate:
	if (!VMM_IS_ERR_OR_NULL(clk_uart)) {
		if (old_rate) {
			clk_set_rate(clk_uart, old_rate);
		}
	}
clk_disable_unprepare_uart:
	if (!VMM_IS_ERR_OR_NULL(clk_uart)) {
		clk_disable_unprepare(clk_uart);
	}
clk_disable_unprepare_ipg:
	if (!VMM_IS_ERR_OR_NULL(clk_ipg)) {
		clk_disable_unprepare(clk_ipg);
	}
free_reg:
	vmm_devtree_regunmap_release(dev->of_node, port->base, 0);
free_port:
	vmm_free(port);
free_nothing:
	return rc;
}
Ejemplo n.º 4
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;
}
Ejemplo n.º 5
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;
}