/*
 * Copyright (C) 2014 Linaro Ltd.
 * Author: Rob Herring <robh@kernel.org>
 *
 * Based on 8250 earlycon:
 * (c) Copyright 2004 Hewlett-Packard Development Company, L.P.
 *	Bjorn Helgaas <bjorn.helgaas@hp.com>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */
#include <linux/console.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/serial_core.h>
#include <linux/sizes.h>
#include <linux/mod_devicetable.h>

#ifdef CONFIG_FIX_EARLYCON_MEM
#include <asm/fixmap.h>
#endif

#include <asm/serial.h>

static struct console early_con = {
	.name =		"uart", /* 8250 console switch requires this name */
	.flags =	CON_PRINTBUFFER | CON_BOOT,
	.index =	-1,
};

static struct earlycon_device early_console_dev = {
	.con = &early_con,
};

static const struct of_device_id __earlycon_of_table_sentinel
	__used __section(__earlycon_of_table_end);

static void __iomem * __init earlycon_map(unsigned long paddr, size_t size)
{
	void __iomem *base;
#ifdef CONFIG_FIX_EARLYCON_MEM
	set_fixmap_io(FIX_EARLYCON_MEM_BASE, paddr & PAGE_MASK);
	base = (void __iomem *)__fix_to_virt(FIX_EARLYCON_MEM_BASE);
	base += paddr & ~PAGE_MASK;
#else
	base = ioremap(paddr, size);
#endif
	if (!base)
		pr_err("%s: Couldn't map 0x%llx\n", __func__,
		       (unsigned long long)paddr);

	return base;
}

static int __init parse_options(struct earlycon_device *device,
				char *options)
{
	struct uart_port *port = &device->port;
	int mmio, mmio32, length;
	unsigned long addr;

	if (!options)
		return -ENODEV;

	mmio = !strncmp(options, "mmio,", 5);
	mmio32 = !strncmp(options, "mmio32,", 7);
	if (mmio || mmio32) {
		port->iotype = (mmio ? UPIO_MEM : UPIO_MEM32);
		options += mmio ? 5 : 7;
		addr = simple_strtoul(options, NULL, 0);
		port->mapbase = addr;
		if (mmio32)
			port->regshift = 2;
	} else if (!strncmp(options, "io,", 3)) {
		port->iotype = UPIO_PORT;
		options += 3;
		addr = simple_strtoul(options, NULL, 0);
		port->iobase = addr;
		mmio = 0;
	} else if (!strncmp(options, "0x", 2)) {
		port->iotype = UPIO_MEM;
		addr = simple_strtoul(options, NULL, 0);
		port->mapbase = addr;
	} else {
		return -EINVAL;
	}

	port->uartclk = BASE_BAUD * 16;

	options = strchr(options, ',');
	if (options) {
		options++;
		device->baud = simple_strtoul(options, NULL, 0);
		length = min(strcspn(options, " ") + 1,
			     (size_t)(sizeof(device->options)));
		strlcpy(device->options, options, length);
	}

	if (port->iotype == UPIO_MEM || port->iotype == UPIO_MEM32)
		pr_info("Early serial console at MMIO%s 0x%llx (options '%s')\n",
			mmio32 ? "32" : "",
			(unsigned long long)port->mapbase,
			device->options);
	else
		pr_info("Early serial console at I/O port 0x%lx (options '%s')\n",
			port->iobase,
			device->options);

	return 0;
}

int __init setup_earlycon(char *buf, const char *match,
			  int (*setup)(struct earlycon_device *, const char *))
{
	int err;
	size_t len;
	struct uart_port *port = &early_console_dev.port;

	if (!buf || !match || !setup)
		return 0;

	len = strlen(match);
	if (strncmp(buf, match, len))
		return 0;
	if (buf[len] && (buf[len] != ','))
		return 0;

	buf += len + 1;

	err = parse_options(&early_console_dev, buf);
	/* On parsing error, pass the options buf to the setup function */
	if (!err)
		buf = NULL;

	if (port->mapbase)
		port->membase = earlycon_map(port->mapbase, 64);

	early_console_dev.con->data = &early_console_dev;
	err = setup(&early_console_dev, buf);
	if (err < 0)
		return err;
	if (!early_console_dev.con->write)
		return -ENODEV;

	register_console(early_console_dev.con);
	return 0;
}

int __init of_setup_earlycon(unsigned long addr,
			     int (*setup)(struct earlycon_device *, const char *))
{
	int err;
	struct uart_port *port = &early_console_dev.port;

	port->iotype = UPIO_MEM;
	port->mapbase = addr;
	port->uartclk = BASE_BAUD * 16;
	port->membase = earlycon_map(addr, SZ_4K);

	early_console_dev.con->data = &early_console_dev;
	err = setup(&early_console_dev, NULL);
	if (err < 0)
		return err;
	if (!early_console_dev.con->write)
		return -ENODEV;


	register_console(early_console_dev.con);
	return 0;
}
