// SPDX-License-Identifier: GPL-2.0+
/*
 *  Driver for KS8695 serial ports
 *
 *  Based on drivers/serial/serial_amba.c, by Kam Lee.
 *
 *  Copyright 2002-2005 Micrel Inc.
 */
#include <linux/module.h>
#include <linux/tty.h>
#include <linux/tty_flip.h>
#include <linux/ioport.h>
#include <linux/init.h>
#include <linux/serial.h>
#include <linux/console.h>
#include <linux/sysrq.h>
#include <linux/device.h>

#include <asm/io.h>
#include <asm/irq.h>
#include <asm/mach/irq.h>

#include <mach/regs-uart.h>
#include <mach/regs-irq.h>

#if defined(CONFIG_SERIAL_KS8695_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
#define SUPPORT_SYSRQ
#endif

#include <linux/serial_core.h>


#define SERIAL_KS8695_MAJOR	204
#define SERIAL_KS8695_MINOR	16
#define SERIAL_KS8695_DEVNAME	"ttyAM"

#define SERIAL_KS8695_NR	1

/*
 * Access macros for the KS8695 UART
 */
#define UART_GET_CHAR(p)	(__raw_readl((p)->membase + KS8695_URRB) & 0xFF)
#define UART_PUT_CHAR(p, c)	__raw_writel((c), (p)->membase + KS8695_URTH)
#define UART_GET_FCR(p)		__raw_readl((p)->membase + KS8695_URFC)
#define UART_PUT_FCR(p, c)	__raw_writel((c), (p)->membase + KS8695_URFC)
#define UART_GET_MSR(p)		__raw_readl((p)->membase + KS8695_URMS)
#define UART_GET_LSR(p)		__raw_readl((p)->membase + KS8695_URLS)
#define UART_GET_LCR(p)		__raw_readl((p)->membase + KS8695_URLC)
#define UART_PUT_LCR(p, c)	__raw_writel((c), (p)->membase + KS8695_URLC)
#define UART_GET_MCR(p)		__raw_readl((p)->membase + KS8695_URMC)
#define UART_PUT_MCR(p, c)	__raw_writel((c), (p)->membase + KS8695_URMC)
#define UART_GET_BRDR(p)	__raw_readl((p)->membase + KS8695_URBD)
#define UART_PUT_BRDR(p, c)	__raw_writel((c), (p)->membase + KS8695_URBD)

#define KS8695_CLR_TX_INT()	__raw_writel(1 << KS8695_IRQ_UART_TX, KS8695_IRQ_VA + KS8695_INTST)

#define UART_DUMMY_LSR_RX	0x100
#define UART_PORT_SIZE		(KS8695_USR - KS8695_URRB + 4)

static inline int tx_enabled(struct uart_port *port)
{
	return port->unused[0] & 1;
}

static inline int rx_enabled(struct uart_port *port)
{
	return port->unused[0] & 2;
}

static inline int ms_enabled(struct uart_port *port)
{
	return port->unused[0] & 4;
}

static inline void ms_enable(struct uart_port *port, int enabled)
{
	if(enabled)
		port->unused[0] |= 4;
	else
		port->unused[0] &= ~4;
}

static inline void rx_enable(struct uart_port *port, int enabled)
{
	if(enabled)
		port->unused[0] |= 2;
	else
		port->unused[0] &= ~2;
}

static inline void tx_enable(struct uart_port *port, int enabled)
{
	if(enabled)
		port->unused[0] |= 1;
	else
		port->unused[0] &= ~1;
}


#ifdef SUPPORT_SYSRQ
static struct console ks8695_console;
#endif

static void ks8695uart_stop_tx(struct uart_port *port)
{
	if (tx_enabled(port)) {
		/* use disable_irq_nosync() and not disable_irq() to avoid self
		 * imposed deadlock by not waiting for irq handler to end,
		 * since this ks8695uart_stop_tx() is called from interrupt context.
		 */
		disable_irq_nosync(KS8695_IRQ_UART_TX);
		tx_enable(port, 0);
	}
}

static void ks8695uart_start_tx(struct uart_port *port)
{
	if (!tx_enabled(port)) {
		enable_irq(KS8695_IRQ_UART_TX);
		tx_enable(port, 1);
	}
}

