linux/drivers/tty/serial/arc_uart.c

// SPDX-License-Identifier: GPL-2.0
/*
 * ARC On-Chip(fpga) UART Driver
 *
 * Copyright (C) 2010-2012 Synopsys, Inc. (www.synopsys.com)
 *
 * vineetg: July 10th 2012
 *  -Decoupled the driver from arch/arc
 *    +Using platform_get_resource() for irq/membase (thx to bfin_uart.c)
 *    +Using early_platform_xxx() for early console (thx to mach-shmobile/xxx)
 *
 * Vineetg: Aug 21st 2010
 *  -Is uart_tx_stopped() not done in tty write path as it has already been
 *   taken care of, in serial core
 *
 * Vineetg: Aug 18th 2010
 *  -New Serial Core based ARC UART driver
 *  -Derived largely from blackfin driver albiet with some major tweaks
 *
 * TODO:
 *  -check if sysreq works
 */

#include <linux/module.h>
#include <linux/serial.h>
#include <linux/console.h>
#include <linux/sysrq.h>
#include <linux/platform_device.h>
#include <linux/tty.h>
#include <linux/tty_flip.h>
#include <linux/serial_core.h>
#include <linux/io.h>
#include <linux/of_irq.h>
#include <linux/of_address.h>

/*************************************
 * ARC UART Hardware Specs
 ************************************/
#define ARC_UART_TX_FIFO_SIZE

/*
 * UART Register set (this is not a Standards Compliant IP)
 * Also each reg is Word aligned, but only 8 bits wide
 */
#define R_ID0
#define R_ID1
#define R_ID2
#define R_ID3
#define R_DATA
#define R_STS
#define R_BAUDL
#define R_BAUDH

/* Bits for UART Status Reg (R/W) */
#define RXIENB
#define TXIENB

#define RXEMPTY
#define TXEMPTY

#define RXFULL
#define RXFULL1

#define RXFERR
#define RXOERR

/* Uart bit fiddling helpers: lowest level */
#define RBASE(port, reg)
#define UART_REG_SET(u, r, v)
#define UART_REG_GET(u, r)

#define UART_REG_OR(u, r, v)
#define UART_REG_CLR(u, r, v)

/* Uart bit fiddling helpers: API level */
#define UART_SET_DATA(uart, val)
#define UART_GET_DATA(uart)

#define UART_SET_BAUDH(uart, val)
#define UART_SET_BAUDL(uart, val)

#define UART_CLR_STATUS(uart, val)
#define UART_GET_STATUS(uart)

#define UART_ALL_IRQ_DISABLE(uart)
#define UART_RX_IRQ_DISABLE(uart)
#define UART_TX_IRQ_DISABLE(uart)

#define UART_ALL_IRQ_ENABLE(uart)
#define UART_RX_IRQ_ENABLE(uart)
#define UART_TX_IRQ_ENABLE(uart)

#define ARC_SERIAL_DEV_NAME

struct arc_uart_port {};

#define to_arc_port(uport)

static struct arc_uart_port arc_uart_ports[CONFIG_SERIAL_ARC_NR_PORTS];

#ifdef CONFIG_SERIAL_ARC_CONSOLE
static struct console arc_console;
#endif

#define DRIVER_NAME

static struct uart_driver arc_uart_driver =;

static void arc_serial_stop_rx(struct uart_port *port)
{}

static void arc_serial_stop_tx(struct uart_port *port)
{}

/*
 * Return TIOCSER_TEMT when transmitter is not busy.
 */
static unsigned int arc_serial_tx_empty(struct uart_port *port)
{}

/*
 * Driver internal routine, used by both tty(serial core) as well as tx-isr
 *  -Called under spinlock in either cases
 *  -also tty->flow.stopped has already been checked
 *     = by uart_start( ) before calling us
 *     = tx_ist checks that too before calling
 */
static void arc_serial_tx_chars(struct uart_port *port)
{}

