/*
 * PIC32 Integrated Serial Driver.
 *
 * Copyright (C) 2015 Microchip Technology, Inc.
 *
 * Authors:
 *   Sorin-Andrei Pistirica <andrei.pistirica@microchip.com>
 *
 * Licensed under GPLv2 or later.
 */

#include <linux/kernel.h>
#include <linux/platform_device.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/of_irq.h>
#include <linux/of_gpio.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/console.h>
#include <linux/clk.h>
#include <linux/tty.h>
#include <linux/tty_flip.h>
#include <linux/serial_core.h>
#include <linux/delay.h>

#include <asm/mach-pic32/pic32.h>
#include "pic32_uart.h"

/* UART name and device definitions */
#define PIC32_DEV_NAME		"pic32-uart"
#define PIC32_MAX_UARTS		6
#define PIC32_SDEV_NAME		"ttyPIC"

/* pic32_sport pointer for console use */
static struct pic32_sport *pic32_sports[PIC32_MAX_UARTS];

static inline void pic32_wait_deplete_txbuf(struct pic32_sport *sport)
{
	/* wait for tx empty, otherwise chars will be lost or corrupted */
	while (!(pic32_uart_readl(sport, PIC32_UART_STA) & PIC32_UART_STA_TRMT))
		udelay(1);
}

static inline int pic32_enable_clock(struct pic32_sport *sport)
{
	int ret = clk_prepare_enable(sport->clk);

	if (ret)
		return ret;

	sport->ref_clk++;
	return 0;
}

static inline void pic32_disable_clock(struct pic32_sport *sport)
{
	sport->ref_clk--;
	clk_disable_unprepare(sport->clk);
}

/* serial core request to check if uart tx buffer is empty */
static unsigned int pic32_uart_tx_empty(struct uart_port *port)
{
	struct pic32_sport *sport = to_pic32_sport(port);
	u32 val = pic32_uart_readl(sport, PIC32_UART_STA);

	return (val & PIC32_UART_STA_TRMT) ? 1 : 0;
}

/* serial core request to set UART outputs */
static void pic32_uart_set_mctrl(struct uart_port *port, unsigned int mctrl)
{
	struct pic32_sport *sport = to_pic32_sport(port);

	/* set loopback mode */
	if (mctrl & TIOCM_LOOP)
		pic32_uart_writel(sport, PIC32_SET(PIC32_UART_MODE),
					PIC32_UART_MODE_LPBK);
	else
		pic32_uart_writel(sport, PIC32_CLR(PIC32_UART_MODE),
					PIC32_UART_MODE_LPBK);
}

/* get the state of CTS input pin for this port */
static unsigned int get_cts_state(struct pic32_sport *sport)
{
	/* read and invert UxCTS */
	if (gpio_is_valid(sport->cts_gpio))
		return !gpio_get_value(sport->cts_gpio);

	return 1;
}

/* serial core request to return the state of misc UART input pins */
static unsigned int pic32_uart_get_mctrl(struct uart_port *port)
{
	struct pic32_sport *sport = to_pic32_sport(port);
	unsigned int mctrl = 0;

	if (!sport->hw_flow_ctrl)
		mctrl |= TIOCM_CTS;
	else if (get_cts_state(sport))
		mctrl |= TIOCM_CTS;

	/* DSR and CD are not supported in PIC32, so return 1
	 * RI is not supported in PIC32, so return 0
	 */
	mctrl |= TIOCM_CD;
	mctrl |= TIOCM_DSR;

	return mctrl;
}

/* stop tx and start tx are not called in pairs, therefore a flag indicates
 * the status of irq to control the irq-depth.
 */
static inline void pic32_uart_irqtxen(struct pic32_sport *sport, u8 en)
{
	if (en && !tx_irq_enabled(sport)) {
		enable_irq(sport->irq_tx);
		tx_irq_enabled(sport) = 1;
	} else if (!en && tx_irq_enabled(sport)) {
		/* use disable_irq_nosync() and not disable_irq() to avoid self
		 * imposed deadlock by not waiting for irq handler to end,
		 * since this callback is called from interrupt context.
		 */
		disable_irq_nosync(sport->irq_tx);
		tx_irq_enabled(sport) = 0;
	}
}

