linux/drivers/tty/serial/8250/8250_aspeed_vuart.c

// SPDX-License-Identifier: GPL-2.0+
/*
 *  Serial Port driver for Aspeed VUART device
 *
 *    Copyright (C) 2016 Jeremy Kerr <[email protected]>, IBM Corp.
 *    Copyright (C) 2006 Arnd Bergmann <[email protected]>, IBM Corp.
 */
#include <linux/device.h>
#include <linux/module.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>
#include <linux/of_platform.h>
#include <linux/regmap.h>
#include <linux/mfd/syscon.h>
#include <linux/tty.h>
#include <linux/tty_flip.h>
#include <linux/clk.h>

#include "8250.h"

#define ASPEED_VUART_GCRA
#define ASPEED_VUART_GCRA_VUART_EN
#define ASPEED_VUART_GCRA_HOST_SIRQ_POLARITY
#define ASPEED_VUART_GCRA_DISABLE_HOST_TX_DISCARD
#define ASPEED_VUART_GCRB
#define ASPEED_VUART_GCRB_HOST_SIRQ_MASK
#define ASPEED_VUART_GCRB_HOST_SIRQ_SHIFT
#define ASPEED_VUART_ADDRL
#define ASPEED_VUART_ADDRH

#define ASPEED_VUART_DEFAULT_LPC_ADDR
#define ASPEED_VUART_DEFAULT_SIRQ
#define ASPEED_VUART_DEFAULT_SIRQ_POLARITY

struct aspeed_vuart {};

/*
 * If we fill the tty flip buffers, we throttle the data ready interrupt
 * to prevent dropped characters. This timeout defines how long we wait
 * to (conditionally, depending on buffer state) unthrottle.
 */
static const int unthrottle_timeout =;

/*
 * The VUART is basically two UART 'front ends' connected by their FIFO
 * (no actual serial line in between). One is on the BMC side (management
 * controller) and one is on the host CPU side.
 *
 * It allows the BMC to provide to the host a "UART" that pipes into
 * the BMC itself and can then be turned by the BMC into a network console
 * of some sort for example.
 *
 * This driver is for the BMC side. The sysfs files allow the BMC
 * userspace which owns the system configuration policy, to specify
 * at what IO port and interrupt number the host side will appear
 * to the host on the Host <-> BMC LPC bus. It could be different on a
 * different system (though most of them use 3f8/4).
 */

static inline u8 aspeed_vuart_readb(struct aspeed_vuart *vuart, u8 reg)
{}

static inline void aspeed_vuart_writeb(struct aspeed_vuart *vuart, u8 val, u8 reg)
{}

static ssize_t lpc_address_show(struct device *dev,
				struct device_attribute *attr, char *buf)
{}

static int aspeed_vuart_set_lpc_address(struct aspeed_vuart *vuart, u32 addr)
{}

static ssize_t lpc_address_store(struct device *dev,
				 struct device_attribute *attr,
				 const char *buf, size_t count)
{}

static DEVICE_ATTR_RW(lpc_address);

static ssize_t sirq_show(struct device *dev,
			 struct device_attribute *attr, char *buf)
{}

static int aspeed_vuart_set_sirq(struct aspeed_vuart *vuart, u32 sirq)
{}

static ssize_t sirq_store(struct device *dev, struct device_attribute *attr,
			  const char *buf, size_t count)
{}

static DEVICE_ATTR_RW(sirq);

static ssize_t sirq_polarity_show(struct device *dev,
				  struct device_attribute *attr, char *buf)
{}

static void aspeed_vuart_set_sirq_polarity(struct aspeed_vuart *vuart,
					   bool polarity)
{}

static ssize_t sirq_polarity_store(struct device *dev,
				   struct device_attribute *attr,
				   const char *buf, size_t count)
{}

static DEVICE_ATTR_RW(sirq_polarity);

static struct attribute *aspeed_vuart_attrs[] =;

static const struct attribute_group aspeed_vuart_attr_group =;

static void aspeed_vuart_set_enabled(struct aspeed_vuart *vuart, bool enabled)
{}

static void aspeed_vuart_set_host_tx_discard(struct aspeed_vuart *vuart,
					     bool discard)
{}

static int aspeed_vuart_startup(struct uart_port *uart_port)
{}

static void aspeed_vuart_shutdown(struct uart_port *uart_port)
{}

static void __aspeed_vuart_set_throttle(struct uart_8250_port *up,
		bool throttle)
{}
static void aspeed_vuart_set_throttle(struct uart_port *port, bool throttle)
{}

static void aspeed_vuart_throttle(struct uart_port *port)
{}

static void aspeed_vuart_unthrottle(struct uart_port *port)
{}

static void aspeed_vuart_unthrottle_exp(struct timer_list *timer)
{}

/*
 * Custom interrupt handler to manage finer-grained flow control. Although we
 * have throttle/unthrottle callbacks, we've seen that the VUART device can
 * deliver characters faster than the ldisc has a chance to check buffer space
 * against the throttle threshold. This results in dropped characters before
 * the throttle.
 *
 * We do this by checking for flip buffer space before RX. If we have no space,
 * throttle now and schedule an unthrottle for later, once the ldisc has had
 * a chance to drain the buffers.
 */
static int aspeed_vuart_handle_irq(struct uart_port *port)
{}

static void aspeed_vuart_auto_configure_sirq_polarity(
	struct aspeed_vuart *vuart, struct device_node *syscon_np,
	u32 reg_offset, u32 reg_mask)
{}

static int aspeed_vuart_map_irq_polarity(u32 dt)
{}

static int aspeed_vuart_probe(struct platform_device *pdev)
{}

static void aspeed_vuart_remove(struct platform_device *pdev)
{}

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

static struct platform_driver aspeed_vuart_driver =;

module_platform_driver();

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