// SPDX-License-Identifier: GPL-2.0
/*
 * MPS2 UART driver
 *
 * Copyright (C) 2015 ARM Limited
 *
 * Author: Vladimir Murzin <vladimir.murzin@arm.com>
 *
 * TODO: support for SysRq
 */

#define pr_fmt(fmt)	KBUILD_MODNAME ": " fmt

#include <linux/bitops.h>
#include <linux/clk.h>
#include <linux/console.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/of_device.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/serial_core.h>
#include <linux/tty_flip.h>
#include <linux/types.h>

#define SERIAL_NAME	"ttyMPS"
#define DRIVER_NAME	"mps2-uart"
#define MAKE_NAME(x)	(DRIVER_NAME # x)

#define UARTn_DATA				0x00

#define UARTn_STATE				0x04
#define UARTn_STATE_TX_FULL			BIT(0)
#define UARTn_STATE_RX_FULL			BIT(1)
#define UARTn_STATE_TX_OVERRUN			BIT(2)
#define UARTn_STATE_RX_OVERRUN			BIT(3)

#define UARTn_CTRL				0x08
#define UARTn_CTRL_TX_ENABLE			BIT(0)
#define UARTn_CTRL_RX_ENABLE			BIT(1)
#define UARTn_CTRL_TX_INT_ENABLE		BIT(2)
#define UARTn_CTRL_RX_INT_ENABLE		BIT(3)
#define UARTn_CTRL_TX_OVERRUN_INT_ENABLE	BIT(4)
#define UARTn_CTRL_RX_OVERRUN_INT_ENABLE	BIT(5)

#define UARTn_INT				0x0c
#define UARTn_INT_TX				BIT(0)
#define UARTn_INT_RX				BIT(1)
#define UARTn_INT_TX_OVERRUN			BIT(2)
#define UARTn_INT_RX_OVERRUN			BIT(3)

#define UARTn_BAUDDIV				0x10
#define UARTn_BAUDDIV_MASK			GENMASK(20, 0)

/*
 * Helpers to make typical enable/disable operations more readable.
 */
#define UARTn_CTRL_TX_GRP	(UARTn_CTRL_TX_ENABLE		 |\
				 UARTn_CTRL_TX_INT_ENABLE	 |\
				 UARTn_CTRL_TX_OVERRUN_INT_ENABLE)

#define UARTn_CTRL_RX_GRP	(UARTn_CTRL_RX_ENABLE		 |\
				 UARTn_CTRL_RX_INT_ENABLE	 |\
				 UARTn_CTRL_RX_OVERRUN_INT_ENABLE)

#define MPS2_MAX_PORTS		3

struct mps2_uart_port {
	struct uart_port port;
	struct clk *clk;
	unsigned int tx_irq;
	unsigned int rx_irq;
};

static inline struct mps2_uart_port *to_mps2_port(struct uart_port *port)
{
	return container_of(port, struct mps2_uart_port, port);
}

static void mps2_uart_write8(struct uart_port *port, u8 val, unsigned int off)
{
	struct mps2_uart_port *mps_port = to_mps2_port(port);

	writeb(val, mps_port->port.membase + off);
}

static u8 mps2_uart_read8(struct uart_port *port, unsigned int off)
{
	struct mps2_uart_port *mps_port = to_mps2_port(port);

	return readb(mps_port->port.membase + off);
}

static void mps2_uart_write32(struct uart_port *port, u32 val, unsigned int off)
{
	struct mps2_uart_port *mps_port = to_mps2_port(port);

	writel_relaxed(val, mps_port->port.membase + off);
}

static unsigned int mps2_uart_tx_empty(struct uart_port *port)
{
	u8 status = mps2_uart_read8(port, UARTn_STATE);

	return (status & UARTn_STATE_TX_FULL) ? 0 : TIOCSER_TEMT;
}