/* serial core request to disable tx ASAP (used for flow control) */
static void pic32_uart_stop_tx(struct uart_port *port)
{
	struct pic32_sport *sport = to_pic32_sport(port);

	if (!(pic32_uart_readl(sport, PIC32_UART_MODE) & PIC32_UART_MODE_ON))
		return;

	if (!(pic32_uart_readl(sport, PIC32_UART_STA) & PIC32_UART_STA_UTXEN))
		return;

	/* wait for tx empty */
	pic32_wait_deplete_txbuf(sport);

	pic32_uart_writel(sport, PIC32_CLR(PIC32_UART_STA),
				PIC32_UART_STA_UTXEN);
	pic32_uart_irqtxen(sport, 0);
}

/* serial core request to (re)enable tx */
static void pic32_uart_start_tx(struct uart_port *port)
{
	struct pic32_sport *sport = to_pic32_sport(port);

	pic32_uart_irqtxen(sport, 1);
	pic32_uart_writel(sport, PIC32_SET(PIC32_UART_STA),
				PIC32_UART_STA_UTXEN);
}

/* serial core request to stop rx, called before port shutdown */
static void pic32_uart_stop_rx(struct uart_port *port)
{
	struct pic32_sport *sport = to_pic32_sport(port);

	/* disable rx interrupts */
	disable_irq(sport->irq_rx);

	/* receiver Enable bit OFF */
	pic32_uart_writel(sport, PIC32_CLR(PIC32_UART_STA),
				PIC32_UART_STA_URXEN);
}

/* serial core request to start/stop emitting break char */
static void pic32_uart_break_ctl(struct uart_port *port, int ctl)
{
	struct pic32_sport *sport = to_pic32_sport(port);
	unsigned long flags;

	spin_lock_irqsave(&port->lock, flags);

	if (ctl)
		pic32_uart_writel(sport, PIC32_SET(PIC32_UART_STA),
					PIC32_UART_STA_UTXBRK);
	else
		pic32_uart_writel(sport, PIC32_CLR(PIC32_UART_STA),
					PIC32_UART_STA_UTXBRK);

	spin_unlock_irqrestore(&port->lock, flags);
}

/* get port type in string format */
static const char *pic32_uart_type(struct uart_port *port)
{
	return (port->type == PORT_PIC32) ? PIC32_DEV_NAME : NULL;
}

/* read all chars in rx fifo and send them to core */
static void pic32_uart_do_rx(struct uart_port *port)
{
	struct pic32_sport *sport = to_pic32_sport(port);
	struct tty_port *tty;
	unsigned int max_count;

	/* limit number of char read in interrupt, should not be
	 * higher than fifo size anyway since we're much faster than
	 * serial port
	 */
	max_count = PIC32_UART_RX_FIFO_DEPTH;

	spin_lock(&port->lock);

	tty = &port->state->port;

	do {
		u32 sta_reg, c;
		char flag;

		/* get overrun/fifo empty information from status register */
		sta_reg = pic32_uart_readl(sport, PIC32_UART_STA);
		if (unlikely(sta_reg & PIC32_UART_STA_OERR)) {

			/* fifo reset is required to clear interrupt */
			pic32_uart_writel(sport, PIC32_CLR(PIC32_UART_STA),
						PIC32_UART_STA_OERR);

			port->icount.overrun++;
			tty_insert_flip_char(tty, 0, TTY_OVERRUN);
		}

		/* Can at least one more character can be read? */
		if (!(sta_reg & PIC32_UART_STA_URXDA))
			break;

		/* read the character and increment the rx counter */
		c = pic32_uart_readl(sport, PIC32_UART_RX);

		port->icount.rx++;
		flag = TTY_NORMAL;
		c &= 0xff;

		if (unlikely((sta_reg & PIC32_UART_STA_PERR) ||
			     (sta_reg & PIC32_UART_STA_FERR))) {

			/* do stats first */
			if (sta_reg & PIC32_UART_STA_PERR)
				port->icount.parity++;
			if (sta_reg & PIC32_UART_STA_FERR)
				port->icount.frame++;

			/* update flag wrt read_status_mask */
			sta_reg &= port->read_status_mask;

			if (sta_reg & PIC32_UART_STA_FERR)
				flag = TTY_FRAME;
			if (sta_reg & PIC32_UART_STA_PERR)
				flag = TTY_PARITY;
		}

		if (uart_handle_sysrq_char(port, c))
			continue;

		if ((sta_reg & port->ignore_status_mask) == 0)
			tty_insert_flip_char(tty, c, flag);

	} while (--max_count);

	spin_unlock(&port->lock);

	tty_flip_buffer_push(tty);
}

