/*
 * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

#include <linux/clk.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>

#include "8250.h"

/* Most (but not all) of UniPhier UART devices have 64-depth FIFO. */
#define UNIPHIER_UART_DEFAULT_FIFO_SIZE	64

#define UNIPHIER_UART_CHAR_FCR	3	/* Character / FIFO Control Register */
#define UNIPHIER_UART_LCR_MCR	4	/* Line/Modem Control Register */
#define   UNIPHIER_UART_LCR_SHIFT	8
#define UNIPHIER_UART_DLR	9	/* Divisor Latch Register */

struct uniphier8250_priv {
	int line;
	struct clk *clk;
	spinlock_t atomic_write_lock;
};

/*
 * The register map is slightly different from that of 8250.
 * IO callbacks must be overridden for correct access to FCR, LCR, and MCR.
 */
static unsigned int uniphier_serial_in(struct uart_port *p, int offset)
{
	unsigned int valshift = 0;

	switch (offset) {
	case UART_LCR:
		valshift = UNIPHIER_UART_LCR_SHIFT;
		/* fall through */
	case UART_MCR:
		offset = UNIPHIER_UART_LCR_MCR;
		break;
	default:
		break;
	}

	offset <<= p->regshift;

	/*
	 * The return value must be masked with 0xff because LCR and MCR reside
	 * in the same register that must be accessed by 32-bit write/read.
	 * 8 or 16 bit access to this hardware result in unexpected behavior.
	 */
	return (readl(p->membase + offset) >> valshift) & 0xff;
}

static void uniphier_serial_out(struct uart_port *p, int offset, int value)
{
	unsigned int valshift = 0;
	bool normal = false;

	switch (offset) {
	case UART_FCR:
		offset = UNIPHIER_UART_CHAR_FCR;
		break;
	case UART_LCR:
		valshift = UNIPHIER_UART_LCR_SHIFT;
		/* Divisor latch access bit does not exist. */
		value &= ~(UART_LCR_DLAB << valshift);
		/* fall through */
	case UART_MCR:
		offset = UNIPHIER_UART_LCR_MCR;
		break;
	default:
		normal = true;
		break;
	}

	offset <<= p->regshift;

	if (normal) {
		writel(value, p->membase + offset);
	} else {
		/*
		 * Special case: two registers share the same address that
		 * must be 32-bit accessed.  As this is not longer atomic safe,
		 * take a lock just in case.
		 */
		struct uniphier8250_priv *priv = p->private_data;
		unsigned long flags;
		u32 tmp;

		spin_lock_irqsave(&priv->atomic_write_lock, flags);
		tmp = readl(p->membase + offset);
		tmp &= ~(0xff << valshift);
		tmp |= value << valshift;
		writel(tmp, p->membase + offset);
		spin_unlock_irqrestore(&priv->atomic_write_lock, flags);
	}
}

/*
 * This hardware does not have the divisor latch access bit.
 * The divisor latch register exists at different address.
 * Override dl_read/write callbacks.
 */
static int uniphier_serial_dl_read(struct uart_8250_port *up)
{
	int offset = UNIPHIER_UART_DLR << up->port.regshift;

	return readl(up->port.membase + offset);
}

static void uniphier_serial_dl_write(struct uart_8250_port *up, int value)
{
	int offset = UNIPHIER_UART_DLR << up->port.regshift;

	writel(value, up->port.membase + offset);
}

static int uniphier_of_serial_setup(struct device *dev, struct uart_port *port,
				    struct uniphier8250_priv *priv)
{
	int ret;
	u32 prop;
	struct device_node *np = dev->of_node;

	ret = of_alias_get_id(np, "serial");
	if (ret < 0) {
		dev_err(dev, "failed to get alias id\n");
		return ret;
	}
	port->line = priv->line = ret;

	/* Get clk rate through clk driver */
	priv->clk = devm_clk_get(dev, NULL);
	if (IS_ERR(priv->clk)) {
		dev_err(dev, "failed to get clock\n");
		return PTR_ERR(priv->clk);
	}

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

	port->uartclk = clk_get_rate(priv->clk);

	/* Check for fifo size */
	if (of_property_read_u32(np, "fifo-size", &prop) == 0)
		port->fifosize = prop;
	else
		port->fifosize = UNIPHIER_UART_DEFAULT_FIFO_SIZE;

	return 0;
}

static int uniphier_uart_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct uart_8250_port up;
	struct uniphier8250_priv *priv;
	struct resource *regs;
	void __iomem *membase;
	int irq;
	int ret;

	regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!regs) {
		dev_err(dev, "failed to get memory resource");
		return -EINVAL;
	}

	membase = devm_ioremap(dev, regs->start, resource_size(regs));
	if (!membase)
		return -ENOMEM;

	irq = platform_get_irq(pdev, 0);
	if (irq < 0) {
		dev_err(dev, "failed to get IRQ number");
		return irq;
	}

	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
	if (!priv)
		return -ENOMEM;

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

	ret = uniphier_of_serial_setup(dev, &up.port, priv);
	if (ret < 0)
		return ret;

	spin_lock_init(&priv->atomic_write_lock);

	up.port.dev = dev;
	up.port.private_data = priv;
	up.port.mapbase = regs->start;
	up.port.mapsize = resource_size(regs);
	up.port.membase = membase;
	up.port.irq = irq;

	up.port.type = PORT_16550A;
	up.port.iotype = UPIO_MEM32;
	up.port.regshift = 2;
	up.port.flags = UPF_FIXED_PORT | UPF_FIXED_TYPE;
	up.capabilities = UART_CAP_FIFO;

	up.port.serial_in = uniphier_serial_in;
	up.port.serial_out = uniphier_serial_out;
	up.dl_read = uniphier_serial_dl_read;
	up.dl_write = uniphier_serial_dl_write;

	ret = serial8250_register_8250_port(&up);
	if (ret < 0) {
		dev_err(dev, "failed to register 8250 port\n");
		clk_disable_unprepare(priv->clk);
		return ret;
	}

	platform_set_drvdata(pdev, priv);

	return 0;
}

static int uniphier_uart_remove(struct platform_device *pdev)
{
	struct uniphier8250_priv *priv = platform_get_drvdata(pdev);

	serial8250_unregister_port(priv->line);
	clk_disable_unprepare(priv->clk);

	return 0;
}

static const struct of_device_id uniphier_uart_match[] = {
	{ .compatible = "socionext,uniphier-uart" },
	{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, uniphier_uart_match);

static struct platform_driver uniphier_uart_platform_driver = {
	.probe		= uniphier_uart_probe,
	.remove		= uniphier_uart_remove,
	.driver = {
		.name	= "uniphier-uart",
		.of_match_table = uniphier_uart_match,
	},
};
module_platform_driver(uniphier_uart_platform_driver);

MODULE_AUTHOR("Masahiro Yamada <yamada.masahiro@socionext.com>");
MODULE_DESCRIPTION("UniPhier UART driver");
MODULE_LICENSE("GPL");
