static int tegra_uart_startup(struct uart_port *u)
{
	struct tegra_uart_port *tup = to_tegra_uport(u);
	int ret;

	ret = tegra_uart_dma_channel_allocate(tup, false);
	if (ret < 0) {
		dev_err(u->dev, "Tx Dma allocation failed, err = %d\n", ret);
		return ret;
	}

	if (!tup->use_rx_pio) {
		ret = tegra_uart_dma_channel_allocate(tup, true);
		if (ret < 0) {
			dev_err(u->dev, "Rx Dma allocation failed, err = %d\n",
					ret);
			goto fail_rx_dma;
		}
	}

	ret = tegra_uart_hw_init(tup);
	if (ret < 0) {
		dev_err(u->dev, "Uart HW init failed, err = %d\n", ret);
		goto fail_hw_init;
	}

	ret = request_irq(u->irq, tegra_uart_isr, IRQF_DISABLED,
				dev_name(u->dev), tup);
	if (ret < 0) {
		dev_err(u->dev, "Failed to register ISR for IRQ %d\n", u->irq);
		goto fail_hw_init;
	}
	return 0;

fail_hw_init:
	if (!tup->use_rx_pio)
		tegra_uart_dma_channel_free(tup, true);
fail_rx_dma:
	tegra_uart_dma_channel_free(tup, false);
	return ret;
}
Beispiel #2
0
static int tegra_startup(struct uart_port *u)
{
	struct tegra_uart_port *t = container_of(u,
		struct tegra_uart_port, uport);
	int ret = 0;
	struct tegra_uart_platform_data *pdata;

	t = container_of(u, struct tegra_uart_port, uport);
	sprintf(t->port_name, "tegra_uart_%d", u->line);

	t->use_tx_dma = false;
	if (!TX_FORCE_PIO) {
		t->tx_dma = tegra_dma_allocate_channel(TEGRA_DMA_MODE_ONESHOT,
					"uart_tx_%d", u->line);
		if (t->tx_dma)
			t->use_tx_dma = true;
		else
			pr_err("%s: failed to allocate TX DMA.\n", __func__);
	}
	if (t->use_tx_dma) {
		t->tx_dma_req.instance = u->line;
		t->tx_dma_req.complete = tegra_tx_dma_complete_callback;
		t->tx_dma_req.to_memory = 0;

		t->tx_dma_req.dest_addr = (unsigned long)t->uport.mapbase;
		t->tx_dma_req.dest_wrap = 4;
		t->tx_dma_req.source_wrap = 0;
		t->tx_dma_req.source_bus_width = 32;
		t->tx_dma_req.dest_bus_width = 8;
		t->tx_dma_req.req_sel = dma_req_sel[t->uport.line];
		t->tx_dma_req.dev = t;
		t->tx_dma_req.size = 0;
		t->xmit_dma_addr = dma_map_single(t->uport.dev,
			t->uport.state->xmit.buf, UART_XMIT_SIZE,
			DMA_TO_DEVICE);
	}
	t->tx_in_progress = 0;

	t->use_rx_dma = false;
	if (!RX_FORCE_PIO && t->rx_dma_req.virt_addr) {
		if (!tegra_uart_init_rx_dma(t))
			t->use_rx_dma = true;
	}

	ret = tegra_uart_hw_init(t);
	if (ret)
		goto fail;

	if (t->is_irda && t->irda_start)
		t->irda_start();

	pdata = u->dev->platform_data;
	if (pdata && pdata->is_loopback)
		t->mcr_shadow |= UART_MCR_LOOP;

	dev_dbg(u->dev, "Requesting IRQ %d\n", u->irq);
	ret = request_irq(u->irq, tegra_uart_isr,
					IRQF_DISABLED | IRQF_TRIGGER_HIGH,
					t->port_name, t);
	if (ret) {
		dev_err(u->dev, "Failed to register ISR for IRQ %d\n", u->irq);
		goto fail;
	}

	dev_dbg(u->dev, "Started UART port %d\n", u->line);
	return 0;
fail:
	dev_err(u->dev, "Tegra UART startup failed\n");
	return ret;
}