/* fill tx fifo with chars to send, stop when fifo is about to be full
 * or when all chars have been sent.
 */
static void pic32_uart_do_tx(struct uart_port *port)
{
	struct pic32_sport *sport = to_pic32_sport(port);
	struct circ_buf *xmit = &port->state->xmit;
	unsigned int max_count = PIC32_UART_TX_FIFO_DEPTH;

	if (port->x_char) {
		pic32_uart_writel(sport, PIC32_UART_TX, port->x_char);
		port->icount.tx++;
		port->x_char = 0;
		return;
	}

	if (uart_tx_stopped(port)) {
		pic32_uart_stop_tx(port);
		return;
	}

	if (uart_circ_empty(xmit))
		goto txq_empty;

	/* keep stuffing chars into uart tx buffer
	 * 1) until uart fifo is full
	 * or
	 * 2) until the circ buffer is empty
	 * (all chars have been sent)
	 * or
	 * 3) until the max count is reached
	 * (prevents lingering here for too long in certain cases)
	 */
	while (!(PIC32_UART_STA_UTXBF &
		pic32_uart_readl(sport, PIC32_UART_STA))) {
		unsigned int c = xmit->buf[xmit->tail];

		pic32_uart_writel(sport, PIC32_UART_TX, c);

		xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
		port->icount.tx++;
		if (uart_circ_empty(xmit))
			break;
		if (--max_count == 0)
			break;
	}

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

	if (uart_circ_empty(xmit))
		goto txq_empty;

	return;

txq_empty:
	pic32_uart_irqtxen(sport, 0);
}

/* RX interrupt handler */
static irqreturn_t pic32_uart_rx_interrupt(int irq, void *dev_id)
{
	struct uart_port *port = dev_id;

	pic32_uart_do_rx(port);

	return IRQ_HANDLED;
}

/* TX interrupt handler */
static irqreturn_t pic32_uart_tx_interrupt(int irq, void *dev_id)
{
	struct uart_port *port = dev_id;
	unsigned long flags;

	spin_lock_irqsave(&port->lock, flags);
	pic32_uart_do_tx(port);
	spin_unlock_irqrestore(&port->lock, flags);

	return IRQ_HANDLED;
}

/* FAULT interrupt handler */
static irqreturn_t pic32_uart_fault_interrupt(int irq, void *dev_id)
{
	/* do nothing: pic32_uart_do_rx() handles faults. */
	return IRQ_HANDLED;
}

/* enable rx & tx operation on uart */
static void pic32_uart_en_and_unmask(struct uart_port *port)
{
	struct pic32_sport *sport = to_pic32_sport(port);

	pic32_uart_writel(sport, PIC32_SET(PIC32_UART_STA),
				PIC32_UART_STA_UTXEN | PIC32_UART_STA_URXEN);
	pic32_uart_writel(sport, PIC32_SET(PIC32_UART_MODE),
				PIC32_UART_MODE_ON);
}