static void mps2_uart_set_mctrl(struct uart_port *port, unsigned int mctrl)
{
}

static unsigned int mps2_uart_get_mctrl(struct uart_port *port)
{
	return TIOCM_CAR | TIOCM_CTS | TIOCM_DSR;
}

static void mps2_uart_stop_tx(struct uart_port *port)
{
	u8 control = mps2_uart_read8(port, UARTn_CTRL);

	control &= ~UARTn_CTRL_TX_INT_ENABLE;

	mps2_uart_write8(port, control, UARTn_CTRL);
}

static void mps2_uart_tx_chars(struct uart_port *port)
{
	struct circ_buf *xmit = &port->state->xmit;

	while (!(mps2_uart_read8(port, UARTn_STATE) & UARTn_STATE_TX_FULL)) {
		if (port->x_char) {
			mps2_uart_write8(port, port->x_char, UARTn_DATA);
			port->x_char = 0;
			port->icount.tx++;
			continue;
		}

		if (uart_circ_empty(xmit) || uart_tx_stopped(port))
			break;

		mps2_uart_write8(port, xmit->buf[xmit->tail], UARTn_DATA);
		xmit->tail = (xmit->tail + 1) % UART_XMIT_SIZE;
		port->icount.tx++;
	}

	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
		uart_write_wakeup(port);

	if (uart_circ_empty(xmit))
		mps2_uart_stop_tx(port);
}

static void mps2_uart_start_tx(struct uart_port *port)
{
	u8 control = mps2_uart_read8(port, UARTn_CTRL);

	control |= UARTn_CTRL_TX_INT_ENABLE;

	mps2_uart_write8(port, control, UARTn_CTRL);

	/*
	 * We've just unmasked the TX IRQ and now slow-starting via
	 * polling; if there is enough data to fill up the internal
	 * write buffer in one go, the TX IRQ should assert, at which
	 * point we switch to fully interrupt-driven TX.
	 */

	mps2_uart_tx_chars(port);
}

static void mps2_uart_stop_rx(struct uart_port *port)
{
	u8 control = mps2_uart_read8(port, UARTn_CTRL);

	control &= ~UARTn_CTRL_RX_GRP;

	mps2_uart_write8(port, control, UARTn_CTRL);
}

static void mps2_uart_break_ctl(struct uart_port *port, int ctl)
{
}

static void mps2_uart_rx_chars(struct uart_port *port)
{
	struct tty_port *tport = &port->state->port;

	while (mps2_uart_read8(port, UARTn_STATE) & UARTn_STATE_RX_FULL) {
		u8 rxdata = mps2_uart_read8(port, UARTn_DATA);

		port->icount.rx++;
		tty_insert_flip_char(&port->state->port, rxdata, TTY_NORMAL);
	}

	tty_flip_buffer_push(tport);
}

static irqreturn_t mps2_uart_rxirq(int irq, void *data)
{
	struct uart_port *port = data;
	u8 irqflag = mps2_uart_read8(port, UARTn_INT);

	if (unlikely(!(irqflag & UARTn_INT_RX)))
		return IRQ_NONE;

	spin_lock(&port->lock);

	mps2_uart_write8(port, UARTn_INT_RX, UARTn_INT);
	mps2_uart_rx_chars(port);

	spin_unlock(&port->lock);

	return IRQ_HANDLED;
}

static irqreturn_t mps2_uart_txirq(int irq, void *data)
{
	struct uart_port *port = data;
	u8 irqflag = mps2_uart_read8(port, UARTn_INT);

	if (unlikely(!(irqflag & UARTn_INT_TX)))
		return IRQ_NONE;

	spin_lock(&port->lock);

	mps2_uart_write8(port, UARTn_INT_TX, UARTn_INT);
	mps2_uart_tx_chars(port);

	spin_unlock(&port->lock);

	return IRQ_HANDLED;
}

