// SPDX-License-Identifier: GPL-2.0+
/*
 *  Serial Port driver for Tegra devices
 *
 *  Copyright (c) 2020, NVIDIA CORPORATION. All rights reserved.
 */

#include <linux/acpi.h>
#include <linux/clk.h>
#include <linux/console.h>
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/reset.h>
#include <linux/slab.h>

#include "8250.h"

struct tegra_uart {
	struct clk *clk;
	struct reset_control *rst;
	int line;
};

static void tegra_uart_handle_break(struct uart_port *p)
{
	unsigned int status, tmout = 10000;

	while (1) {
		status = p->serial_in(p, UART_LSR);
		if (!(status & (UART_LSR_FIFOE | UART_LSR_BRK_ERROR_BITS)))
			break;

		p->serial_in(p, UART_RX);

		if (--tmout == 0)
			break;
		udelay(1);
	}
}

static int tegra_uart_probe(struct platform_device *pdev)
{
	struct uart_8250_port port8250;
	struct tegra_uart *uart;
	struct uart_port *port;
	struct resource *res;
	int ret;

	uart = devm_kzalloc(&pdev->dev, sizeof(*uart), GFP_KERNEL);
	if (!uart)
		return -ENOMEM;

	memset(&port8250, 0, sizeof(port8250));

	port = &port8250.port;
	spin_lock_init(&port->lock);

	port->flags = UPF_SHARE_IRQ | UPF_BOOT_AUTOCONF | UPF_FIXED_PORT |
		      UPF_FIXED_TYPE;
	port->iotype = UPIO_MEM32;
	port->regshift = 2;
	port->type = PORT_TEGRA;
	port->irqflags |= IRQF_SHARED;
	port->dev = &pdev->dev;
	port->handle_break = tegra_uart_handle_break;

	ret = of_alias_get_id(pdev->dev.of_node, "serial");
	if (ret >= 0)
		port->line = ret;

	ret = platform_get_irq(pdev, 0);
	if (ret < 0)
		return ret;

	port->irq = ret;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res)
		return -ENODEV;

	port->membase = devm_ioremap(&pdev->dev, res->start,
				     resource_size(res));
	if (!port->membase)
		return -ENOMEM;

	port->mapbase = res->start;
	port->mapsize = resource_size(res);

	uart->rst = devm_reset_control_get_optional_shared(&pdev->dev, NULL);
	if (IS_ERR(uart->rst))
		return PTR_ERR(uart->rst);

	if (device_property_read_u32(&pdev->dev, "clock-frequency",
				     &port->uartclk)) {
		uart->clk = devm_clk_get(&pdev->dev, NULL);
		if (IS_ERR(uart->clk)) {
			dev_err(&pdev->dev, "failed to get clock!\n");
			return -ENODEV;
		}

		ret = clk_prepare_enable(uart->clk);
		if (ret < 0)
			return ret;

		port->uartclk = clk_get_rate(uart->clk);
	}

	ret = reset_control_deassert(uart->rst);
	if (ret)
		goto err_clkdisable;

	ret = serial8250_register_8250_port(&port8250);
	if (ret < 0)
		goto err_clkdisable;

	platform_set_drvdata(pdev, uart);
	uart->line = ret;

	return 0;

err_clkdisable:
	clk_disable_unprepare(uart->clk);

	return ret;
}

static int tegra_uart_remove(struct platform_device *pdev)
{
	struct tegra_uart *uart = platform_get_drvdata(pdev);

	serial8250_unregister_port(uart->line);
	reset_control_assert(uart->rst);
	clk_disable_unprepare(uart->clk);

	return 0;
}

#ifdef CONFIG_PM_SLEEP
static int tegra_uart_suspend(struct device *dev)
{
	struct tegra_uart *uart = dev_get_drvdata(dev);
	struct uart_8250_port *port8250 = serial8250_get_port(uart->line);
	struct uart_port *port = &port8250->port;

	serial8250_suspend_port(uart->line);

	if (!uart_console(port) || console_suspend_enabled)
		clk_disable_unprepare(uart->clk);

	return 0;
}

static int tegra_uart_resume(struct device *dev)
{
	struct tegra_uart *uart = dev_get_drvdata(dev);
	struct uart_8250_port *port8250 = serial8250_get_port(uart->line);
	struct uart_port *port = &port8250->port;

	if (!uart_console(port) || console_suspend_enabled)
		clk_prepare_enable(uart->clk);

	serial8250_resume_port(uart->line);

	return 0;
}
#endif

static SIMPLE_DEV_PM_OPS(tegra_uart_pm_ops, tegra_uart_suspend,
			 tegra_uart_resume);

static const struct of_device_id tegra_uart_of_match[] = {
	{ .compatible = "nvidia,tegra20-uart", },
	{ },
};
MODULE_DEVICE_TABLE(of, tegra_uart_of_match);

static const struct acpi_device_id tegra_uart_acpi_match[] = {
	{ "NVDA0100", 0 },
	{ },
};
MODULE_DEVICE_TABLE(acpi, tegra_uart_acpi_match);

static struct platform_driver tegra_uart_driver = {
	.driver = {
		.name = "tegra-uart",
		.pm = &tegra_uart_pm_ops,
		.of_match_table = tegra_uart_of_match,
		.acpi_match_table = ACPI_PTR(tegra_uart_acpi_match),
	},
	.probe = tegra_uart_probe,
	.remove = tegra_uart_remove,
};

module_platform_driver(tegra_uart_driver);

MODULE_AUTHOR("Jeff Brasen <jbrasen@nvidia.com>");
MODULE_DESCRIPTION("NVIDIA Tegra 8250 Driver");
MODULE_LICENSE("GPL v2");