/* disable rx & tx operation on uart */
static void pic32_uart_dsbl_and_mask(struct uart_port *port)
{
	struct pic32_sport *sport = to_pic32_sport(port);

	/* wait for tx empty, otherwise chars will be lost or corrupted */
	pic32_wait_deplete_txbuf(sport);

	pic32_uart_writel(sport, PIC32_CLR(PIC32_UART_STA),
				PIC32_UART_STA_UTXEN | PIC32_UART_STA_URXEN);
	pic32_uart_writel(sport, PIC32_CLR(PIC32_UART_MODE),
				PIC32_UART_MODE_ON);
}

/* serial core request to initialize uart and start rx operation */
static int pic32_uart_startup(struct uart_port *port)
{
	struct pic32_sport *sport = to_pic32_sport(port);
	u32 dflt_baud = (port->uartclk / PIC32_UART_DFLT_BRATE / 16) - 1;
	unsigned long flags;
	int ret;

	local_irq_save(flags);

	ret = pic32_enable_clock(sport);
	if (ret) {
		local_irq_restore(flags);
		goto out_done;
	}

	/* clear status and mode registers */
	pic32_uart_writel(sport, PIC32_UART_MODE, 0);
	pic32_uart_writel(sport, PIC32_UART_STA, 0);

	/* disable uart and mask all interrupts */
	pic32_uart_dsbl_and_mask(port);

	/* set default baud */
	pic32_uart_writel(sport, PIC32_UART_BRG, dflt_baud);

	local_irq_restore(flags);

	/* Each UART of a PIC32 has three interrupts therefore,
	 * we setup driver to register the 3 irqs for the device.
	 *
	 * For each irq request_irq() is called with interrupt disabled.
	 * And the irq is enabled as soon as we are ready to handle them.
	 */
	tx_irq_enabled(sport) = 0;

	sport->irq_fault_name = kasprintf(GFP_KERNEL, "%s%d-fault",
					  pic32_uart_type(port),
					  sport->idx);
	if (!sport->irq_fault_name) {
		dev_err(port->dev, "%s: kasprintf err!", __func__);
		ret = -ENOMEM;
		goto out_done;
	}
	irq_set_status_flags(sport->irq_fault, IRQ_NOAUTOEN);
	ret = request_irq(sport->irq_fault, pic32_uart_fault_interrupt,
			  sport->irqflags_fault, sport->irq_fault_name, port);
	if (ret) {
		dev_err(port->dev, "%s: request irq(%d) err! ret:%d name:%s\n",
			__func__, sport->irq_fault, ret,
			pic32_uart_type(port));
		goto out_f;
	}

	sport->irq_rx_name = kasprintf(GFP_KERNEL, "%s%d-rx",
				       pic32_uart_type(port),
				       sport->idx);
	if (!sport->irq_rx_name) {
		dev_err(port->dev, "%s: kasprintf err!", __func__);
		kfree(sport->irq_fault_name);
		ret = -ENOMEM;
		goto out_f;
	}
	irq_set_status_flags(sport->irq_rx, IRQ_NOAUTOEN);
	ret = request_irq(sport->irq_rx, pic32_uart_rx_interrupt,
			  sport->irqflags_rx, sport->irq_rx_name, port);
	if (ret) {
		dev_err(port->dev, "%s: request irq(%d) err! ret:%d name:%s\n",
			__func__, sport->irq_rx, ret,
			pic32_uart_type(port));
		goto out_r;
	}

	sport->irq_tx_name = kasprintf(GFP_KERNEL, "%s%d-tx",
				       pic32_uart_type(port),
				       sport->idx);
	if (!sport->irq_tx_name) {
		dev_err(port->dev, "%s: kasprintf err!", __func__);
		ret = -ENOMEM;
		goto out_r;
	}
	irq_set_status_flags(sport->irq_tx, IRQ_NOAUTOEN);
	ret = request_irq(sport->irq_tx, pic32_uart_tx_interrupt,
			  sport->irqflags_tx, sport->irq_tx_name, port);
	if (ret) {
		dev_err(port->dev, "%s: request irq(%d) err! ret:%d name:%s\n",
			__func__, sport->irq_tx, ret,
			pic32_uart_type(port));
		goto out_t;
	}

	local_irq_save(flags);

	/* set rx interrupt on first receive */
	pic32_uart_writel(sport, PIC32_CLR(PIC32_UART_STA),
			PIC32_UART_STA_URXISEL1 | PIC32_UART_STA_URXISEL0);

	/* set interrupt on empty */
	pic32_uart_writel(sport, PIC32_CLR(PIC32_UART_STA),
			PIC32_UART_STA_UTXISEL1);

	/* enable all interrupts and eanable uart */
	pic32_uart_en_and_unmask(port);

	enable_irq(sport->irq_rx);

	return 0;

out_t:
	kfree(sport->irq_tx_name);
	free_irq(sport->irq_tx, sport);
out_r:
	kfree(sport->irq_rx_name);
	free_irq(sport->irq_rx, sport);
out_f:
	kfree(sport->irq_fault_name);
	free_irq(sport->irq_fault, sport);
out_done:
	return ret;
}

