Files
kernel_arpi/include/linux/serial_core.h
Greg Kroah-Hartman 20c4f16769 Merge 5.15.71 into android14-5.15
Changes in 5.15.71
	drm/amdgpu: Separate vf2pf work item init from virt data exchange
	drm/amdgpu: make sure to init common IP before gmc
	staging: r8188eu: Remove support for devices with 8188FU chipset (0bda:f179)
	staging: r8188eu: Add Rosewill USB-N150 Nano to device tables
	usb: dwc3: gadget: Avoid starting DWC3 gadget during UDC unbind
	usb: dwc3: Issue core soft reset before enabling run/stop
	usb: dwc3: gadget: Prevent repeat pullup()
	usb: dwc3: gadget: Refactor pullup()
	usb: dwc3: gadget: Don't modify GEVNTCOUNT in pullup()
	usb: dwc3: gadget: Avoid duplicate requests to enable Run/Stop
	usb: add quirks for Lenovo OneLink+ Dock
	usb: gadget: udc-xilinx: replace memcpy with memcpy_toio
	Revert "usb: add quirks for Lenovo OneLink+ Dock"
	Revert "usb: gadget: udc-xilinx: replace memcpy with memcpy_toio"
	drivers/base: Fix unsigned comparison to -1 in CPUMAP_FILE_MAX_BYTES
	USB: core: Fix RST error in hub.c
	USB: serial: option: add Quectel BG95 0x0203 composition
	USB: serial: option: add Quectel RM520N
	Revert "ALSA: usb-audio: Split endpoint setups for hw_params and prepare"
	ALSA: core: Fix double-free at snd_card_new()
	ALSA: hda/tegra: set depop delay for tegra
	ALSA: hda: add Intel 5 Series / 3400 PCI DID
	ALSA: hda/realtek: Add quirk for Huawei WRT-WX9
	ALSA: hda/realtek: Enable 4-speaker output Dell Precision 5570 laptop
	ALSA: hda/realtek: Re-arrange quirk table entries
	ALSA: hda/realtek: Add pincfg for ASUS G513 HP jack
	ALSA: hda/realtek: Add pincfg for ASUS G533Z HP jack
	ALSA: hda/realtek: Add quirk for ASUS GA503R laptop
	ALSA: hda/realtek: Enable 4-speaker output Dell Precision 5530 laptop
	iommu/vt-d: Check correct capability for sagaw determination
	btrfs: fix hang during unmount when stopping block group reclaim worker
	btrfs: fix hang during unmount when stopping a space reclaim worker
	media: flexcop-usb: fix endpoint type check
	usb: dwc3: core: leave default DMA if the controller does not support 64-bit DMA
	thunderbolt: Add support for Intel Maple Ridge single port controller
	efi: x86: Wipe setup_data on pure EFI boot
	efi: libstub: check Shim mode using MokSBStateRT
	wifi: mt76: fix reading current per-tid starting sequence number for aggregation
	gpio: mockup: fix NULL pointer dereference when removing debugfs
	gpio: mockup: Fix potential resource leakage when register a chip
	gpiolib: cdev: Set lineevent_state::irq after IRQ register successfully
	riscv: fix a nasty sigreturn bug...
	kasan: call kasan_malloc() from __kmalloc_*track_caller()
	can: flexcan: flexcan_mailbox_read() fix return value for drop = true
	net: mana: Add rmb after checking owner bits
	mm/slub: fix to return errno if kmalloc() fails
	mm: slub: fix flush_cpu_slab()/__free_slab() invocations in task context.
	KVM: x86: Inject #UD on emulated XSETBV if XSAVES isn't enabled
	arm64: topology: fix possible overflow in amu_fie_setup()
	vmlinux.lds.h: CFI: Reduce alignment of jump-table to function alignment
	xfs: reorder iunlink remove operation in xfs_ifree
	xfs: fix xfs_ifree() error handling to not leak perag ref
	xfs: validate inode fork size against fork format
	firmware: arm_scmi: Harden accesses to the reset domains
	firmware: arm_scmi: Fix the asynchronous reset requests
	arm64: dts: rockchip: Pull up wlan wake# on Gru-Bob
	arm64: dts: rockchip: Fix typo in lisense text for PX30.Core
	drm/mediatek: dsi: Add atomic {destroy,duplicate}_state, reset callbacks
	arm64: dts: rockchip: Set RK3399-Gru PCLK_EDP to 24 MHz
	dmaengine: ti: k3-udma-private: Fix refcount leak bug in of_xudma_dev_get()
	arm64: dts: rockchip: Remove 'enable-active-low' from rk3399-puma
	netfilter: nf_conntrack_sip: fix ct_sip_walk_headers
	netfilter: nf_conntrack_irc: Tighten matching on DCC message
	netfilter: nfnetlink_osf: fix possible bogus match in nf_osf_find()
	ice: Don't double unplug aux on peer initiated reset
	iavf: Fix cached head and tail value for iavf_get_tx_pending
	ipvlan: Fix out-of-bound bugs caused by unset skb->mac_header
	net: core: fix flow symmetric hash
	net: phy: aquantia: wait for the suspend/resume operations to finish
	scsi: qla2xxx: Fix memory leak in __qlt_24xx_handle_abts()
	scsi: mpt3sas: Fix return value check of dma_get_required_mask()
	net: bonding: Share lacpdu_mcast_addr definition
	net: bonding: Unsync device addresses on ndo_stop
	net: team: Unsync device addresses on ndo_stop
	drm/panel: simple: Fix innolux_g121i1_l01 bus_format
	MIPS: lantiq: export clk_get_io() for lantiq_wdt.ko
	MIPS: Loongson32: Fix PHY-mode being left unspecified
	um: fix default console kernel parameter
	iavf: Fix bad page state
	mlxbf_gige: clear MDIO gateway lock after read
	iavf: Fix set max MTU size with port VLAN and jumbo frames
	i40e: Fix VF set max MTU size
	i40e: Fix set max_tx_rate when it is lower than 1 Mbps
	sfc: fix TX channel offset when using legacy interrupts
	sfc: fix null pointer dereference in efx_hard_start_xmit
	drm/hisilicon/hibmc: Allow to be built if COMPILE_TEST is enabled
	drm/hisilicon: Add depends on MMU
	of: mdio: Add of_node_put() when breaking out of for_each_xx
	net: ipa: properly limit modem routing table use
	wireguard: ratelimiter: disable timings test by default
	wireguard: netlink: avoid variable-sized memcpy on sockaddr
	net: enetc: move enetc_set_psfp() out of the common enetc_set_features()
	net: enetc: deny offload of tc-based TSN features on VF interfaces
	net/sched: taprio: avoid disabling offload when it was never enabled
	net/sched: taprio: make qdisc_leaf() see the per-netdev-queue pfifo child qdiscs
	netfilter: nf_tables: fix nft_counters_enabled underflow at nf_tables_addchain()
	netfilter: nf_tables: fix percpu memory leak at nf_tables_addchain()
	netfilter: ebtables: fix memory leak when blob is malformed
	net: ravb: Fix PHY state warning splat during system resume
	net: sh_eth: Fix PHY state warning splat during system resume
	can: gs_usb: gs_can_open(): fix race dev->can.state condition
	perf stat: Fix BPF program section name
	perf jit: Include program header in ELF files
	perf kcore_copy: Do not check /proc/modules is unchanged
	perf tools: Honor namespace when synthesizing build-ids
	drm/mediatek: dsi: Move mtk_dsi_stop() call back to mtk_dsi_poweroff()
	net/smc: Stop the CLC flow if no link to map buffers on
	bonding: fix NULL deref in bond_rr_gen_slave_id
	net: sunhme: Fix packet reception for len < RX_COPY_THRESHOLD
	net: sched: fix possible refcount leak in tc_new_tfilter()
	bnxt: prevent skb UAF after handing over to PTP worker
	selftests: forwarding: add shebang for sch_red.sh
	KVM: x86/mmu: Fold rmap_recycle into rmap_add
	serial: fsl_lpuart: Reset prior to registration
	serial: Create uart_xmit_advance()
	serial: tegra: Use uart_xmit_advance(), fixes icount.tx accounting
	serial: tegra-tcu: Use uart_xmit_advance(), fixes icount.tx accounting
	s390/dasd: fix Oops in dasd_alias_get_start_dev due to missing pavgroup
	drm/amd/amdgpu: fixing read wrong pf2vf data in SRIOV
	Drivers: hv: Never allocate anything besides framebuffer from framebuffer memory region
	drm/gma500: Fix BUG: sleeping function called from invalid context errors
	drm/amd/pm: disable BACO entry/exit completely on several sienna cichlid cards
	drm/amdgpu: use dirty framebuffer helper
	drm/amd/display: Limit user regamma to a valid value
	drm/amd/display: Reduce number of arguments of dml31's CalculateWatermarksAndDRAMSpeedChangeSupport()
	drm/amd/display: Reduce number of arguments of dml31's CalculateFlipSchedule()
	drm/amd/display: Mark dml30's UseMinimumDCFCLK() as noinline for stack usage
	drm/rockchip: Fix return type of cdn_dp_connector_mode_valid
	fsdax: Fix infinite loop in dax_iomap_rw()
	workqueue: don't skip lockdep work dependency in cancel_work_sync()
	i2c: imx: If pm_runtime_get_sync() returned 1 device access is possible
	i2c: mlxbf: incorrect base address passed during io write
	i2c: mlxbf: prevent stack overflow in mlxbf_i2c_smbus_start_transaction()
	i2c: mlxbf: Fix frequency calculation
	drm/amdgpu: don't register a dirty callback for non-atomic
	NFSv4: Fixes for nfs4_inode_return_delegation()
	devdax: Fix soft-reservation memory description
	ext4: make directory inode spreading reflect flexbg size
	ext4: fix bug in extents parsing when eh_entries == 0 and eh_depth > 0
	ext4: limit the number of retries after discarding preallocations blocks
	ext4: make mballoc try target group first even with mb_optimize_scan
	ext4: avoid unnecessary spreading of allocations among groups
	ext4: use locality group preallocation for small closed files
	Linux 5.15.71

Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
Change-Id: Ie66ba67f788b7ce6ffd766544f9ec0286bec5d9f
2022-09-28 13:32:32 +02:00