static void ks8695uart_stop_rx(struct uart_port *port)
{
	if (rx_enabled(port)) {
		disable_irq(KS8695_IRQ_UART_RX);
		rx_enable(port, 0);
	}
}

static void ks8695uart_enable_ms(struct uart_port *port)
{
	if (!ms_enabled(port)) {
		enable_irq(KS8695_IRQ_UART_MODEM_STATUS);
		ms_enable(port,1);
	}
}

static void ks8695uart_disable_ms(struct uart_port *port)
{
	if (ms_enabled(port)) {
		disable_irq(KS8695_IRQ_UART_MODEM_STATUS);
		ms_enable(port,0);
	}
}

static irqreturn_t ks8695uart_rx_chars(int irq, void *dev_id)
{
	struct uart_port *port = dev_id;
	unsigned int status, ch, lsr, flg, max_count = 256;

	status = UART_GET_LSR(port);		/* clears pending LSR interrupts */
	while ((status & URLS_URDR) && max_count--) {
		ch = UART_GET_CHAR(port);
		flg = TTY_NORMAL;

		port->icount.rx++;

		/*
		 * Note that the error handling code is
		 * out of the main execution path
		 */
		lsr = UART_GET_LSR(port) | UART_DUMMY_LSR_RX;
		if (unlikely(lsr & (URLS_URBI | URLS_URPE | URLS_URFE | URLS_URROE))) {
			if (lsr & URLS_URBI) {
				lsr &= ~(URLS_URFE | URLS_URPE);
				port->icount.brk++;
				if (uart_handle_break(port))
					goto ignore_char;
			}
			if (lsr & URLS_URPE)
				port->icount.parity++;
			if (lsr & URLS_URFE)
				port->icount.frame++;
			if (lsr & URLS_URROE)
				port->icount.overrun++;

			lsr &= port->read_status_mask;

			if (lsr & URLS_URBI)
				flg = TTY_BREAK;
			else if (lsr & URLS_URPE)
				flg = TTY_PARITY;
			else if (lsr & URLS_URFE)
				flg = TTY_FRAME;
		}

		if (uart_handle_sysrq_char(port, ch))
			goto ignore_char;

		uart_insert_char(port, lsr, URLS_URROE, ch, flg);

ignore_char:
		status = UART_GET_LSR(port);
	}
	tty_flip_buffer_push(&port->state->port);

	return IRQ_HANDLED;
}


static irqreturn_t ks8695uart_tx_chars(int irq, void *dev_id)
{
	struct uart_port *port = dev_id;
	struct circ_buf *xmit = &port->state->xmit;
	unsigned int count;

	if (port->x_char) {
		KS8695_CLR_TX_INT();
		UART_PUT_CHAR(port, port->x_char);
		port->icount.tx++;
		port->x_char = 0;
		return IRQ_HANDLED;
	}

	if (uart_tx_stopped(port) || uart_circ_empty(xmit)) {
		ks8695uart_stop_tx(port);
		return IRQ_HANDLED;
	}

	count = 16;	/* fifo size */
	while (!uart_circ_empty(xmit) && (count-- > 0)) {
		KS8695_CLR_TX_INT();
		UART_PUT_CHAR(port, xmit->buf[xmit->tail]);

		xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
		port->icount.tx++;
	}

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

	if (uart_circ_empty(xmit))
		ks8695uart_stop_tx(port);

	return IRQ_HANDLED;
}

static irqreturn_t ks8695uart_modem_status(int irq, void *dev_id)
{
	struct uart_port *port = dev_id;
	unsigned int status;

	/*
	 * clear modem interrupt by reading MSR
	 */
	status = UART_GET_MSR(port);

	if (status & URMS_URDDCD)
		uart_handle_dcd_change(port, status & URMS_URDDCD);

	if (status & URMS_URDDST)
		port->icount.dsr++;

	if (status & URMS_URDCTS)
		uart_handle_cts_change(port, status & URMS_URDCTS);

	if (status & URMS_URTERI)
		port->icount.rng++;

	wake_up_interruptible(&port->state->port.delta_msr_wait);

	return IRQ_HANDLED;
}

static unsigned int ks8695uart_tx_empty(struct uart_port *port)
{
	return (UART_GET_LSR(port) & URLS_URTE) ? TIOCSER_TEMT : 0;
}