static irqreturn_t mps2_uart_oerrirq(int irq, void *data)
{
	irqreturn_t handled = IRQ_NONE;
	struct uart_port *port = data;
	u8 irqflag = mps2_uart_read8(port, UARTn_INT);

	spin_lock(&port->lock);

	if (irqflag & UARTn_INT_RX_OVERRUN) {
		struct tty_port *tport = &port->state->port;

		mps2_uart_write8(port, UARTn_INT_RX_OVERRUN, UARTn_INT);
		port->icount.overrun++;
		tty_insert_flip_char(tport, 0, TTY_OVERRUN);
		tty_flip_buffer_push(tport);
		handled = IRQ_HANDLED;
	}

	/*
	 * It's never been seen in practice and it never *should* happen since
	 * we check if there is enough room in TX buffer before sending data.
	 * So we keep this check in case something suspicious has happened.
	 */
	if (irqflag & UARTn_INT_TX_OVERRUN) {
		mps2_uart_write8(port, UARTn_INT_TX_OVERRUN, UARTn_INT);
		handled = IRQ_HANDLED;
	}

	spin_unlock(&port->lock);

	return handled;
}

static int mps2_uart_startup(struct uart_port *port)
{
	struct mps2_uart_port *mps_port = to_mps2_port(port);
	u8 control = mps2_uart_read8(port, UARTn_CTRL);
	int ret;

	control &= ~(UARTn_CTRL_RX_GRP | UARTn_CTRL_TX_GRP);

	mps2_uart_write8(port, control, UARTn_CTRL);

	ret = request_irq(mps_port->rx_irq, mps2_uart_rxirq, 0,
			  MAKE_NAME(-rx), mps_port);
	if (ret) {
		dev_err(port->dev, "failed to register rxirq (%d)\n", ret);
		return ret;
	}

	ret = request_irq(mps_port->tx_irq, mps2_uart_txirq, 0,
			  MAKE_NAME(-tx), mps_port);
	if (ret) {
		dev_err(port->dev, "failed to register txirq (%d)\n", ret);
		goto err_free_rxirq;
	}

	ret = request_irq(port->irq, mps2_uart_oerrirq, IRQF_SHARED,
			  MAKE_NAME(-overrun), mps_port);

	if (ret) {
		dev_err(port->dev, "failed to register oerrirq (%d)\n", ret);
		goto err_free_txirq;
	}

	control |= UARTn_CTRL_RX_GRP | UARTn_CTRL_TX_GRP;

	mps2_uart_write8(port, control, UARTn_CTRL);

	return 0;

err_free_txirq:
	free_irq(mps_port->tx_irq, mps_port);
err_free_rxirq:
	free_irq(mps_port->rx_irq, mps_port);

	return ret;
}

static void mps2_uart_shutdown(struct uart_port *port)
{
	struct mps2_uart_port *mps_port = to_mps2_port(port);
	u8 control = mps2_uart_read8(port, UARTn_CTRL);

	control &= ~(UARTn_CTRL_RX_GRP | UARTn_CTRL_TX_GRP);

	mps2_uart_write8(port, control, UARTn_CTRL);

	free_irq(mps_port->rx_irq, mps_port);
	free_irq(mps_port->tx_irq, mps_port);
	free_irq(port->irq, mps_port);
}

static void
mps2_uart_set_termios(struct uart_port *port, struct ktermios *termios,
		      struct ktermios *old)
{
	unsigned long flags;
	unsigned int baud, bauddiv;

	termios->c_cflag &= ~(CRTSCTS | CMSPAR);
	termios->c_cflag &= ~CSIZE;
	termios->c_cflag |= CS8;
	termios->c_cflag &= ~PARENB;
	termios->c_cflag &= ~CSTOPB;

	baud = uart_get_baud_rate(port, termios, old,
			DIV_ROUND_CLOSEST(port->uartclk, UARTn_BAUDDIV_MASK),
			DIV_ROUND_CLOSEST(port->uartclk, 16));