626 lines
18 KiB
C

/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* linux/drivers/char/serial_core.h
*
* Copyright (C) 2000 Deep Blue Solutions Ltd.
*/
#ifndef LINUX_SERIAL_CORE_H
#define LINUX_SERIAL_CORE_H
#include <linux/bitops.h>
#include <linux/compiler.h>
#include <linux/console.h>
#include <linux/interrupt.h>
#include <linux/circ_buf.h>
#include <linux/spinlock.h>
#include <linux/sched.h>
#include <linux/tty.h>
#include <linux/mutex.h>
#include <linux/sysrq.h>
#include <linux/android_kabi.h>
#include <uapi/linux/serial_core.h>
#ifdef CONFIG_SERIAL_CORE_CONSOLE
#define uart_console(port) \
((port)->cons && (port)->cons->index == (port)->line)
#else
#define uart_console(port) ({ (void)port; 0; })
#endif
struct uart_port;
struct serial_struct;
struct device;
struct gpio_desc;
/*
* This structure describes all the operations that can be done on the
* physical hardware. See Documentation/driver-api/serial/driver.rst for details.
*/
struct uart_ops {
unsigned int (*tx_empty)(struct uart_port *);
void (*set_mctrl)(struct uart_port *, unsigned int mctrl);
unsigned int (*get_mctrl)(struct uart_port *);
void (*stop_tx)(struct uart_port *);
void (*start_tx)(struct uart_port *);
void (*throttle)(struct uart_port *);
void (*unthrottle)(struct uart_port *);
void (*send_xchar)(struct uart_port *, char ch);
void (*stop_rx)(struct uart_port *);
void (*enable_ms)(struct uart_port *);
void (*break_ctl)(struct uart_port *, int ctl);
int (*startup)(struct uart_port *);
void (*shutdown)(struct uart_port *);
void (*flush_buffer)(struct uart_port *);
void (*set_termios)(struct uart_port *, struct ktermios *new,
struct ktermios *old);
void (*set_ldisc)(struct uart_port *, struct ktermios *);
void (*pm)(struct uart_port *, unsigned int state,
unsigned int oldstate);
/*
* Return a string describing the type of the port
*/
const char *(*type)(struct uart_port *);
/*
* Release IO and memory resources used by the port.
* This includes iounmap if necessary.
*/
void (*release_port)(struct uart_port *);
/*
* Request IO and memory resources used by the port.
* This includes iomapping the port if necessary.
*/
int (*request_port)(struct uart_port *);
void (*config_port)(struct uart_port *, int);
int (*verify_port)(struct uart_port *, struct serial_struct *);
int (*ioctl)(struct uart_port *, unsigned int, unsigned long);
#ifdef CONFIG_CONSOLE_POLL
int (*poll_init)(struct uart_port *);
void (*poll_put_char)(struct uart_port *, unsigned char);
int (*poll_get_char)(struct uart_port *);
#endif
ANDROID_KABI_RESERVE(1);
ANDROID_KABI_RESERVE(2);
};
#define NO_POLL_CHAR 0x00ff0000
#define UART_CONFIG_TYPE (1 << 0)
#define UART_CONFIG_IRQ (1 << 1)
struct uart_icount {
__u32 cts;
__u32 dsr;
__u32 rng;
__u32 dcd;
__u32 rx;
__u32 tx;
__u32 frame;
__u32 overrun;
__u32 parity;
__u32 brk;
__u32 buf_overrun;
};
typedef unsigned int __bitwise upf_t;
typedef unsigned int __bitwise upstat_t;
struct uart_port {
spinlock_t lock; /* port lock */
unsigned long iobase; /* in/out[bwl] */
unsigned char __iomem *membase; /* read/write[bwl] */
unsigned int (*serial_in)(struct uart_port *, int);
void (*serial_out)(struct uart_port *, int, int);
void (*set_termios)(struct uart_port *,
struct ktermios *new,
struct ktermios *old);
void (*set_ldisc)(struct uart_port *,
struct ktermios *);
unsigned int (*get_mctrl)(struct uart_port *);
void (*set_mctrl)(struct uart_port *, unsigned int);
unsigned int (*get_divisor)(struct uart_port *,
unsigned int baud,
unsigned int *frac);
void (*set_divisor)(struct uart_port *,
unsigned int baud,
unsigned int quot,
unsigned int quot_frac);
int (*startup)(struct uart_port *port);
void (*shutdown)(struct uart_port *port);
void (*throttle)(struct uart_port *port);
void (*unthrottle)(struct uart_port *port);
int (*handle_irq)(struct uart_port *);
void (*pm)(struct uart_port *, unsigned int state,
unsigned int old);
void (*handle_break)(struct uart_port *);
int (*rs485_config)(struct uart_port *,
struct serial_rs485 *rs485);
int (*iso7816_config)(struct uart_port *,
struct serial_iso7816 *iso7816);
unsigned int irq; /* irq number */
unsigned long irqflags; /* irq flags */
unsigned int uartclk; /* base uart clock */
unsigned int fifosize; /* tx fifo size */
unsigned char x_char; /* xon/xoff char */
unsigned char regshift; /* reg offset shift */
unsigned char iotype; /* io access style */
unsigned char quirks; /* internal quirks */
#define UPIO_PORT (SERIAL_IO_PORT) /* 8b I/O port access */
#define UPIO_HUB6 (SERIAL_IO_HUB6) /* Hub6 ISA card */
#define UPIO_MEM (SERIAL_IO_MEM) /* driver-specific */
#define UPIO_MEM32 (SERIAL_IO_MEM32) /* 32b little endian */
#define UPIO_AU (SERIAL_IO_AU) /* Au1x00 and RT288x type IO */
#define UPIO_TSI (SERIAL_IO_TSI) /* Tsi108/109 type IO */
#define UPIO_MEM32BE (SERIAL_IO_MEM32BE) /* 32b big endian */
#define UPIO_MEM16 (SERIAL_IO_MEM16) /* 16b little endian */
/* quirks must be updated while holding port mutex */
#define UPQ_NO_TXEN_TEST BIT(0)
unsigned int read_status_mask; /* driver specific */
unsigned int ignore_status_mask; /* driver specific */
struct uart_state *state; /* pointer to parent state */
struct uart_icount icount; /* statistics */
struct console *cons; /* struct console, if any */
/* flags must be updated while holding port mutex */
upf_t flags;
/*
* These flags must be equivalent to the flags defined in
* include/uapi/linux/tty_flags.h which are the userspace definitions
* assigned from the serial_struct flags in uart_set_info()
* [for bit definitions in the UPF_CHANGE_MASK]
*
* Bits [0..UPF_LAST_USER] are userspace defined/visible/changeable
* The remaining bits are serial-core specific and not modifiable by
* userspace.
*/
#define UPF_FOURPORT ((__force upf_t) ASYNC_FOURPORT /* 1 */ )
#define UPF_SAK ((__force upf_t) ASYNC_SAK /* 2 */ )
#define UPF_SPD_HI ((__force upf_t) ASYNC_SPD_HI /* 4 */ )
#define UPF_SPD_VHI ((__force upf_t) ASYNC_SPD_VHI /* 5 */ )
#define UPF_SPD_CUST ((__force upf_t) ASYNC_SPD_CUST /* 0x0030 */ )
#define UPF_SPD_WARP ((__force upf_t) ASYNC_SPD_WARP /* 0x1010 */ )
#define UPF_SPD_MASK ((__force upf_t) ASYNC_SPD_MASK /* 0x1030 */ )
#define UPF_SKIP_TEST ((__force upf_t) ASYNC_SKIP_TEST /* 6 */ )
#define UPF_AUTO_IRQ ((__force upf_t) ASYNC_AUTO_IRQ /* 7 */ )
#define UPF_HARDPPS_CD ((__force upf_t) ASYNC_HARDPPS_CD /* 11 */ )
#define UPF_SPD_SHI ((__force upf_t) ASYNC_SPD_SHI /* 12 */ )
#define UPF_LOW_LATENCY ((__force upf_t) ASYNC_LOW_LATENCY /* 13 */ )
#define UPF_BUGGY_UART ((__force upf_t) ASYNC_BUGGY_UART /* 14 */ )
#define UPF_MAGIC_MULTIPLIER ((__force upf_t) ASYNC_MAGIC_MULTIPLIER /* 16 */ )
#define UPF_NO_THRE_TEST ((__force upf_t) (1 << 19))
/* Port has hardware-assisted h/w flow control */
#define UPF_AUTO_CTS ((__force upf_t) (1 << 20))
#define UPF_AUTO_RTS ((__force upf_t) (1 << 21))
#define UPF_HARD_FLOW ((__force upf_t) (UPF_AUTO_CTS | UPF_AUTO_RTS))
/* Port has hardware-assisted s/w flow control */
#define UPF_SOFT_FLOW ((__force upf_t) (1 << 22))
#define UPF_CONS_FLOW ((__force upf_t) (1 << 23))
#define UPF_SHARE_IRQ ((__force upf_t) (1 << 24))
#define UPF_EXAR_EFR ((__force upf_t) (1 << 25))
#define UPF_BUG_THRE ((__force upf_t) (1 << 26))
/* The exact UART type is known and should not be probed. */
#define UPF_FIXED_TYPE ((__force upf_t) (1 << 27))
#define UPF_BOOT_AUTOCONF ((__force upf_t) (1 << 28))
#define UPF_FIXED_PORT ((__force upf_t) (1 << 29))
#define UPF_DEAD ((__force upf_t) (1 << 30))
#define UPF_IOREMAP ((__force upf_t) (1 << 31))
#define __UPF_CHANGE_MASK 0x17fff
#define UPF_CHANGE_MASK ((__force upf_t) __UPF_CHANGE_MASK)
#define UPF_USR_MASK ((__force upf_t) (UPF_SPD_MASK|UPF_LOW_LATENCY))
#if __UPF_CHANGE_MASK > ASYNC_FLAGS
#error Change mask not equivalent to userspace-visible bit defines
#endif
/*
* Must hold termios_rwsem, port mutex and port lock to change;
* can hold any one lock to read.
*/
upstat_t status;
#define UPSTAT_CTS_ENABLE ((__force upstat_t) (1 << 0))
#define UPSTAT_DCD_ENABLE ((__force upstat_t) (1 << 1))
#define UPSTAT_AUTORTS ((__force upstat_t) (1 << 2))
#define UPSTAT_AUTOCTS ((__force upstat_t) (1 << 3))
#define UPSTAT_AUTOXOFF ((__force upstat_t) (1 << 4))
#define UPSTAT_SYNC_FIFO ((__force upstat_t) (1 << 5))
int hw_stopped; /* sw-assisted CTS flow state */
unsigned int mctrl; /* current modem ctrl settings */
unsigned int timeout; /* character-based timeout */
unsigned int type; /* port type */
const struct uart_ops *ops;
unsigned int custom_divisor;
unsigned int line; /* port index */
unsigned int minor;
resource_size_t mapbase; /* for ioremap */
resource_size_t mapsize;
struct device *dev; /* parent device */
unsigned long sysrq; /* sysrq timeout */
unsigned int sysrq_ch; /* char for sysrq */
unsigned char has_sysrq;
unsigned char sysrq_seq; /* index in sysrq_toggle_seq */
unsigned char hub6; /* this should be in the 8250 driver */
unsigned char suspended;
unsigned char console_reinit;
const char *name; /* port name */
struct attribute_group *attr_group; /* port specific attributes */
const struct attribute_group **tty_groups; /* all attributes (serial core use only) */
struct serial_rs485 rs485;
struct gpio_desc *rs485_term_gpio; /* enable RS485 bus termination */
struct serial_iso7816 iso7816;
void *private_data; /* generic platform data pointer */
ANDROID_KABI_RESERVE(1);
ANDROID_KABI_RESERVE(2);
};
static inline int serial_port_in(struct uart_port *up, int offset)
{
return up->serial_in(up, offset);
}
static inline void serial_port_out(struct uart_port *up, int offset, int value)
{
up->serial_out(up, offset, value);
}
/**
* enum uart_pm_state - power states for UARTs
* @UART_PM_STATE_ON: UART is powered, up and operational
* @UART_PM_STATE_OFF: UART is powered off
* @UART_PM_STATE_UNDEFINED: sentinel
*/
enum uart_pm_state {
UART_PM_STATE_ON = 0,
UART_PM_STATE_OFF = 3, /* number taken from ACPI */
UART_PM_STATE_UNDEFINED,
};
/*
* This is the state information which is persistent across opens.
*/
struct uart_state {
struct tty_port port;
enum uart_pm_state pm_state;
struct circ_buf xmit;
atomic_t refcount;
wait_queue_head_t remove_wait;
struct uart_port *uart_port;
};
#define UART_XMIT_SIZE PAGE_SIZE
/* number of characters left in xmit buffer before we ask for more */
#define WAKEUP_CHARS 256
/**
* uart_xmit_advance - Advance xmit buffer and account Tx'ed chars
* @up: uart_port structure describing the port
* @chars: number of characters sent
*
* This function advances the tail of circular xmit buffer by the number of
* @chars transmitted and handles accounting of transmitted bytes (into
* @up's icount.tx).
*/
static inline void uart_xmit_advance(struct uart_port *up, unsigned int chars)
{
struct circ_buf *xmit = &up->state->xmit;
xmit->tail = (xmit->tail + chars) & (UART_XMIT_SIZE - 1);
up->icount.tx += chars;
}
struct module;
struct tty_driver;
struct uart_driver {
struct module *owner;
const char *driver_name;
const char *dev_name;
int major;
int minor;
int nr;
struct console *cons;
/*
* these are private; the low level driver should not
* touch these; they should be initialised to NULL
*/
struct uart_state *state;
struct tty_driver *tty_driver;
ANDROID_KABI_RESERVE(1);
};
void uart_write_wakeup(struct uart_port *port);
/*
* Baud rate helpers.
*/
void uart_update_timeout(struct uart_port *port, unsigned int cflag,
unsigned int baud);
unsigned int uart_get_baud_rate(struct uart_port *port, struct ktermios *termios,
struct ktermios *old, unsigned int min,
unsigned int max);
unsigned int uart_get_divisor(struct uart_port *port, unsigned int baud);
/* Base timer interval for polling */
static inline int uart_poll_timeout(struct uart_port *port)
{
int timeout = port->timeout;
return timeout > 6 ? (timeout / 2 - 2) : 1;
}
/*
* Console helpers.
*/
struct earlycon_device {
struct console *con;
struct uart_port port;
char options[16]; /* e.g., 115200n8 */
unsigned int baud;
};
struct earlycon_id {
char name[15];
char name_term; /* In case compiler didn't '\0' term name */
char compatible[128];
int (*setup)(struct earlycon_device *, const char *options);
};
extern const struct earlycon_id __earlycon_table[];
extern const struct earlycon_id __earlycon_table_end[];
#if defined(CONFIG_SERIAL_EARLYCON) && !defined(MODULE)
#define EARLYCON_USED_OR_UNUSED __used
#else
#define EARLYCON_USED_OR_UNUSED __maybe_unused
#endif
#define OF_EARLYCON_DECLARE(_name, compat, fn) \
static const struct earlycon_id __UNIQUE_ID(__earlycon_##_name) \
EARLYCON_USED_OR_UNUSED __section("__earlycon_table") \
__aligned(__alignof__(struct earlycon_id)) \
= { .name = __stringify(_name), \
.compatible = compat, \
.setup = fn }
#define EARLYCON_DECLARE(_name, fn) OF_EARLYCON_DECLARE(_name, "", fn)
extern int of_setup_earlycon(const struct earlycon_id *match,
unsigned long node,
const char *options);
#ifdef CONFIG_SERIAL_EARLYCON
extern bool earlycon_acpi_spcr_enable __initdata;
int setup_earlycon(char *buf);
#else
static const bool earlycon_acpi_spcr_enable EARLYCON_USED_OR_UNUSED;
static inline int setup_earlycon(char *buf) { return 0; }
#endif
static inline bool uart_console_enabled(struct uart_port *port)
{
return uart_console(port) && (port->cons->flags & CON_ENABLED);
}
struct uart_port *uart_get_console(struct uart_port *ports, int nr,
struct console *c);
int uart_parse_earlycon(char *p, unsigned char *iotype, resource_size_t *addr,
char **options);
void uart_parse_options(const char *options, int *baud, int *parity, int *bits,
int *flow);
int uart_set_options(struct uart_port *port, struct console *co, int baud,
int parity, int bits, int flow);
struct tty_driver *uart_console_device(struct console *co, int *index);
void uart_console_write(struct uart_port *port, const char *s,
unsigned int count,
void (*putchar)(struct uart_port *, int));
/*
* Port/driver registration/removal
*/
int uart_register_driver(struct uart_driver *uart);
void uart_unregister_driver(struct uart_driver *uart);
int uart_add_one_port(struct uart_driver *reg, struct uart_port *port);
int uart_remove_one_port(struct uart_driver *reg, struct uart_port *port);
bool uart_match_port(const struct uart_port *port1,
const struct uart_port *port2);
/*
* Power Management
*/
int uart_suspend_port(struct uart_driver *reg, struct uart_port *port);
int uart_resume_port(struct uart_driver *reg, struct uart_port *port);
#define uart_circ_empty(circ) ((circ)->head == (circ)->tail)
#define uart_circ_clear(circ) ((circ)->head = (circ)->tail = 0)
#define uart_circ_chars_pending(circ) \
(CIRC_CNT((circ)->head, (circ)->tail, UART_XMIT_SIZE))
#define uart_circ_chars_free(circ) \
(CIRC_SPACE((circ)->head, (circ)->tail, UART_XMIT_SIZE))
static inline int uart_tx_stopped(struct uart_port *port)
{
struct tty_struct *tty = port->state->port.tty;
if ((tty && tty->flow.stopped) || port->hw_stopped)
return 1;
return 0;
}
static inline bool uart_cts_enabled(struct uart_port *uport)
{
return !!(uport->status & UPSTAT_CTS_ENABLE);
}
static inline bool uart_softcts_mode(struct uart_port *uport)
{
upstat_t mask = UPSTAT_CTS_ENABLE | UPSTAT_AUTOCTS;
return ((uport->status & mask) == UPSTAT_CTS_ENABLE);
}
/*
* The following are helper functions for the low level drivers.
*/
extern void uart_handle_dcd_change(struct uart_port *uport,
unsigned int status);
extern void uart_handle_cts_change(struct uart_port *uport,
unsigned int status);
extern void uart_insert_char(struct uart_port *port, unsigned int status,
unsigned int overrun, unsigned int ch, unsigned int flag);
void uart_xchar_out(struct uart_port *uport, int offset);
#ifdef CONFIG_MAGIC_SYSRQ_SERIAL
#define SYSRQ_TIMEOUT (HZ * 5)
bool uart_try_toggle_sysrq(struct uart_port *port, unsigned int ch);
static inline int uart_handle_sysrq_char(struct uart_port *port, unsigned int ch)
{
if (!port->sysrq)
return 0;
if (ch && time_before(jiffies, port->sysrq)) {
if (sysrq_mask()) {
handle_sysrq(ch);
port->sysrq = 0;
return 1;
}
if (uart_try_toggle_sysrq(port, ch))
return 1;
}
port->sysrq = 0;
return 0;
}
static inline int uart_prepare_sysrq_char(struct uart_port *port, unsigned int ch)
{
if (!port->sysrq)
return 0;
if (ch && time_before(jiffies, port->sysrq)) {
if (sysrq_mask()) {
port->sysrq_ch = ch;
port->sysrq = 0;
return 1;
}
if (uart_try_toggle_sysrq(port, ch))
return 1;
}
port->sysrq = 0;
return 0;
}
static inline void uart_unlock_and_check_sysrq(struct uart_port *port)
{
int sysrq_ch;
if (!port->has_sysrq) {
spin_unlock(&port->lock);
return;
}
sysrq_ch = port->sysrq_ch;
port->sysrq_ch = 0;
spin_unlock(&port->lock);
if (sysrq_ch)
handle_sysrq(sysrq_ch);
}
static inline void uart_unlock_and_check_sysrq_irqrestore(struct uart_port *port,
unsigned long flags)
{
int sysrq_ch;
if (!port->has_sysrq) {
spin_unlock_irqrestore(&port->lock, flags);
return;
}
sysrq_ch = port->sysrq_ch;
port->sysrq_ch = 0;
spin_unlock_irqrestore(&port->lock, flags);
if (sysrq_ch)
handle_sysrq(sysrq_ch);
}
#else /* CONFIG_MAGIC_SYSRQ_SERIAL */
static inline int uart_handle_sysrq_char(struct uart_port *port, unsigned int ch)
{
return 0;
}
static inline int uart_prepare_sysrq_char(struct uart_port *port, unsigned int ch)
{
return 0;
}
static inline void uart_unlock_and_check_sysrq(struct uart_port *port)
{
spin_unlock(&port->lock);
}
static inline void uart_unlock_and_check_sysrq_irqrestore(struct uart_port *port,
unsigned long flags)
{
spin_unlock_irqrestore(&port->lock, flags);
}
#endif /* CONFIG_MAGIC_SYSRQ_SERIAL */
/*
* We do the SysRQ and SAK checking like this...
*/
static inline int uart_handle_break(struct uart_port *port)
{
struct uart_state *state = port->state;
if (port->handle_break)
port->handle_break(port);
#ifdef CONFIG_MAGIC_SYSRQ_SERIAL
if (port->has_sysrq && uart_console(port)) {
if (!port->sysrq) {
port->sysrq = jiffies + SYSRQ_TIMEOUT;
return 1;
}
port->sysrq = 0;
}
#endif
if (port->flags & UPF_SAK)
do_SAK(state->port.tty);
return 0;
}
/*
* UART_ENABLE_MS - determine if port should enable modem status irqs
*/
#define UART_ENABLE_MS(port,cflag) ((port)->flags & UPF_HARDPPS_CD || \
(cflag) & CRTSCTS || \
!((cflag) & CLOCAL))
int uart_get_rs485_mode(struct uart_port *port);
#endif /* LINUX_SERIAL_CORE_H */