static unsigned int ks8695uart_get_mctrl(struct uart_port *port)
{
	unsigned int result = 0;
	unsigned int status;

	status = UART_GET_MSR(port);
	if (status & URMS_URDCD)
		result |= TIOCM_CAR;
	if (status & URMS_URDSR)
		result |= TIOCM_DSR;
	if (status & URMS_URCTS)
		result |= TIOCM_CTS;
	if (status & URMS_URRI)
		result |= TIOCM_RI;

	return result;
}

static void ks8695uart_set_mctrl(struct uart_port *port, u_int mctrl)
{
	unsigned int mcr;

	mcr = UART_GET_MCR(port);
	if (mctrl & TIOCM_RTS)
		mcr |= URMC_URRTS;
	else
		mcr &= ~URMC_URRTS;

	if (mctrl & TIOCM_DTR)
		mcr |= URMC_URDTR;
	else
		mcr &= ~URMC_URDTR;

	UART_PUT_MCR(port, mcr);
}

static void ks8695uart_break_ctl(struct uart_port *port, int break_state)
{
	unsigned int lcr;

	lcr = UART_GET_LCR(port);

	if (break_state == -1)
		lcr |= URLC_URSBC;
	else
		lcr &= ~URLC_URSBC;

	UART_PUT_LCR(port, lcr);
}

static int ks8695uart_startup(struct uart_port *port)
{
	int retval;

	irq_modify_status(KS8695_IRQ_UART_TX, IRQ_NOREQUEST, IRQ_NOAUTOEN);
	tx_enable(port, 0);
	rx_enable(port, 1);
	ms_enable(port, 1);

	/*
	 * Allocate the IRQ
	 */
	retval = request_irq(KS8695_IRQ_UART_TX, ks8695uart_tx_chars, 0, "UART TX", port);
	if (retval)
		goto err_tx;

	retval = request_irq(KS8695_IRQ_UART_RX, ks8695uart_rx_chars, 0, "UART RX", port);
	if (retval)
		goto err_rx;

	retval = request_irq(KS8695_IRQ_UART_LINE_STATUS, ks8695uart_rx_chars, 0, "UART LineStatus", port);
	if (retval)
		goto err_ls;

	retval = request_irq(KS8695_IRQ_UART_MODEM_STATUS, ks8695uart_modem_status, 0, "UART ModemStatus", port);
	if (retval)
		goto err_ms;

	return 0;

err_ms:
	free_irq(KS8695_IRQ_UART_LINE_STATUS, port);
err_ls:
	free_irq(KS8695_IRQ_UART_RX, port);
err_rx:
	free_irq(KS8695_IRQ_UART_TX, port);
err_tx:
	return retval;
}

static void ks8695uart_shutdown(struct uart_port *port)
{
	/*
	 * Free the interrupt
	 */
	free_irq(KS8695_IRQ_UART_RX, port);
	free_irq(KS8695_IRQ_UART_TX, port);
	free_irq(KS8695_IRQ_UART_MODEM_STATUS, port);
	free_irq(KS8695_IRQ_UART_LINE_STATUS, port);

	/* disable break condition and fifos */
	UART_PUT_LCR(port, UART_GET_LCR(port) & ~URLC_URSBC);
	UART_PUT_FCR(port, UART_GET_FCR(port) & ~URFC_URFE);
}