	bauddiv = DIV_ROUND_CLOSEST(port->uartclk, baud);

	spin_lock_irqsave(&port->lock, flags);

	uart_update_timeout(port, termios->c_cflag, baud);
	mps2_uart_write32(port, bauddiv, UARTn_BAUDDIV);

	spin_unlock_irqrestore(&port->lock, flags);

	if (tty_termios_baud_rate(termios))
		tty_termios_encode_baud_rate(termios, baud, baud);
}

static const char *mps2_uart_type(struct uart_port *port)
{
	return (port->type == PORT_MPS2UART) ? DRIVER_NAME : NULL;
}

static void mps2_uart_release_port(struct uart_port *port)
{
}

static int mps2_uart_request_port(struct uart_port *port)
{
	return 0;
}

static void mps2_uart_config_port(struct uart_port *port, int type)
{
	if (type & UART_CONFIG_TYPE && !mps2_uart_request_port(port))
		port->type = PORT_MPS2UART;
}

static int mps2_uart_verify_port(struct uart_port *port, struct serial_struct *serinfo)
{
	return -EINVAL;
}

static const struct uart_ops mps2_uart_pops = {
	.tx_empty = mps2_uart_tx_empty,
	.set_mctrl = mps2_uart_set_mctrl,
	.get_mctrl = mps2_uart_get_mctrl,
	.stop_tx = mps2_uart_stop_tx,
	.start_tx = mps2_uart_start_tx,
	.stop_rx = mps2_uart_stop_rx,
	.break_ctl = mps2_uart_break_ctl,
	.startup = mps2_uart_startup,
	.shutdown = mps2_uart_shutdown,
	.set_termios = mps2_uart_set_termios,
	.type = mps2_uart_type,
	.release_port = mps2_uart_release_port,
	.request_port = mps2_uart_request_port,
	.config_port = mps2_uart_config_port,
	.verify_port = mps2_uart_verify_port,
};

static struct mps2_uart_port mps2_uart_ports[MPS2_MAX_PORTS];

#ifdef CONFIG_SERIAL_MPS2_UART_CONSOLE
static void mps2_uart_console_putchar(struct uart_port *port, int ch)
{
	while (mps2_uart_read8(port, UARTn_STATE) & UARTn_STATE_TX_FULL)
		cpu_relax();

	mps2_uart_write8(port, ch, UARTn_DATA);
}

static void mps2_uart_console_write(struct console *co, const char *s, unsigned int cnt)
{
	struct uart_port *port = &mps2_uart_ports[co->index].port;

	uart_console_write(port, s, cnt, mps2_uart_console_putchar);
}

static int mps2_uart_console_setup(struct console *co, char *options)
{
	struct mps2_uart_port *mps_port;
	int baud = 9600;
	int bits = 8;
	int parity = 'n';
	int flow = 'n';

	if (co->index < 0 || co->index >= MPS2_MAX_PORTS)
		return -ENODEV;

	mps_port = &mps2_uart_ports[co->index];

	if (options)
		uart_parse_options(options, &baud, &parity, &bits, &flow);

	return uart_set_options(&mps_port->port, co, baud, parity, bits, flow);
}

static struct uart_driver mps2_uart_driver;

static struct console mps2_uart_console = {
	.name = SERIAL_NAME,
	.device = uart_console_device,
	.write = mps2_uart_console_write,
	.setup = mps2_uart_console_setup,
	.flags = CON_PRINTBUFFER,
	.index = -1,
	.data = &mps2_uart_driver,
};

#define MPS2_SERIAL_CONSOLE (&mps2_uart_console)

static void mps2_early_putchar(struct uart_port *port, int ch)
{
	while (readb(port->membase + UARTn_STATE) & UARTn_STATE_TX_FULL)
		cpu_relax();

	writeb((unsigned char)ch, port->membase + UARTn_DATA);
}