/* serial core request to flush & disable uart */
static void pic32_uart_shutdown(struct uart_port *port)
{
	struct pic32_sport *sport = to_pic32_sport(port);
	unsigned long flags;

	/* disable uart */
	spin_lock_irqsave(&port->lock, flags);
	pic32_uart_dsbl_and_mask(port);
	spin_unlock_irqrestore(&port->lock, flags);
	pic32_disable_clock(sport);

	/* free all 3 interrupts for this UART */
	free_irq(sport->irq_fault, port);
	free_irq(sport->irq_tx, port);
	free_irq(sport->irq_rx, port);
}

/* serial core request to change current uart setting */
static void pic32_uart_set_termios(struct uart_port *port,
				   struct ktermios *new,
				   struct ktermios *old)
{
	struct pic32_sport *sport = to_pic32_sport(port);
	unsigned int baud;
	unsigned int quot;
	unsigned long flags;

	spin_lock_irqsave(&port->lock, flags);

	/* disable uart and mask all interrupts while changing speed */
	pic32_uart_dsbl_and_mask(port);

	/* stop bit options */
	if (new->c_cflag & CSTOPB)
		pic32_uart_writel(sport, PIC32_SET(PIC32_UART_MODE),
					PIC32_UART_MODE_STSEL);
	else
		pic32_uart_writel(sport, PIC32_CLR(PIC32_UART_MODE),
					PIC32_UART_MODE_STSEL);

	/* parity options */
	if (new->c_cflag & PARENB) {
		if (new->c_cflag & PARODD) {
			pic32_uart_writel(sport, PIC32_SET(PIC32_UART_MODE),
					PIC32_UART_MODE_PDSEL1);
			pic32_uart_writel(sport, PIC32_CLR(PIC32_UART_MODE),
					PIC32_UART_MODE_PDSEL0);
		} else {
			pic32_uart_writel(sport, PIC32_SET(PIC32_UART_MODE),
					PIC32_UART_MODE_PDSEL0);
			pic32_uart_writel(sport, PIC32_CLR(PIC32_UART_MODE),
					PIC32_UART_MODE_PDSEL1);
		}
	} else {
		pic32_uart_writel(sport, PIC32_CLR(PIC32_UART_MODE),
					PIC32_UART_MODE_PDSEL1 |
					PIC32_UART_MODE_PDSEL0);
	}
	/* if hw flow ctrl, then the pins must be specified in device tree */
	if ((new->c_cflag & CRTSCTS) && sport->hw_flow_ctrl) {
		/* enable hardware flow control */
		pic32_uart_writel(sport, PIC32_SET(PIC32_UART_MODE),
					PIC32_UART_MODE_UEN1);
		pic32_uart_writel(sport, PIC32_CLR(PIC32_UART_MODE),
					PIC32_UART_MODE_UEN0);
		pic32_uart_writel(sport, PIC32_CLR(PIC32_UART_MODE),
					PIC32_UART_MODE_RTSMD);
	} else {
		/* disable hardware flow control */
		pic32_uart_writel(sport, PIC32_CLR(PIC32_UART_MODE),
					PIC32_UART_MODE_UEN1);
		pic32_uart_writel(sport, PIC32_CLR(PIC32_UART_MODE),
					PIC32_UART_MODE_UEN0);
		pic32_uart_writel(sport, PIC32_CLR(PIC32_UART_MODE),
					PIC32_UART_MODE_RTSMD);
	}