/*
 * port is locked and interrupts are disabled
 * uart_start( ) calls us under the port spinlock irqsave
 */
static void arc_serial_start_tx(struct uart_port *port)
{}

static void arc_serial_rx_chars(struct uart_port *port, unsigned int status)
{}

/*
 * A note on the Interrupt handling state machine of this driver
 *
 * kernel printk writes funnel thru the console driver framework and in order
 * to keep things simple as well as efficient, it writes to UART in polled
 * mode, in one shot, and exits.
 *
 * OTOH, Userland output (via tty layer), uses interrupt based writes as there
 * can be undeterministic delay between char writes.
 *
 * Thus Rx-interrupts are always enabled, while tx-interrupts are by default
 * disabled.
 *
 * When tty has some data to send out, serial core calls driver's start_tx
 * which
 *   -checks-if-tty-buffer-has-char-to-send
 *   -writes-data-to-uart
 *   -enable-tx-intr
 *
 * Once data bits are pushed out, controller raises the Tx-room-avail-Interrupt.
 * The first thing Tx ISR does is disable further Tx interrupts (as this could
 * be the last char to send, before settling down into the quiet polled mode).
 * It then calls the exact routine used by tty layer write to send out any
 * more char in tty buffer. In case of sending, it re-enables Tx-intr. In case
 * of no data, it remains disabled.
 * This is how the transmit state machine is dynamically switched on/off
 */

static irqreturn_t arc_serial_isr(int irq, void *dev_id)
{}

static unsigned int arc_serial_get_mctrl(struct uart_port *port)
{}

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

static void arc_serial_break_ctl(struct uart_port *port, int break_state)
{}

static int arc_serial_startup(struct uart_port *port)
{}

/* This is not really needed */
static void arc_serial_shutdown(struct uart_port *port)
{}

static void
arc_serial_set_termios(struct uart_port *port, struct ktermios *new,
		       const struct ktermios *old)
{}

static const char *arc_serial_type(struct uart_port *port)
{}

static void arc_serial_release_port(struct uart_port *port)
{}

static int arc_serial_request_port(struct uart_port *port)
{}

/*
 * Verify the new serial_struct (for TIOCSSERIAL).
 */
static int
arc_serial_verify_port(struct uart_port *port, struct serial_struct *ser)
{}

/*
 * Configure/autoconfigure the port.
 */
static void arc_serial_config_port(struct uart_port *port, int flags)
{}

#ifdef CONFIG_CONSOLE_POLL

static void arc_serial_poll_putchar(struct uart_port *port, unsigned char chr)
{}

static int arc_serial_poll_getchar(struct uart_port *port)
{}
#endif

static const struct uart_ops arc_serial_pops =;

#ifdef CONFIG_SERIAL_ARC_CONSOLE

static int arc_serial_console_setup(struct console *co, char *options)
{}

static void arc_serial_console_putchar(struct uart_port *port, unsigned char ch)
{}

/*
 * Interrupts are disabled on entering
 */
static void arc_serial_console_write(struct console *co, const char *s,
				     unsigned int count)
{}

static struct console arc_console =;

static void arc_early_serial_write(struct console *con, const char *s,
				   unsigned int n)
{}

static int __init arc_early_console_setup(struct earlycon_device *dev,
					  const char *opt)
{}
OF_EARLYCON_DECLARE();

#endif	/* CONFIG_SERIAL_ARC_CONSOLE */

static int arc_serial_probe(struct platform_device *pdev)
{}

static const struct of_device_id arc_uart_dt_ids[] =;
MODULE_DEVICE_TABLE(of, arc_uart_dt_ids);

static struct platform_driver arc_platform_driver =;

static int __init arc_serial_init(void)
{}

static void __exit arc_serial_exit(void)
{}

module_init();
module_exit(arc_serial_exit);

MODULE_LICENSE();
MODULE_ALIAS();
MODULE_AUTHOR();
MODULE_DESCRIPTION();