static void ks8695uart_set_termios(struct uart_port *port, struct ktermios *termios, struct ktermios *old)
{
	unsigned int lcr, fcr = 0;
	unsigned long flags;
	unsigned int baud, quot;

	/*
	 * Ask the core to calculate the divisor for us.
	 */
	baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16);
	quot = uart_get_divisor(port, baud);

	switch (termios->c_cflag & CSIZE) {
	case CS5:
		lcr = URCL_5;
		break;
	case CS6:
		lcr = URCL_6;
		break;
	case CS7:
		lcr = URCL_7;
		break;
	default:
		lcr = URCL_8;
		break;
	}

	/* stop bits */
	if (termios->c_cflag & CSTOPB)
		lcr |= URLC_URSB;

	/* parity */
	if (termios->c_cflag & PARENB) {
		if (termios->c_cflag & CMSPAR) {	/* Mark or Space parity */
			if (termios->c_cflag & PARODD)
				lcr |= URPE_MARK;
			else
				lcr |= URPE_SPACE;
		}
		else if (termios->c_cflag & PARODD)
			lcr |= URPE_ODD;
		else
			lcr |= URPE_EVEN;
	}

	if (port->fifosize > 1)
		fcr = URFC_URFRT_8 | URFC_URTFR | URFC_URRFR | URFC_URFE;

	spin_lock_irqsave(&port->lock, flags);

	/*
	 * Update the per-port timeout.
	 */
	uart_update_timeout(port, termios->c_cflag, baud);

	port->read_status_mask = URLS_URROE;
	if (termios->c_iflag & INPCK)
		port->read_status_mask |= (URLS_URFE | URLS_URPE);
	if (termios->c_iflag & (IGNBRK | BRKINT | PARMRK))
		port->read_status_mask |= URLS_URBI;

	/*
	 * Characters to ignore
	 */
	port->ignore_status_mask = 0;
	if (termios->c_iflag & IGNPAR)
		port->ignore_status_mask |= (URLS_URFE | URLS_URPE);
	if (termios->c_iflag & IGNBRK) {
		port->ignore_status_mask |= URLS_URBI;
		/*
		 * If we're ignoring parity and break indicators,
		 * ignore overruns too (for real raw support).
		 */
		if (termios->c_iflag & IGNPAR)
			port->ignore_status_mask |= URLS_URROE;
	}

	/*
	 * Ignore all characters if CREAD is not set.
	 */
	if ((termios->c_cflag & CREAD) == 0)
		port->ignore_status_mask |= UART_DUMMY_LSR_RX;

	/* first, disable everything */
	if (UART_ENABLE_MS(port, termios->c_cflag))
		ks8695uart_enable_ms(port);
	else
		ks8695uart_disable_ms(port);

	/* Set baud rate */
	UART_PUT_BRDR(port, quot);

	UART_PUT_LCR(port, lcr);
	UART_PUT_FCR(port, fcr);

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

static const char *ks8695uart_type(struct uart_port *port)
{
	return port->type == PORT_KS8695 ? "KS8695" : NULL;
}

/*
 * Release the memory region(s) being used by 'port'
 */
static void ks8695uart_release_port(struct uart_port *port)
{
	release_mem_region(port->mapbase, UART_PORT_SIZE);
}

/*
 * Request the memory region(s) being used by 'port'
 */
static int ks8695uart_request_port(struct uart_port *port)
{
	return request_mem_region(port->mapbase, UART_PORT_SIZE,
			"serial_ks8695") != NULL ? 0 : -EBUSY;
}

/*
 * Configure/autoconfigure the port.
 */
static void ks8695uart_config_port(struct uart_port *port, int flags)
{
	if (flags & UART_CONFIG_TYPE) {
		port->type = PORT_KS8695;
		ks8695uart_request_port(port);
	}
}

/*
 * verify the new serial_struct (for TIOCSSERIAL).
 */
static int ks8695uart_verify_port(struct uart_port *port, struct serial_struct *ser)
{
	int ret = 0;

	if (ser->type != PORT_UNKNOWN && ser->type != PORT_KS8695)
		ret = -EINVAL;
	if (ser->irq != port->irq)
		ret = -EINVAL;
	if (ser->baud_base < 9600)
		ret = -EINVAL;
	return ret;
}

static struct uart_ops ks8695uart_pops = {
	.tx_empty	= ks8695uart_tx_empty,
	.set_mctrl	= ks8695uart_set_mctrl,
	.get_mctrl	= ks8695uart_get_mctrl,
	.stop_tx	= ks8695uart_stop_tx,
	.start_tx	= ks8695uart_start_tx,
	.stop_rx	= ks8695uart_stop_rx,
	.enable_ms	= ks8695uart_enable_ms,
	.break_ctl	= ks8695uart_break_ctl,
	.startup	= ks8695uart_startup,
	.shutdown	= ks8695uart_shutdown,
	.set_termios	= ks8695uart_set_termios,
	.type		= ks8695uart_type,
	.release_port	= ks8695uart_release_port,
	.request_port	= ks8695uart_request_port,
	.config_port	= ks8695uart_config_port,
	.verify_port	= ks8695uart_verify_port,
};