	/* Always 8-bit */
	new->c_cflag |= CS8;

	/* Mark/Space parity is not supported */
	new->c_cflag &= ~CMSPAR;

	/* update baud */
	baud = uart_get_baud_rate(port, new, old, 0, port->uartclk / 16);
	quot = uart_get_divisor(port, baud) - 1;
	pic32_uart_writel(sport, PIC32_UART_BRG, quot);
	uart_update_timeout(port, new->c_cflag, baud);

	if (tty_termios_baud_rate(new))
		tty_termios_encode_baud_rate(new, baud, baud);

	/* enable uart */
	pic32_uart_en_and_unmask(port);

	spin_unlock_irqrestore(&port->lock, flags);
}

/* serial core request to claim uart iomem */
static int pic32_uart_request_port(struct uart_port *port)
{
	struct platform_device *pdev = to_platform_device(port->dev);
	struct resource *res_mem;

	res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (unlikely(!res_mem))
		return -EINVAL;

	if (!request_mem_region(port->mapbase, resource_size(res_mem),
				"pic32_uart_mem"))
		return -EBUSY;

	port->membase = devm_ioremap_nocache(port->dev, port->mapbase,
						resource_size(res_mem));
	if (!port->membase) {
		dev_err(port->dev, "Unable to map registers\n");
		release_mem_region(port->mapbase, resource_size(res_mem));
		return -ENOMEM;
	}

	return 0;
}

/* serial core request to release uart iomem */
static void pic32_uart_release_port(struct uart_port *port)
{
	struct platform_device *pdev = to_platform_device(port->dev);
	struct resource *res_mem;
	unsigned int res_size;

	res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (unlikely(!res_mem))
		return;
	res_size = resource_size(res_mem);

	release_mem_region(port->mapbase, res_size);
}

/* serial core request to do any port required auto-configuration */
static void pic32_uart_config_port(struct uart_port *port, int flags)
{
	if (flags & UART_CONFIG_TYPE) {
		if (pic32_uart_request_port(port))
			return;
		port->type = PORT_PIC32;
	}
}

/* serial core request to check that port information in serinfo are suitable */
static int pic32_uart_verify_port(struct uart_port *port,
				  struct serial_struct *serinfo)
{
	if (port->type != PORT_PIC32)
		return -EINVAL;
	if (port->irq != serinfo->irq)
		return -EINVAL;
	if (port->iotype != serinfo->io_type)
		return -EINVAL;
	if (port->mapbase != (unsigned long)serinfo->iomem_base)
		return -EINVAL;

	return 0;
}

/* serial core callbacks */
static const struct uart_ops pic32_uart_ops = {
	.tx_empty	= pic32_uart_tx_empty,
	.get_mctrl	= pic32_uart_get_mctrl,
	.set_mctrl	= pic32_uart_set_mctrl,
	.start_tx	= pic32_uart_start_tx,
	.stop_tx	= pic32_uart_stop_tx,
	.stop_rx	= pic32_uart_stop_rx,
	.break_ctl	= pic32_uart_break_ctl,
	.startup	= pic32_uart_startup,
	.shutdown	= pic32_uart_shutdown,
	.set_termios	= pic32_uart_set_termios,
	.type		= pic32_uart_type,
	.release_port	= pic32_uart_release_port,
	.request_port	= pic32_uart_request_port,
	.config_port	= pic32_uart_config_port,
	.verify_port	= pic32_uart_verify_port,
};

