Esempio n. 1
0
static int __init tegra_uart_probe(struct platform_device *pdev)
{
	struct tegra_uart_port *t;
	struct uart_port *u;
	struct tegra_uart_platform_data *pdata;
	struct resource *resource;
	struct resource *iomem;
	int ret;
	char name[64];
	if (pdev->id < 0 || pdev->id > tegra_uart_driver.nr) {
		pr_err("Invalid Uart instance (%d)\n", pdev->id);
		return -ENODEV;
	}

	t = kzalloc(sizeof(struct tegra_uart_port), GFP_KERNEL);
	if (!t) {
		pr_err("%s: Failed to allocate memory\n", __func__);
		return -ENOMEM;
	}
	u = &t->uport;
	u->dev = &pdev->dev;
	platform_set_drvdata(pdev, u);
	u->line = pdev->id;
	u->ops = &tegra_uart_ops;
	u->type = PORT_TEGRA;
	u->fifosize = 32;

	pdata = u->dev->platform_data;
	if (pdata && pdata->is_irda) {
		dev_info(&pdev->dev, "Initialized UART %d as SIR PHY\n",
								u->line);
		t->is_irda = pdata->is_irda;
		t->irda_init = pdata->irda_init;
		t->irda_start = pdata->irda_start;
		t->irda_mode_switch = pdata->irda_mode_switch;
		t->irda_shutdown = pdata->irda_shutdown;
		t->irda_remove = pdata->irda_remove;
		if (t->irda_init)
			t->irda_init();
	}

	resource = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (unlikely(!resource)) {
		ret = -ENXIO;
		goto fail;
	}

	u->mapbase = resource->start;
	iomem = request_mem_region(u->mapbase, resource_size(resource),
			pdev->name);
	if (!iomem) {
		dev_err(&pdev->dev, "UART region already claimed\n");
		ret = -EBUSY;
		goto fail;
	}

	u->membase = ioremap(iomem->start, resource_size(iomem));
	if (unlikely(!u->membase)) {
		dev_err(&pdev->dev, "Cannot ioremap UART region\n");
		ret = -ENOMEM;
		goto fail;
	}
	u->iotype = UPIO_MEM32;

	u->irq = platform_get_irq(pdev, 0);
	if (unlikely((int)(u->irq) < 0)) {
		ret = -ENXIO;
		goto fail;
	}

	device_set_wakeup_capable(u->dev, 1);
	u->regshift = 2;

	t->clk = clk_get(&pdev->dev, NULL);
	if (IS_ERR_OR_NULL(t->clk)) {
		dev_err(&pdev->dev, "Couldn't get the clock\n");
		ret = -ENODEV;
		goto fail;
	}

	ret = uart_add_one_port(&tegra_uart_driver, u);
	if (ret) {
		pr_err("%s: Failed(%d) to add uart port %s%d\n",
			__func__, ret, tegra_uart_driver.dev_name, u->line);
		goto fail;
	}

	snprintf(name, sizeof(name), "tegra_hsuart_%d", u->line);
	pr_info("Registered UART port %s%d\n",
		tegra_uart_driver.dev_name, u->line);
	t->uart_state = TEGRA_UART_CLOSED;

	if (!RX_FORCE_PIO) {
		ret = tegra_uart_init_rx_dma_buffer(t);
		if (ret < 0) {
			pr_err("%s: Failed(%d) to allocate rx dma buffer "
				"%s%d\n", __func__, ret,
				tegra_uart_driver.dev_name, u->line);
			goto rx_dma_buff_fail;
		}
	}
	tasklet_init(&t->tlet, tegra_uart_tasklet_action, (unsigned long) t);
	pm_runtime_enable((&t->uport)->dev);

	return ret;

rx_dma_buff_fail:
	uart_remove_one_port(&tegra_uart_driver, u);
fail:
	if (t->clk)
		clk_put(t->clk);
	platform_set_drvdata(pdev, NULL);
	kfree(t);
	return ret;
}
static int tegra_uart_probe(struct platform_device *pdev)
{
	struct tegra_uart_port *t;
	struct uart_port *u;
	struct resource *resource;
	int ret;
	char name[64];
	if (pdev->id < 0 || pdev->id > tegra_uart_driver.nr) {
		pr_err("Invalid Uart instance (%d)\n", pdev->id);
		return -ENODEV;
	}

	t = kzalloc(sizeof(struct tegra_uart_port), GFP_KERNEL);
	if (!t) {
		pr_err("%s: Failed to allocate memory\n", __func__);
		return -ENOMEM;
	}
	u = &t->uport;
	u->dev = &pdev->dev;
	platform_set_drvdata(pdev, u);
	u->line = pdev->id;
	u->ops = &tegra_uart_ops;
	u->type = ~PORT_UNKNOWN;
	u->fifosize = 32;

	resource = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (unlikely(!resource)) {
		ret = -ENXIO;
		goto fail;
	}

	u->mapbase = resource->start;
	u->membase = IO_ADDRESS(u->mapbase);
	if (unlikely(!u->membase)) {
		ret = -ENOMEM;
		goto fail;
	}

	u->irq = platform_get_irq(pdev, 0);
	if (unlikely(u->irq < 0)) {
		ret = -ENXIO;
		goto fail;
	}

	u->regshift = 2;

	t->clk = clk_get(&pdev->dev, NULL);
	if (IS_ERR_OR_NULL(t->clk)) {
		dev_err(&pdev->dev, "Couldn't get the clock\n");
		ret = -ENODEV;
		goto fail;
	}

	ret = uart_add_one_port(&tegra_uart_driver, u);
	if (ret) {
		pr_err("%s: Failed(%d) to add uart port %s%d\n",
			__func__, ret, tegra_uart_driver.dev_name, u->line);
		goto fail;
	}

	snprintf(name, sizeof(name), "tegra_hsuart_%d", u->line);
	pr_info("Registered UART port %s%d\n",
		tegra_uart_driver.dev_name, u->line);
	t->uart_state = TEGRA_UART_CLOSED;

	if (!RX_FORCE_PIO) {
		ret = tegra_uart_init_rx_dma_buffer(t);
		if (ret < 0) {
			pr_err("%s: Failed(%d) to allocate rx dma buffer "
				"%s%d\n", __func__, ret,
				tegra_uart_driver.dev_name, u->line);
			goto rx_dma_buff_fail;
		}
	}
	return ret;

rx_dma_buff_fail:
	uart_remove_one_port(&tegra_uart_driver, u);
fail:
	if (t->clk)
		clk_put(t->clk);
	platform_set_drvdata(pdev, NULL);
	kfree(t);
	return ret;
}