static struct uart_port ks8695uart_ports[SERIAL_KS8695_NR] = {
	{
		.membase	= KS8695_UART_VA,
		.mapbase	= KS8695_UART_PA,
		.iotype		= SERIAL_IO_MEM,
		.irq		= KS8695_IRQ_UART_TX,
		.uartclk	= KS8695_CLOCK_RATE * 16,
		.fifosize	= 16,
		.ops		= &ks8695uart_pops,
		.flags		= UPF_BOOT_AUTOCONF,
		.line		= 0,
	}
};

#ifdef CONFIG_SERIAL_KS8695_CONSOLE
static void ks8695_console_putchar(struct uart_port *port, int ch)
{
	while (!(UART_GET_LSR(port) & URLS_URTHRE))
		barrier();

	UART_PUT_CHAR(port, ch);
}

static void ks8695_console_write(struct console *co, const char *s, u_int count)
{
	struct uart_port *port = ks8695uart_ports + co->index;

	uart_console_write(port, s, count, ks8695_console_putchar);
}

static void __init ks8695_console_get_options(struct uart_port *port, int *baud, int *parity, int *bits)
{
	unsigned int lcr;

	lcr = UART_GET_LCR(port);

	switch (lcr & URLC_PARITY) {
		case URPE_ODD:
			*parity = 'o';
			break;
		case URPE_EVEN:
			*parity = 'e';
			break;
		default:
			*parity = 'n';
	}

	switch (lcr & URLC_URCL) {
		case URCL_5:
			*bits = 5;
			break;
		case URCL_6:
			*bits = 6;
			break;
		case URCL_7:
			*bits = 7;
			break;
		default:
			*bits = 8;
	}

	*baud = port->uartclk / (UART_GET_BRDR(port) & 0x0FFF);
	*baud /= 16;
	*baud &= 0xFFFFFFF0;
}

static int __init ks8695_console_setup(struct console *co, char *options)
{
	struct uart_port *port;
	int baud = 115200;
	int bits = 8;
	int parity = 'n';
	int flow = 'n';

	/*
	 * Check whether an invalid uart number has been specified, and
	 * if so, search for the first available port that does have
	 * console support.
	 */
	port = uart_get_console(ks8695uart_ports, SERIAL_KS8695_NR, co);

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

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

static struct uart_driver ks8695_reg;

static struct console ks8695_console = {
	.name		= SERIAL_KS8695_DEVNAME,
	.write		= ks8695_console_write,
	.device		= uart_console_device,
	.setup		= ks8695_console_setup,
	.flags		= CON_PRINTBUFFER,
	.index		= -1,
	.data		= &ks8695_reg,
};

static int __init ks8695_console_init(void)
{
	add_preferred_console(SERIAL_KS8695_DEVNAME, 0, NULL);
	register_console(&ks8695_console);
	return 0;
}

console_initcall(ks8695_console_init);

#define KS8695_CONSOLE	&ks8695_console
#else
#define KS8695_CONSOLE	NULL
#endif

static struct uart_driver ks8695_reg = {
	.owner			= THIS_MODULE,
	.driver_name		= "serial_ks8695",
	.dev_name		= SERIAL_KS8695_DEVNAME,
	.major			= SERIAL_KS8695_MAJOR,
	.minor			= SERIAL_KS8695_MINOR,
	.nr			= SERIAL_KS8695_NR,
	.cons			= KS8695_CONSOLE,
};

static int __init ks8695uart_init(void)
{
	int i, ret;

	printk(KERN_INFO "Serial: Micrel KS8695 UART driver\n");

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

	for (i = 0; i < SERIAL_KS8695_NR; i++)
		uart_add_one_port(&ks8695_reg, &ks8695uart_ports[0]);

	return 0;
}

static void __exit ks8695uart_exit(void)
{
	int i;

	for (i = 0; i < SERIAL_KS8695_NR; i++)
		uart_remove_one_port(&ks8695_reg, &ks8695uart_ports[0]);
	uart_unregister_driver(&ks8695_reg);
}

module_init(ks8695uart_init);
module_exit(ks8695uart_exit);

MODULE_DESCRIPTION("KS8695 serial port driver");
MODULE_AUTHOR("Micrel Inc.");
MODULE_LICENSE("GPL");