#ifdef CONFIG_SERIAL_PIC32_CONSOLE
/* output given char */
static void pic32_console_putchar(struct uart_port *port, int ch)
{
	struct pic32_sport *sport = to_pic32_sport(port);

	if (!(pic32_uart_readl(sport, PIC32_UART_MODE) & PIC32_UART_MODE_ON))
		return;

	if (!(pic32_uart_readl(sport, PIC32_UART_STA) & PIC32_UART_STA_UTXEN))
		return;

	/* wait for tx empty */
	pic32_wait_deplete_txbuf(sport);

	pic32_uart_writel(sport, PIC32_UART_TX, ch & 0xff);
}

/* console core request to output given string */
static void pic32_console_write(struct console *co, const char *s,
				unsigned int count)
{
	struct pic32_sport *sport = pic32_sports[co->index];
	struct uart_port *port = pic32_get_port(sport);

	/* call uart helper to deal with \r\n */
	uart_console_write(port, s, count, pic32_console_putchar);
}

/* console core request to setup given console, find matching uart
 * port and setup it.
 */
static int pic32_console_setup(struct console *co, char *options)
{
	struct pic32_sport *sport;
	struct uart_port *port = NULL;
	int baud = 115200;
	int bits = 8;
	int parity = 'n';
	int flow = 'n';
	int ret = 0;

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

	sport = pic32_sports[co->index];
	if (!sport)
		return -ENODEV;
	port = pic32_get_port(sport);

	ret = pic32_enable_clock(sport);
	if (ret)
		return ret;

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

	return uart_set_options(port, co, baud, parity, bits, flow);
}

static struct uart_driver pic32_uart_driver;
static struct console pic32_console = {
	.name		= PIC32_SDEV_NAME,
	.write		= pic32_console_write,
	.device		= uart_console_device,
	.setup		= pic32_console_setup,
	.flags		= CON_PRINTBUFFER,
	.index		= -1,
	.data		= &pic32_uart_driver,
};
#define PIC32_SCONSOLE (&pic32_console)

static int __init pic32_console_init(void)
{
	register_console(&pic32_console);
	return 0;
}
console_initcall(pic32_console_init);

static inline bool is_pic32_console_port(struct uart_port *port)
{
	return port->cons && port->cons->index == port->line;
}

/*
 * Late console initialization.
 */
static int __init pic32_late_console_init(void)
{
	if (!(pic32_console.flags & CON_ENABLED))
		register_console(&pic32_console);

	return 0;
}

core_initcall(pic32_late_console_init);

#else
#define PIC32_SCONSOLE NULL
#endif

static struct uart_driver pic32_uart_driver = {
	.owner			= THIS_MODULE,
	.driver_name		= PIC32_DEV_NAME,
	.dev_name		= PIC32_SDEV_NAME,
	.nr			= PIC32_MAX_UARTS,
	.cons			= PIC32_SCONSOLE,
};