static void mps2_early_write(struct console *con, const char *s, unsigned int n)
{
	struct earlycon_device *dev = con->data;

	uart_console_write(&dev->port, s, n, mps2_early_putchar);
}

static int __init mps2_early_console_setup(struct earlycon_device *device,
					   const char *opt)
{
	if (!device->port.membase)
		return -ENODEV;

	device->con->write = mps2_early_write;

	return 0;
}

OF_EARLYCON_DECLARE(mps2, "arm,mps2-uart", mps2_early_console_setup);

#else
#define MPS2_SERIAL_CONSOLE NULL
#endif

static struct uart_driver mps2_uart_driver = {
	.driver_name = DRIVER_NAME,
	.dev_name = SERIAL_NAME,
	.nr = MPS2_MAX_PORTS,
	.cons = MPS2_SERIAL_CONSOLE,
};

static struct mps2_uart_port *mps2_of_get_port(struct platform_device *pdev)
{
	struct device_node *np = pdev->dev.of_node;
	int id;

	if (!np)
		return NULL;

	id = of_alias_get_id(np, "serial");
	if (id < 0)
		id = 0;

	if (WARN_ON(id >= MPS2_MAX_PORTS))
		return NULL;

	mps2_uart_ports[id].port.line = id;
	return &mps2_uart_ports[id];
}

static int mps2_init_port(struct mps2_uart_port *mps_port,
			  struct platform_device *pdev)
{
	struct resource *res;
	int ret;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	mps_port->port.membase = devm_ioremap_resource(&pdev->dev, res);
	if (IS_ERR(mps_port->port.membase))
		return PTR_ERR(mps_port->port.membase);

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

	mps_port->rx_irq = platform_get_irq(pdev, 0);
	mps_port->tx_irq = platform_get_irq(pdev, 1);
	mps_port->port.irq = platform_get_irq(pdev, 2);

	mps_port->port.iotype = UPIO_MEM;
	mps_port->port.flags = UPF_BOOT_AUTOCONF;
	mps_port->port.fifosize = 1;
	mps_port->port.ops = &mps2_uart_pops;
	mps_port->port.dev = &pdev->dev;

	mps_port->clk = devm_clk_get(&pdev->dev, NULL);
	if (IS_ERR(mps_port->clk))
		return PTR_ERR(mps_port->clk);

	ret = clk_prepare_enable(mps_port->clk);
	if (ret)
		return ret;

	mps_port->port.uartclk = clk_get_rate(mps_port->clk);

	clk_disable_unprepare(mps_port->clk);

	return ret;
}

static int mps2_serial_probe(struct platform_device *pdev)
{
	struct mps2_uart_port *mps_port;
	int ret;

	mps_port = mps2_of_get_port(pdev);
	if (!mps_port)
		return -ENODEV;

	ret = mps2_init_port(mps_port, pdev);
	if (ret)
		return ret;

	ret = uart_add_one_port(&mps2_uart_driver, &mps_port->port);
	if (ret)
		return ret;

	platform_set_drvdata(pdev, mps_port);

	return 0;
}

#ifdef CONFIG_OF
static const struct of_device_id mps2_match[] = {
	{ .compatible = "arm,mps2-uart", },
	{},
};
#endif

static struct platform_driver mps2_serial_driver = {
	.probe = mps2_serial_probe,

	.driver = {
		.name = DRIVER_NAME,
		.of_match_table = of_match_ptr(mps2_match),
		.suppress_bind_attrs = true,
	},
};

static int __init mps2_uart_init(void)
{
	int ret;

	ret = uart_register_driver(&mps2_uart_driver);
	if (ret)
		return ret;

	ret = platform_driver_register(&mps2_serial_driver);
	if (ret)
		uart_unregister_driver(&mps2_uart_driver);

	return ret;
}
arch_initcall(mps2_uart_init);