static int pic32_uart_probe(struct platform_device *pdev)
{
	struct device_node *np = pdev->dev.of_node;
	struct pic32_sport *sport;
	int uart_idx = 0;
	struct resource *res_mem;
	struct uart_port *port;
	int ret;

	uart_idx = of_alias_get_id(np, "serial");
	if (uart_idx < 0 || uart_idx >= PIC32_MAX_UARTS)
		return -EINVAL;

	res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res_mem)
		return -EINVAL;

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

	sport->idx		= uart_idx;
	sport->irq_fault	= irq_of_parse_and_map(np, 0);
	sport->irqflags_fault	= IRQF_NO_THREAD;
	sport->irq_rx		= irq_of_parse_and_map(np, 1);
	sport->irqflags_rx	= IRQF_NO_THREAD;
	sport->irq_tx		= irq_of_parse_and_map(np, 2);
	sport->irqflags_tx	= IRQF_NO_THREAD;
	sport->clk		= devm_clk_get(&pdev->dev, NULL);
	sport->cts_gpio		= -EINVAL;
	sport->dev		= &pdev->dev;

	/* Hardware flow control: gpios
	 * !Note: Basically, CTS is needed for reading the status.
	 */
	sport->hw_flow_ctrl = false;
	sport->cts_gpio = of_get_named_gpio(np, "cts-gpios", 0);
	if (gpio_is_valid(sport->cts_gpio)) {
		sport->hw_flow_ctrl = true;

		ret = devm_gpio_request(sport->dev,
					sport->cts_gpio, "CTS");
		if (ret) {
			dev_err(&pdev->dev,
				"error requesting CTS GPIO\n");
			goto err;
		}

		ret = gpio_direction_input(sport->cts_gpio);
		if (ret) {
			dev_err(&pdev->dev, "error setting CTS GPIO\n");
			goto err;
		}
	}

	pic32_sports[uart_idx] = sport;
	port = &sport->port;
	memset(port, 0, sizeof(*port));
	port->iotype	= UPIO_MEM;
	port->mapbase	= res_mem->start;
	port->ops	= &pic32_uart_ops;
	port->flags	= UPF_BOOT_AUTOCONF;
	port->dev	= &pdev->dev;
	port->fifosize	= PIC32_UART_TX_FIFO_DEPTH;
	port->uartclk	= clk_get_rate(sport->clk);
	port->line	= uart_idx;

	ret = uart_add_one_port(&pic32_uart_driver, port);
	if (ret) {
		port->membase = NULL;
		dev_err(port->dev, "%s: uart add port error!\n", __func__);
		goto err;
	}

#ifdef CONFIG_SERIAL_PIC32_CONSOLE
	if (is_pic32_console_port(port) &&
	    (pic32_console.flags & CON_ENABLED)) {
		/* The peripheral clock has been enabled by console_setup,
		 * so disable it till the port is used.
		 */
		pic32_disable_clock(sport);
	}
#endif

	platform_set_drvdata(pdev, port);

	dev_info(&pdev->dev, "%s: uart(%d) driver initialized.\n",
		 __func__, uart_idx);

	return 0;
err:
	/* automatic unroll of sport and gpios */
	return ret;
}

static int pic32_uart_remove(struct platform_device *pdev)
{
	struct uart_port *port = platform_get_drvdata(pdev);
	struct pic32_sport *sport = to_pic32_sport(port);

	uart_remove_one_port(&pic32_uart_driver, port);
	pic32_disable_clock(sport);
	platform_set_drvdata(pdev, NULL);
	pic32_sports[sport->idx] = NULL;

	/* automatic unroll of sport and gpios */
	return 0;
}

static const struct of_device_id pic32_serial_dt_ids[] = {
	{ .compatible = "microchip,pic32mzda-uart" },
	{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, pic32_serial_dt_ids);

static struct platform_driver pic32_uart_platform_driver = {
	.probe		= pic32_uart_probe,
	.remove		= pic32_uart_remove,
	.driver		= {
		.name	= PIC32_DEV_NAME,
		.of_match_table	= of_match_ptr(pic32_serial_dt_ids),
	},
};

static int __init pic32_uart_init(void)
{
	int ret;

	ret = uart_register_driver(&pic32_uart_driver);
	if (ret) {
		pr_err("failed to register %s:%d\n",
		       pic32_uart_driver.driver_name, ret);
		return ret;
	}

	ret = platform_driver_register(&pic32_uart_platform_driver);
	if (ret) {
		pr_err("fail to register pic32 uart\n");
		uart_unregister_driver(&pic32_uart_driver);
	}

	return ret;
}
arch_initcall(pic32_uart_init);

static void __exit pic32_uart_exit(void)
{
#ifdef CONFIG_SERIAL_PIC32_CONSOLE
	unregister_console(&pic32_console);
#endif
	platform_driver_unregister(&pic32_uart_platform_driver);
	uart_unregister_driver(&pic32_uart_driver);
}
module_exit(pic32_uart_exit);

MODULE_AUTHOR("Sorin-Andrei Pistirica <andrei.pistirica@microchip.com>");
MODULE_DESCRIPTION("Microchip PIC32 integrated serial port driver");
MODULE_LICENSE("GPL v2");
