162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0+ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Base port operations for 8250/16550-type serial ports 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o. 662306a36Sopenharmony_ci * Split from 8250_core.c, Copyright (C) 2001 Russell King. 762306a36Sopenharmony_ci * 862306a36Sopenharmony_ci * A note about mapbase / membase 962306a36Sopenharmony_ci * 1062306a36Sopenharmony_ci * mapbase is the physical address of the IO port. 1162306a36Sopenharmony_ci * membase is an 'ioremapped' cookie. 1262306a36Sopenharmony_ci */ 1362306a36Sopenharmony_ci 1462306a36Sopenharmony_ci#include <linux/module.h> 1562306a36Sopenharmony_ci#include <linux/moduleparam.h> 1662306a36Sopenharmony_ci#include <linux/ioport.h> 1762306a36Sopenharmony_ci#include <linux/init.h> 1862306a36Sopenharmony_ci#include <linux/irq.h> 1962306a36Sopenharmony_ci#include <linux/console.h> 2062306a36Sopenharmony_ci#include <linux/gpio/consumer.h> 2162306a36Sopenharmony_ci#include <linux/sysrq.h> 2262306a36Sopenharmony_ci#include <linux/delay.h> 2362306a36Sopenharmony_ci#include <linux/platform_device.h> 2462306a36Sopenharmony_ci#include <linux/tty.h> 2562306a36Sopenharmony_ci#include <linux/ratelimit.h> 2662306a36Sopenharmony_ci#include <linux/tty_flip.h> 2762306a36Sopenharmony_ci#include <linux/serial.h> 2862306a36Sopenharmony_ci#include <linux/serial_8250.h> 2962306a36Sopenharmony_ci#include <linux/nmi.h> 3062306a36Sopenharmony_ci#include <linux/mutex.h> 3162306a36Sopenharmony_ci#include <linux/slab.h> 3262306a36Sopenharmony_ci#include <linux/uaccess.h> 3362306a36Sopenharmony_ci#include <linux/pm_runtime.h> 3462306a36Sopenharmony_ci#include <linux/ktime.h> 3562306a36Sopenharmony_ci 3662306a36Sopenharmony_ci#include <asm/io.h> 3762306a36Sopenharmony_ci#include <asm/irq.h> 3862306a36Sopenharmony_ci 3962306a36Sopenharmony_ci#include "8250.h" 4062306a36Sopenharmony_ci 4162306a36Sopenharmony_ci/* Nuvoton NPCM timeout register */ 4262306a36Sopenharmony_ci#define UART_NPCM_TOR 7 4362306a36Sopenharmony_ci#define UART_NPCM_TOIE BIT(7) /* Timeout Interrupt Enable */ 4462306a36Sopenharmony_ci 4562306a36Sopenharmony_ci/* 4662306a36Sopenharmony_ci * Debugging. 4762306a36Sopenharmony_ci */ 4862306a36Sopenharmony_ci#if 0 4962306a36Sopenharmony_ci#define DEBUG_AUTOCONF(fmt...) printk(fmt) 5062306a36Sopenharmony_ci#else 5162306a36Sopenharmony_ci#define DEBUG_AUTOCONF(fmt...) do { } while (0) 5262306a36Sopenharmony_ci#endif 5362306a36Sopenharmony_ci 5462306a36Sopenharmony_ci/* 5562306a36Sopenharmony_ci * Here we define the default xmit fifo size used for each type of UART. 5662306a36Sopenharmony_ci */ 5762306a36Sopenharmony_cistatic const struct serial8250_config uart_config[] = { 5862306a36Sopenharmony_ci [PORT_UNKNOWN] = { 5962306a36Sopenharmony_ci .name = "unknown", 6062306a36Sopenharmony_ci .fifo_size = 1, 6162306a36Sopenharmony_ci .tx_loadsz = 1, 6262306a36Sopenharmony_ci }, 6362306a36Sopenharmony_ci [PORT_8250] = { 6462306a36Sopenharmony_ci .name = "8250", 6562306a36Sopenharmony_ci .fifo_size = 1, 6662306a36Sopenharmony_ci .tx_loadsz = 1, 6762306a36Sopenharmony_ci }, 6862306a36Sopenharmony_ci [PORT_16450] = { 6962306a36Sopenharmony_ci .name = "16450", 7062306a36Sopenharmony_ci .fifo_size = 1, 7162306a36Sopenharmony_ci .tx_loadsz = 1, 7262306a36Sopenharmony_ci }, 7362306a36Sopenharmony_ci [PORT_16550] = { 7462306a36Sopenharmony_ci .name = "16550", 7562306a36Sopenharmony_ci .fifo_size = 1, 7662306a36Sopenharmony_ci .tx_loadsz = 1, 7762306a36Sopenharmony_ci }, 7862306a36Sopenharmony_ci [PORT_16550A] = { 7962306a36Sopenharmony_ci .name = "16550A", 8062306a36Sopenharmony_ci .fifo_size = 16, 8162306a36Sopenharmony_ci .tx_loadsz = 16, 8262306a36Sopenharmony_ci .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, 8362306a36Sopenharmony_ci .rxtrig_bytes = {1, 4, 8, 14}, 8462306a36Sopenharmony_ci .flags = UART_CAP_FIFO, 8562306a36Sopenharmony_ci }, 8662306a36Sopenharmony_ci [PORT_CIRRUS] = { 8762306a36Sopenharmony_ci .name = "Cirrus", 8862306a36Sopenharmony_ci .fifo_size = 1, 8962306a36Sopenharmony_ci .tx_loadsz = 1, 9062306a36Sopenharmony_ci }, 9162306a36Sopenharmony_ci [PORT_16650] = { 9262306a36Sopenharmony_ci .name = "ST16650", 9362306a36Sopenharmony_ci .fifo_size = 1, 9462306a36Sopenharmony_ci .tx_loadsz = 1, 9562306a36Sopenharmony_ci .flags = UART_CAP_FIFO | UART_CAP_EFR | UART_CAP_SLEEP, 9662306a36Sopenharmony_ci }, 9762306a36Sopenharmony_ci [PORT_16650V2] = { 9862306a36Sopenharmony_ci .name = "ST16650V2", 9962306a36Sopenharmony_ci .fifo_size = 32, 10062306a36Sopenharmony_ci .tx_loadsz = 16, 10162306a36Sopenharmony_ci .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_01 | 10262306a36Sopenharmony_ci UART_FCR_T_TRIG_00, 10362306a36Sopenharmony_ci .rxtrig_bytes = {8, 16, 24, 28}, 10462306a36Sopenharmony_ci .flags = UART_CAP_FIFO | UART_CAP_EFR | UART_CAP_SLEEP, 10562306a36Sopenharmony_ci }, 10662306a36Sopenharmony_ci [PORT_16750] = { 10762306a36Sopenharmony_ci .name = "TI16750", 10862306a36Sopenharmony_ci .fifo_size = 64, 10962306a36Sopenharmony_ci .tx_loadsz = 64, 11062306a36Sopenharmony_ci .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10 | 11162306a36Sopenharmony_ci UART_FCR7_64BYTE, 11262306a36Sopenharmony_ci .rxtrig_bytes = {1, 16, 32, 56}, 11362306a36Sopenharmony_ci .flags = UART_CAP_FIFO | UART_CAP_SLEEP | UART_CAP_AFE, 11462306a36Sopenharmony_ci }, 11562306a36Sopenharmony_ci [PORT_STARTECH] = { 11662306a36Sopenharmony_ci .name = "Startech", 11762306a36Sopenharmony_ci .fifo_size = 1, 11862306a36Sopenharmony_ci .tx_loadsz = 1, 11962306a36Sopenharmony_ci }, 12062306a36Sopenharmony_ci [PORT_16C950] = { 12162306a36Sopenharmony_ci .name = "16C950/954", 12262306a36Sopenharmony_ci .fifo_size = 128, 12362306a36Sopenharmony_ci .tx_loadsz = 128, 12462306a36Sopenharmony_ci .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_01, 12562306a36Sopenharmony_ci .rxtrig_bytes = {16, 32, 112, 120}, 12662306a36Sopenharmony_ci /* UART_CAP_EFR breaks billionon CF bluetooth card. */ 12762306a36Sopenharmony_ci .flags = UART_CAP_FIFO | UART_CAP_SLEEP, 12862306a36Sopenharmony_ci }, 12962306a36Sopenharmony_ci [PORT_16654] = { 13062306a36Sopenharmony_ci .name = "ST16654", 13162306a36Sopenharmony_ci .fifo_size = 64, 13262306a36Sopenharmony_ci .tx_loadsz = 32, 13362306a36Sopenharmony_ci .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_01 | 13462306a36Sopenharmony_ci UART_FCR_T_TRIG_10, 13562306a36Sopenharmony_ci .rxtrig_bytes = {8, 16, 56, 60}, 13662306a36Sopenharmony_ci .flags = UART_CAP_FIFO | UART_CAP_EFR | UART_CAP_SLEEP, 13762306a36Sopenharmony_ci }, 13862306a36Sopenharmony_ci [PORT_16850] = { 13962306a36Sopenharmony_ci .name = "XR16850", 14062306a36Sopenharmony_ci .fifo_size = 128, 14162306a36Sopenharmony_ci .tx_loadsz = 128, 14262306a36Sopenharmony_ci .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, 14362306a36Sopenharmony_ci .flags = UART_CAP_FIFO | UART_CAP_EFR | UART_CAP_SLEEP, 14462306a36Sopenharmony_ci }, 14562306a36Sopenharmony_ci [PORT_RSA] = { 14662306a36Sopenharmony_ci .name = "RSA", 14762306a36Sopenharmony_ci .fifo_size = 2048, 14862306a36Sopenharmony_ci .tx_loadsz = 2048, 14962306a36Sopenharmony_ci .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_11, 15062306a36Sopenharmony_ci .flags = UART_CAP_FIFO, 15162306a36Sopenharmony_ci }, 15262306a36Sopenharmony_ci [PORT_NS16550A] = { 15362306a36Sopenharmony_ci .name = "NS16550A", 15462306a36Sopenharmony_ci .fifo_size = 16, 15562306a36Sopenharmony_ci .tx_loadsz = 16, 15662306a36Sopenharmony_ci .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, 15762306a36Sopenharmony_ci .flags = UART_CAP_FIFO | UART_NATSEMI, 15862306a36Sopenharmony_ci }, 15962306a36Sopenharmony_ci [PORT_XSCALE] = { 16062306a36Sopenharmony_ci .name = "XScale", 16162306a36Sopenharmony_ci .fifo_size = 32, 16262306a36Sopenharmony_ci .tx_loadsz = 32, 16362306a36Sopenharmony_ci .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, 16462306a36Sopenharmony_ci .flags = UART_CAP_FIFO | UART_CAP_UUE | UART_CAP_RTOIE, 16562306a36Sopenharmony_ci }, 16662306a36Sopenharmony_ci [PORT_OCTEON] = { 16762306a36Sopenharmony_ci .name = "OCTEON", 16862306a36Sopenharmony_ci .fifo_size = 64, 16962306a36Sopenharmony_ci .tx_loadsz = 64, 17062306a36Sopenharmony_ci .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, 17162306a36Sopenharmony_ci .flags = UART_CAP_FIFO, 17262306a36Sopenharmony_ci }, 17362306a36Sopenharmony_ci [PORT_AR7] = { 17462306a36Sopenharmony_ci .name = "AR7", 17562306a36Sopenharmony_ci .fifo_size = 16, 17662306a36Sopenharmony_ci .tx_loadsz = 16, 17762306a36Sopenharmony_ci .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_00, 17862306a36Sopenharmony_ci .flags = UART_CAP_FIFO /* | UART_CAP_AFE */, 17962306a36Sopenharmony_ci }, 18062306a36Sopenharmony_ci [PORT_U6_16550A] = { 18162306a36Sopenharmony_ci .name = "U6_16550A", 18262306a36Sopenharmony_ci .fifo_size = 64, 18362306a36Sopenharmony_ci .tx_loadsz = 64, 18462306a36Sopenharmony_ci .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, 18562306a36Sopenharmony_ci .flags = UART_CAP_FIFO | UART_CAP_AFE, 18662306a36Sopenharmony_ci }, 18762306a36Sopenharmony_ci [PORT_TEGRA] = { 18862306a36Sopenharmony_ci .name = "Tegra", 18962306a36Sopenharmony_ci .fifo_size = 32, 19062306a36Sopenharmony_ci .tx_loadsz = 8, 19162306a36Sopenharmony_ci .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_01 | 19262306a36Sopenharmony_ci UART_FCR_T_TRIG_01, 19362306a36Sopenharmony_ci .rxtrig_bytes = {1, 4, 8, 14}, 19462306a36Sopenharmony_ci .flags = UART_CAP_FIFO | UART_CAP_RTOIE, 19562306a36Sopenharmony_ci }, 19662306a36Sopenharmony_ci [PORT_XR17D15X] = { 19762306a36Sopenharmony_ci .name = "XR17D15X", 19862306a36Sopenharmony_ci .fifo_size = 64, 19962306a36Sopenharmony_ci .tx_loadsz = 64, 20062306a36Sopenharmony_ci .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, 20162306a36Sopenharmony_ci .flags = UART_CAP_FIFO | UART_CAP_AFE | UART_CAP_EFR | 20262306a36Sopenharmony_ci UART_CAP_SLEEP, 20362306a36Sopenharmony_ci }, 20462306a36Sopenharmony_ci [PORT_XR17V35X] = { 20562306a36Sopenharmony_ci .name = "XR17V35X", 20662306a36Sopenharmony_ci .fifo_size = 256, 20762306a36Sopenharmony_ci .tx_loadsz = 256, 20862306a36Sopenharmony_ci .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_11 | 20962306a36Sopenharmony_ci UART_FCR_T_TRIG_11, 21062306a36Sopenharmony_ci .flags = UART_CAP_FIFO | UART_CAP_AFE | UART_CAP_EFR | 21162306a36Sopenharmony_ci UART_CAP_SLEEP, 21262306a36Sopenharmony_ci }, 21362306a36Sopenharmony_ci [PORT_LPC3220] = { 21462306a36Sopenharmony_ci .name = "LPC3220", 21562306a36Sopenharmony_ci .fifo_size = 64, 21662306a36Sopenharmony_ci .tx_loadsz = 32, 21762306a36Sopenharmony_ci .fcr = UART_FCR_DMA_SELECT | UART_FCR_ENABLE_FIFO | 21862306a36Sopenharmony_ci UART_FCR_R_TRIG_00 | UART_FCR_T_TRIG_00, 21962306a36Sopenharmony_ci .flags = UART_CAP_FIFO, 22062306a36Sopenharmony_ci }, 22162306a36Sopenharmony_ci [PORT_BRCM_TRUMANAGE] = { 22262306a36Sopenharmony_ci .name = "TruManage", 22362306a36Sopenharmony_ci .fifo_size = 1, 22462306a36Sopenharmony_ci .tx_loadsz = 1024, 22562306a36Sopenharmony_ci .flags = UART_CAP_HFIFO, 22662306a36Sopenharmony_ci }, 22762306a36Sopenharmony_ci [PORT_8250_CIR] = { 22862306a36Sopenharmony_ci .name = "CIR port" 22962306a36Sopenharmony_ci }, 23062306a36Sopenharmony_ci [PORT_ALTR_16550_F32] = { 23162306a36Sopenharmony_ci .name = "Altera 16550 FIFO32", 23262306a36Sopenharmony_ci .fifo_size = 32, 23362306a36Sopenharmony_ci .tx_loadsz = 32, 23462306a36Sopenharmony_ci .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, 23562306a36Sopenharmony_ci .rxtrig_bytes = {1, 8, 16, 30}, 23662306a36Sopenharmony_ci .flags = UART_CAP_FIFO | UART_CAP_AFE, 23762306a36Sopenharmony_ci }, 23862306a36Sopenharmony_ci [PORT_ALTR_16550_F64] = { 23962306a36Sopenharmony_ci .name = "Altera 16550 FIFO64", 24062306a36Sopenharmony_ci .fifo_size = 64, 24162306a36Sopenharmony_ci .tx_loadsz = 64, 24262306a36Sopenharmony_ci .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, 24362306a36Sopenharmony_ci .rxtrig_bytes = {1, 16, 32, 62}, 24462306a36Sopenharmony_ci .flags = UART_CAP_FIFO | UART_CAP_AFE, 24562306a36Sopenharmony_ci }, 24662306a36Sopenharmony_ci [PORT_ALTR_16550_F128] = { 24762306a36Sopenharmony_ci .name = "Altera 16550 FIFO128", 24862306a36Sopenharmony_ci .fifo_size = 128, 24962306a36Sopenharmony_ci .tx_loadsz = 128, 25062306a36Sopenharmony_ci .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, 25162306a36Sopenharmony_ci .rxtrig_bytes = {1, 32, 64, 126}, 25262306a36Sopenharmony_ci .flags = UART_CAP_FIFO | UART_CAP_AFE, 25362306a36Sopenharmony_ci }, 25462306a36Sopenharmony_ci /* 25562306a36Sopenharmony_ci * tx_loadsz is set to 63-bytes instead of 64-bytes to implement 25662306a36Sopenharmony_ci * workaround of errata A-008006 which states that tx_loadsz should 25762306a36Sopenharmony_ci * be configured less than Maximum supported fifo bytes. 25862306a36Sopenharmony_ci */ 25962306a36Sopenharmony_ci [PORT_16550A_FSL64] = { 26062306a36Sopenharmony_ci .name = "16550A_FSL64", 26162306a36Sopenharmony_ci .fifo_size = 64, 26262306a36Sopenharmony_ci .tx_loadsz = 63, 26362306a36Sopenharmony_ci .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10 | 26462306a36Sopenharmony_ci UART_FCR7_64BYTE, 26562306a36Sopenharmony_ci .flags = UART_CAP_FIFO | UART_CAP_NOTEMT, 26662306a36Sopenharmony_ci }, 26762306a36Sopenharmony_ci [PORT_RT2880] = { 26862306a36Sopenharmony_ci .name = "Palmchip BK-3103", 26962306a36Sopenharmony_ci .fifo_size = 16, 27062306a36Sopenharmony_ci .tx_loadsz = 16, 27162306a36Sopenharmony_ci .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, 27262306a36Sopenharmony_ci .rxtrig_bytes = {1, 4, 8, 14}, 27362306a36Sopenharmony_ci .flags = UART_CAP_FIFO, 27462306a36Sopenharmony_ci }, 27562306a36Sopenharmony_ci [PORT_DA830] = { 27662306a36Sopenharmony_ci .name = "TI DA8xx/66AK2x", 27762306a36Sopenharmony_ci .fifo_size = 16, 27862306a36Sopenharmony_ci .tx_loadsz = 16, 27962306a36Sopenharmony_ci .fcr = UART_FCR_DMA_SELECT | UART_FCR_ENABLE_FIFO | 28062306a36Sopenharmony_ci UART_FCR_R_TRIG_10, 28162306a36Sopenharmony_ci .rxtrig_bytes = {1, 4, 8, 14}, 28262306a36Sopenharmony_ci .flags = UART_CAP_FIFO | UART_CAP_AFE, 28362306a36Sopenharmony_ci }, 28462306a36Sopenharmony_ci [PORT_MTK_BTIF] = { 28562306a36Sopenharmony_ci .name = "MediaTek BTIF", 28662306a36Sopenharmony_ci .fifo_size = 16, 28762306a36Sopenharmony_ci .tx_loadsz = 16, 28862306a36Sopenharmony_ci .fcr = UART_FCR_ENABLE_FIFO | 28962306a36Sopenharmony_ci UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT, 29062306a36Sopenharmony_ci .flags = UART_CAP_FIFO, 29162306a36Sopenharmony_ci }, 29262306a36Sopenharmony_ci [PORT_NPCM] = { 29362306a36Sopenharmony_ci .name = "Nuvoton 16550", 29462306a36Sopenharmony_ci .fifo_size = 16, 29562306a36Sopenharmony_ci .tx_loadsz = 16, 29662306a36Sopenharmony_ci .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10 | 29762306a36Sopenharmony_ci UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT, 29862306a36Sopenharmony_ci .rxtrig_bytes = {1, 4, 8, 14}, 29962306a36Sopenharmony_ci .flags = UART_CAP_FIFO, 30062306a36Sopenharmony_ci }, 30162306a36Sopenharmony_ci [PORT_SUNIX] = { 30262306a36Sopenharmony_ci .name = "Sunix", 30362306a36Sopenharmony_ci .fifo_size = 128, 30462306a36Sopenharmony_ci .tx_loadsz = 128, 30562306a36Sopenharmony_ci .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, 30662306a36Sopenharmony_ci .rxtrig_bytes = {1, 32, 64, 112}, 30762306a36Sopenharmony_ci .flags = UART_CAP_FIFO | UART_CAP_SLEEP, 30862306a36Sopenharmony_ci }, 30962306a36Sopenharmony_ci [PORT_ASPEED_VUART] = { 31062306a36Sopenharmony_ci .name = "ASPEED VUART", 31162306a36Sopenharmony_ci .fifo_size = 16, 31262306a36Sopenharmony_ci .tx_loadsz = 16, 31362306a36Sopenharmony_ci .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_00, 31462306a36Sopenharmony_ci .rxtrig_bytes = {1, 4, 8, 14}, 31562306a36Sopenharmony_ci .flags = UART_CAP_FIFO, 31662306a36Sopenharmony_ci }, 31762306a36Sopenharmony_ci [PORT_MCHP16550A] = { 31862306a36Sopenharmony_ci .name = "MCHP16550A", 31962306a36Sopenharmony_ci .fifo_size = 256, 32062306a36Sopenharmony_ci .tx_loadsz = 256, 32162306a36Sopenharmony_ci .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_01, 32262306a36Sopenharmony_ci .rxtrig_bytes = {2, 66, 130, 194}, 32362306a36Sopenharmony_ci .flags = UART_CAP_FIFO, 32462306a36Sopenharmony_ci }, 32562306a36Sopenharmony_ci [PORT_BCM7271] = { 32662306a36Sopenharmony_ci .name = "Broadcom BCM7271 UART", 32762306a36Sopenharmony_ci .fifo_size = 32, 32862306a36Sopenharmony_ci .tx_loadsz = 32, 32962306a36Sopenharmony_ci .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_01, 33062306a36Sopenharmony_ci .rxtrig_bytes = {1, 8, 16, 30}, 33162306a36Sopenharmony_ci .flags = UART_CAP_FIFO | UART_CAP_AFE, 33262306a36Sopenharmony_ci }, 33362306a36Sopenharmony_ci}; 33462306a36Sopenharmony_ci 33562306a36Sopenharmony_ci/* Uart divisor latch read */ 33662306a36Sopenharmony_cistatic u32 default_serial_dl_read(struct uart_8250_port *up) 33762306a36Sopenharmony_ci{ 33862306a36Sopenharmony_ci /* Assign these in pieces to truncate any bits above 7. */ 33962306a36Sopenharmony_ci unsigned char dll = serial_in(up, UART_DLL); 34062306a36Sopenharmony_ci unsigned char dlm = serial_in(up, UART_DLM); 34162306a36Sopenharmony_ci 34262306a36Sopenharmony_ci return dll | dlm << 8; 34362306a36Sopenharmony_ci} 34462306a36Sopenharmony_ci 34562306a36Sopenharmony_ci/* Uart divisor latch write */ 34662306a36Sopenharmony_cistatic void default_serial_dl_write(struct uart_8250_port *up, u32 value) 34762306a36Sopenharmony_ci{ 34862306a36Sopenharmony_ci serial_out(up, UART_DLL, value & 0xff); 34962306a36Sopenharmony_ci serial_out(up, UART_DLM, value >> 8 & 0xff); 35062306a36Sopenharmony_ci} 35162306a36Sopenharmony_ci 35262306a36Sopenharmony_cistatic unsigned int hub6_serial_in(struct uart_port *p, int offset) 35362306a36Sopenharmony_ci{ 35462306a36Sopenharmony_ci offset = offset << p->regshift; 35562306a36Sopenharmony_ci outb(p->hub6 - 1 + offset, p->iobase); 35662306a36Sopenharmony_ci return inb(p->iobase + 1); 35762306a36Sopenharmony_ci} 35862306a36Sopenharmony_ci 35962306a36Sopenharmony_cistatic void hub6_serial_out(struct uart_port *p, int offset, int value) 36062306a36Sopenharmony_ci{ 36162306a36Sopenharmony_ci offset = offset << p->regshift; 36262306a36Sopenharmony_ci outb(p->hub6 - 1 + offset, p->iobase); 36362306a36Sopenharmony_ci outb(value, p->iobase + 1); 36462306a36Sopenharmony_ci} 36562306a36Sopenharmony_ci 36662306a36Sopenharmony_cistatic unsigned int mem_serial_in(struct uart_port *p, int offset) 36762306a36Sopenharmony_ci{ 36862306a36Sopenharmony_ci offset = offset << p->regshift; 36962306a36Sopenharmony_ci return readb(p->membase + offset); 37062306a36Sopenharmony_ci} 37162306a36Sopenharmony_ci 37262306a36Sopenharmony_cistatic void mem_serial_out(struct uart_port *p, int offset, int value) 37362306a36Sopenharmony_ci{ 37462306a36Sopenharmony_ci offset = offset << p->regshift; 37562306a36Sopenharmony_ci writeb(value, p->membase + offset); 37662306a36Sopenharmony_ci} 37762306a36Sopenharmony_ci 37862306a36Sopenharmony_cistatic void mem16_serial_out(struct uart_port *p, int offset, int value) 37962306a36Sopenharmony_ci{ 38062306a36Sopenharmony_ci offset = offset << p->regshift; 38162306a36Sopenharmony_ci writew(value, p->membase + offset); 38262306a36Sopenharmony_ci} 38362306a36Sopenharmony_ci 38462306a36Sopenharmony_cistatic unsigned int mem16_serial_in(struct uart_port *p, int offset) 38562306a36Sopenharmony_ci{ 38662306a36Sopenharmony_ci offset = offset << p->regshift; 38762306a36Sopenharmony_ci return readw(p->membase + offset); 38862306a36Sopenharmony_ci} 38962306a36Sopenharmony_ci 39062306a36Sopenharmony_cistatic void mem32_serial_out(struct uart_port *p, int offset, int value) 39162306a36Sopenharmony_ci{ 39262306a36Sopenharmony_ci offset = offset << p->regshift; 39362306a36Sopenharmony_ci writel(value, p->membase + offset); 39462306a36Sopenharmony_ci} 39562306a36Sopenharmony_ci 39662306a36Sopenharmony_cistatic unsigned int mem32_serial_in(struct uart_port *p, int offset) 39762306a36Sopenharmony_ci{ 39862306a36Sopenharmony_ci offset = offset << p->regshift; 39962306a36Sopenharmony_ci return readl(p->membase + offset); 40062306a36Sopenharmony_ci} 40162306a36Sopenharmony_ci 40262306a36Sopenharmony_cistatic void mem32be_serial_out(struct uart_port *p, int offset, int value) 40362306a36Sopenharmony_ci{ 40462306a36Sopenharmony_ci offset = offset << p->regshift; 40562306a36Sopenharmony_ci iowrite32be(value, p->membase + offset); 40662306a36Sopenharmony_ci} 40762306a36Sopenharmony_ci 40862306a36Sopenharmony_cistatic unsigned int mem32be_serial_in(struct uart_port *p, int offset) 40962306a36Sopenharmony_ci{ 41062306a36Sopenharmony_ci offset = offset << p->regshift; 41162306a36Sopenharmony_ci return ioread32be(p->membase + offset); 41262306a36Sopenharmony_ci} 41362306a36Sopenharmony_ci 41462306a36Sopenharmony_cistatic unsigned int io_serial_in(struct uart_port *p, int offset) 41562306a36Sopenharmony_ci{ 41662306a36Sopenharmony_ci offset = offset << p->regshift; 41762306a36Sopenharmony_ci return inb(p->iobase + offset); 41862306a36Sopenharmony_ci} 41962306a36Sopenharmony_ci 42062306a36Sopenharmony_cistatic void io_serial_out(struct uart_port *p, int offset, int value) 42162306a36Sopenharmony_ci{ 42262306a36Sopenharmony_ci offset = offset << p->regshift; 42362306a36Sopenharmony_ci outb(value, p->iobase + offset); 42462306a36Sopenharmony_ci} 42562306a36Sopenharmony_ci 42662306a36Sopenharmony_cistatic int serial8250_default_handle_irq(struct uart_port *port); 42762306a36Sopenharmony_ci 42862306a36Sopenharmony_cistatic void set_io_from_upio(struct uart_port *p) 42962306a36Sopenharmony_ci{ 43062306a36Sopenharmony_ci struct uart_8250_port *up = up_to_u8250p(p); 43162306a36Sopenharmony_ci 43262306a36Sopenharmony_ci up->dl_read = default_serial_dl_read; 43362306a36Sopenharmony_ci up->dl_write = default_serial_dl_write; 43462306a36Sopenharmony_ci 43562306a36Sopenharmony_ci switch (p->iotype) { 43662306a36Sopenharmony_ci case UPIO_HUB6: 43762306a36Sopenharmony_ci p->serial_in = hub6_serial_in; 43862306a36Sopenharmony_ci p->serial_out = hub6_serial_out; 43962306a36Sopenharmony_ci break; 44062306a36Sopenharmony_ci 44162306a36Sopenharmony_ci case UPIO_MEM: 44262306a36Sopenharmony_ci p->serial_in = mem_serial_in; 44362306a36Sopenharmony_ci p->serial_out = mem_serial_out; 44462306a36Sopenharmony_ci break; 44562306a36Sopenharmony_ci 44662306a36Sopenharmony_ci case UPIO_MEM16: 44762306a36Sopenharmony_ci p->serial_in = mem16_serial_in; 44862306a36Sopenharmony_ci p->serial_out = mem16_serial_out; 44962306a36Sopenharmony_ci break; 45062306a36Sopenharmony_ci 45162306a36Sopenharmony_ci case UPIO_MEM32: 45262306a36Sopenharmony_ci p->serial_in = mem32_serial_in; 45362306a36Sopenharmony_ci p->serial_out = mem32_serial_out; 45462306a36Sopenharmony_ci break; 45562306a36Sopenharmony_ci 45662306a36Sopenharmony_ci case UPIO_MEM32BE: 45762306a36Sopenharmony_ci p->serial_in = mem32be_serial_in; 45862306a36Sopenharmony_ci p->serial_out = mem32be_serial_out; 45962306a36Sopenharmony_ci break; 46062306a36Sopenharmony_ci 46162306a36Sopenharmony_ci default: 46262306a36Sopenharmony_ci p->serial_in = io_serial_in; 46362306a36Sopenharmony_ci p->serial_out = io_serial_out; 46462306a36Sopenharmony_ci break; 46562306a36Sopenharmony_ci } 46662306a36Sopenharmony_ci /* Remember loaded iotype */ 46762306a36Sopenharmony_ci up->cur_iotype = p->iotype; 46862306a36Sopenharmony_ci p->handle_irq = serial8250_default_handle_irq; 46962306a36Sopenharmony_ci} 47062306a36Sopenharmony_ci 47162306a36Sopenharmony_cistatic void 47262306a36Sopenharmony_ciserial_port_out_sync(struct uart_port *p, int offset, int value) 47362306a36Sopenharmony_ci{ 47462306a36Sopenharmony_ci switch (p->iotype) { 47562306a36Sopenharmony_ci case UPIO_MEM: 47662306a36Sopenharmony_ci case UPIO_MEM16: 47762306a36Sopenharmony_ci case UPIO_MEM32: 47862306a36Sopenharmony_ci case UPIO_MEM32BE: 47962306a36Sopenharmony_ci case UPIO_AU: 48062306a36Sopenharmony_ci p->serial_out(p, offset, value); 48162306a36Sopenharmony_ci p->serial_in(p, UART_LCR); /* safe, no side-effects */ 48262306a36Sopenharmony_ci break; 48362306a36Sopenharmony_ci default: 48462306a36Sopenharmony_ci p->serial_out(p, offset, value); 48562306a36Sopenharmony_ci } 48662306a36Sopenharmony_ci} 48762306a36Sopenharmony_ci 48862306a36Sopenharmony_ci/* 48962306a36Sopenharmony_ci * FIFO support. 49062306a36Sopenharmony_ci */ 49162306a36Sopenharmony_cistatic void serial8250_clear_fifos(struct uart_8250_port *p) 49262306a36Sopenharmony_ci{ 49362306a36Sopenharmony_ci if (p->capabilities & UART_CAP_FIFO) { 49462306a36Sopenharmony_ci serial_out(p, UART_FCR, UART_FCR_ENABLE_FIFO); 49562306a36Sopenharmony_ci serial_out(p, UART_FCR, UART_FCR_ENABLE_FIFO | 49662306a36Sopenharmony_ci UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT); 49762306a36Sopenharmony_ci serial_out(p, UART_FCR, 0); 49862306a36Sopenharmony_ci } 49962306a36Sopenharmony_ci} 50062306a36Sopenharmony_ci 50162306a36Sopenharmony_cistatic enum hrtimer_restart serial8250_em485_handle_start_tx(struct hrtimer *t); 50262306a36Sopenharmony_cistatic enum hrtimer_restart serial8250_em485_handle_stop_tx(struct hrtimer *t); 50362306a36Sopenharmony_ci 50462306a36Sopenharmony_civoid serial8250_clear_and_reinit_fifos(struct uart_8250_port *p) 50562306a36Sopenharmony_ci{ 50662306a36Sopenharmony_ci serial8250_clear_fifos(p); 50762306a36Sopenharmony_ci serial_out(p, UART_FCR, p->fcr); 50862306a36Sopenharmony_ci} 50962306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(serial8250_clear_and_reinit_fifos); 51062306a36Sopenharmony_ci 51162306a36Sopenharmony_civoid serial8250_rpm_get(struct uart_8250_port *p) 51262306a36Sopenharmony_ci{ 51362306a36Sopenharmony_ci if (!(p->capabilities & UART_CAP_RPM)) 51462306a36Sopenharmony_ci return; 51562306a36Sopenharmony_ci pm_runtime_get_sync(p->port.dev); 51662306a36Sopenharmony_ci} 51762306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(serial8250_rpm_get); 51862306a36Sopenharmony_ci 51962306a36Sopenharmony_civoid serial8250_rpm_put(struct uart_8250_port *p) 52062306a36Sopenharmony_ci{ 52162306a36Sopenharmony_ci if (!(p->capabilities & UART_CAP_RPM)) 52262306a36Sopenharmony_ci return; 52362306a36Sopenharmony_ci pm_runtime_mark_last_busy(p->port.dev); 52462306a36Sopenharmony_ci pm_runtime_put_autosuspend(p->port.dev); 52562306a36Sopenharmony_ci} 52662306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(serial8250_rpm_put); 52762306a36Sopenharmony_ci 52862306a36Sopenharmony_ci/** 52962306a36Sopenharmony_ci * serial8250_em485_init() - put uart_8250_port into rs485 emulating 53062306a36Sopenharmony_ci * @p: uart_8250_port port instance 53162306a36Sopenharmony_ci * 53262306a36Sopenharmony_ci * The function is used to start rs485 software emulating on the 53362306a36Sopenharmony_ci * &struct uart_8250_port* @p. Namely, RTS is switched before/after 53462306a36Sopenharmony_ci * transmission. The function is idempotent, so it is safe to call it 53562306a36Sopenharmony_ci * multiple times. 53662306a36Sopenharmony_ci * 53762306a36Sopenharmony_ci * The caller MUST enable interrupt on empty shift register before 53862306a36Sopenharmony_ci * calling serial8250_em485_init(). This interrupt is not a part of 53962306a36Sopenharmony_ci * 8250 standard, but implementation defined. 54062306a36Sopenharmony_ci * 54162306a36Sopenharmony_ci * The function is supposed to be called from .rs485_config callback 54262306a36Sopenharmony_ci * or from any other callback protected with p->port.lock spinlock. 54362306a36Sopenharmony_ci * 54462306a36Sopenharmony_ci * See also serial8250_em485_destroy() 54562306a36Sopenharmony_ci * 54662306a36Sopenharmony_ci * Return 0 - success, -errno - otherwise 54762306a36Sopenharmony_ci */ 54862306a36Sopenharmony_cistatic int serial8250_em485_init(struct uart_8250_port *p) 54962306a36Sopenharmony_ci{ 55062306a36Sopenharmony_ci /* Port locked to synchronize UART_IER access against the console. */ 55162306a36Sopenharmony_ci lockdep_assert_held_once(&p->port.lock); 55262306a36Sopenharmony_ci 55362306a36Sopenharmony_ci if (p->em485) 55462306a36Sopenharmony_ci goto deassert_rts; 55562306a36Sopenharmony_ci 55662306a36Sopenharmony_ci p->em485 = kmalloc(sizeof(struct uart_8250_em485), GFP_ATOMIC); 55762306a36Sopenharmony_ci if (!p->em485) 55862306a36Sopenharmony_ci return -ENOMEM; 55962306a36Sopenharmony_ci 56062306a36Sopenharmony_ci hrtimer_init(&p->em485->stop_tx_timer, CLOCK_MONOTONIC, 56162306a36Sopenharmony_ci HRTIMER_MODE_REL); 56262306a36Sopenharmony_ci hrtimer_init(&p->em485->start_tx_timer, CLOCK_MONOTONIC, 56362306a36Sopenharmony_ci HRTIMER_MODE_REL); 56462306a36Sopenharmony_ci p->em485->stop_tx_timer.function = &serial8250_em485_handle_stop_tx; 56562306a36Sopenharmony_ci p->em485->start_tx_timer.function = &serial8250_em485_handle_start_tx; 56662306a36Sopenharmony_ci p->em485->port = p; 56762306a36Sopenharmony_ci p->em485->active_timer = NULL; 56862306a36Sopenharmony_ci p->em485->tx_stopped = true; 56962306a36Sopenharmony_ci 57062306a36Sopenharmony_cideassert_rts: 57162306a36Sopenharmony_ci if (p->em485->tx_stopped) 57262306a36Sopenharmony_ci p->rs485_stop_tx(p); 57362306a36Sopenharmony_ci 57462306a36Sopenharmony_ci return 0; 57562306a36Sopenharmony_ci} 57662306a36Sopenharmony_ci 57762306a36Sopenharmony_ci/** 57862306a36Sopenharmony_ci * serial8250_em485_destroy() - put uart_8250_port into normal state 57962306a36Sopenharmony_ci * @p: uart_8250_port port instance 58062306a36Sopenharmony_ci * 58162306a36Sopenharmony_ci * The function is used to stop rs485 software emulating on the 58262306a36Sopenharmony_ci * &struct uart_8250_port* @p. The function is idempotent, so it is safe to 58362306a36Sopenharmony_ci * call it multiple times. 58462306a36Sopenharmony_ci * 58562306a36Sopenharmony_ci * The function is supposed to be called from .rs485_config callback 58662306a36Sopenharmony_ci * or from any other callback protected with p->port.lock spinlock. 58762306a36Sopenharmony_ci * 58862306a36Sopenharmony_ci * See also serial8250_em485_init() 58962306a36Sopenharmony_ci */ 59062306a36Sopenharmony_civoid serial8250_em485_destroy(struct uart_8250_port *p) 59162306a36Sopenharmony_ci{ 59262306a36Sopenharmony_ci if (!p->em485) 59362306a36Sopenharmony_ci return; 59462306a36Sopenharmony_ci 59562306a36Sopenharmony_ci hrtimer_cancel(&p->em485->start_tx_timer); 59662306a36Sopenharmony_ci hrtimer_cancel(&p->em485->stop_tx_timer); 59762306a36Sopenharmony_ci 59862306a36Sopenharmony_ci kfree(p->em485); 59962306a36Sopenharmony_ci p->em485 = NULL; 60062306a36Sopenharmony_ci} 60162306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(serial8250_em485_destroy); 60262306a36Sopenharmony_ci 60362306a36Sopenharmony_cistruct serial_rs485 serial8250_em485_supported = { 60462306a36Sopenharmony_ci .flags = SER_RS485_ENABLED | SER_RS485_RTS_ON_SEND | SER_RS485_RTS_AFTER_SEND | 60562306a36Sopenharmony_ci SER_RS485_TERMINATE_BUS | SER_RS485_RX_DURING_TX, 60662306a36Sopenharmony_ci .delay_rts_before_send = 1, 60762306a36Sopenharmony_ci .delay_rts_after_send = 1, 60862306a36Sopenharmony_ci}; 60962306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(serial8250_em485_supported); 61062306a36Sopenharmony_ci 61162306a36Sopenharmony_ci/** 61262306a36Sopenharmony_ci * serial8250_em485_config() - generic ->rs485_config() callback 61362306a36Sopenharmony_ci * @port: uart port 61462306a36Sopenharmony_ci * @termios: termios structure 61562306a36Sopenharmony_ci * @rs485: rs485 settings 61662306a36Sopenharmony_ci * 61762306a36Sopenharmony_ci * Generic callback usable by 8250 uart drivers to activate rs485 settings 61862306a36Sopenharmony_ci * if the uart is incapable of driving RTS as a Transmit Enable signal in 61962306a36Sopenharmony_ci * hardware, relying on software emulation instead. 62062306a36Sopenharmony_ci */ 62162306a36Sopenharmony_ciint serial8250_em485_config(struct uart_port *port, struct ktermios *termios, 62262306a36Sopenharmony_ci struct serial_rs485 *rs485) 62362306a36Sopenharmony_ci{ 62462306a36Sopenharmony_ci struct uart_8250_port *up = up_to_u8250p(port); 62562306a36Sopenharmony_ci 62662306a36Sopenharmony_ci /* pick sane settings if the user hasn't */ 62762306a36Sopenharmony_ci if (!!(rs485->flags & SER_RS485_RTS_ON_SEND) == 62862306a36Sopenharmony_ci !!(rs485->flags & SER_RS485_RTS_AFTER_SEND)) { 62962306a36Sopenharmony_ci rs485->flags |= SER_RS485_RTS_ON_SEND; 63062306a36Sopenharmony_ci rs485->flags &= ~SER_RS485_RTS_AFTER_SEND; 63162306a36Sopenharmony_ci } 63262306a36Sopenharmony_ci 63362306a36Sopenharmony_ci /* 63462306a36Sopenharmony_ci * Both serial8250_em485_init() and serial8250_em485_destroy() 63562306a36Sopenharmony_ci * are idempotent. 63662306a36Sopenharmony_ci */ 63762306a36Sopenharmony_ci if (rs485->flags & SER_RS485_ENABLED) 63862306a36Sopenharmony_ci return serial8250_em485_init(up); 63962306a36Sopenharmony_ci 64062306a36Sopenharmony_ci serial8250_em485_destroy(up); 64162306a36Sopenharmony_ci return 0; 64262306a36Sopenharmony_ci} 64362306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(serial8250_em485_config); 64462306a36Sopenharmony_ci 64562306a36Sopenharmony_ci/* 64662306a36Sopenharmony_ci * These two wrappers ensure that enable_runtime_pm_tx() can be called more than 64762306a36Sopenharmony_ci * once and disable_runtime_pm_tx() will still disable RPM because the fifo is 64862306a36Sopenharmony_ci * empty and the HW can idle again. 64962306a36Sopenharmony_ci */ 65062306a36Sopenharmony_civoid serial8250_rpm_get_tx(struct uart_8250_port *p) 65162306a36Sopenharmony_ci{ 65262306a36Sopenharmony_ci unsigned char rpm_active; 65362306a36Sopenharmony_ci 65462306a36Sopenharmony_ci if (!(p->capabilities & UART_CAP_RPM)) 65562306a36Sopenharmony_ci return; 65662306a36Sopenharmony_ci 65762306a36Sopenharmony_ci rpm_active = xchg(&p->rpm_tx_active, 1); 65862306a36Sopenharmony_ci if (rpm_active) 65962306a36Sopenharmony_ci return; 66062306a36Sopenharmony_ci pm_runtime_get_sync(p->port.dev); 66162306a36Sopenharmony_ci} 66262306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(serial8250_rpm_get_tx); 66362306a36Sopenharmony_ci 66462306a36Sopenharmony_civoid serial8250_rpm_put_tx(struct uart_8250_port *p) 66562306a36Sopenharmony_ci{ 66662306a36Sopenharmony_ci unsigned char rpm_active; 66762306a36Sopenharmony_ci 66862306a36Sopenharmony_ci if (!(p->capabilities & UART_CAP_RPM)) 66962306a36Sopenharmony_ci return; 67062306a36Sopenharmony_ci 67162306a36Sopenharmony_ci rpm_active = xchg(&p->rpm_tx_active, 0); 67262306a36Sopenharmony_ci if (!rpm_active) 67362306a36Sopenharmony_ci return; 67462306a36Sopenharmony_ci pm_runtime_mark_last_busy(p->port.dev); 67562306a36Sopenharmony_ci pm_runtime_put_autosuspend(p->port.dev); 67662306a36Sopenharmony_ci} 67762306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(serial8250_rpm_put_tx); 67862306a36Sopenharmony_ci 67962306a36Sopenharmony_ci/* 68062306a36Sopenharmony_ci * IER sleep support. UARTs which have EFRs need the "extended 68162306a36Sopenharmony_ci * capability" bit enabled. Note that on XR16C850s, we need to 68262306a36Sopenharmony_ci * reset LCR to write to IER. 68362306a36Sopenharmony_ci */ 68462306a36Sopenharmony_cistatic void serial8250_set_sleep(struct uart_8250_port *p, int sleep) 68562306a36Sopenharmony_ci{ 68662306a36Sopenharmony_ci unsigned char lcr = 0, efr = 0; 68762306a36Sopenharmony_ci 68862306a36Sopenharmony_ci serial8250_rpm_get(p); 68962306a36Sopenharmony_ci 69062306a36Sopenharmony_ci if (p->capabilities & UART_CAP_SLEEP) { 69162306a36Sopenharmony_ci /* Synchronize UART_IER access against the console. */ 69262306a36Sopenharmony_ci spin_lock_irq(&p->port.lock); 69362306a36Sopenharmony_ci if (p->capabilities & UART_CAP_EFR) { 69462306a36Sopenharmony_ci lcr = serial_in(p, UART_LCR); 69562306a36Sopenharmony_ci efr = serial_in(p, UART_EFR); 69662306a36Sopenharmony_ci serial_out(p, UART_LCR, UART_LCR_CONF_MODE_B); 69762306a36Sopenharmony_ci serial_out(p, UART_EFR, UART_EFR_ECB); 69862306a36Sopenharmony_ci serial_out(p, UART_LCR, 0); 69962306a36Sopenharmony_ci } 70062306a36Sopenharmony_ci serial_out(p, UART_IER, sleep ? UART_IERX_SLEEP : 0); 70162306a36Sopenharmony_ci if (p->capabilities & UART_CAP_EFR) { 70262306a36Sopenharmony_ci serial_out(p, UART_LCR, UART_LCR_CONF_MODE_B); 70362306a36Sopenharmony_ci serial_out(p, UART_EFR, efr); 70462306a36Sopenharmony_ci serial_out(p, UART_LCR, lcr); 70562306a36Sopenharmony_ci } 70662306a36Sopenharmony_ci spin_unlock_irq(&p->port.lock); 70762306a36Sopenharmony_ci } 70862306a36Sopenharmony_ci 70962306a36Sopenharmony_ci serial8250_rpm_put(p); 71062306a36Sopenharmony_ci} 71162306a36Sopenharmony_ci 71262306a36Sopenharmony_cistatic void serial8250_clear_IER(struct uart_8250_port *up) 71362306a36Sopenharmony_ci{ 71462306a36Sopenharmony_ci if (up->capabilities & UART_CAP_UUE) 71562306a36Sopenharmony_ci serial_out(up, UART_IER, UART_IER_UUE); 71662306a36Sopenharmony_ci else 71762306a36Sopenharmony_ci serial_out(up, UART_IER, 0); 71862306a36Sopenharmony_ci} 71962306a36Sopenharmony_ci 72062306a36Sopenharmony_ci#ifdef CONFIG_SERIAL_8250_RSA 72162306a36Sopenharmony_ci/* 72262306a36Sopenharmony_ci * Attempts to turn on the RSA FIFO. Returns zero on failure. 72362306a36Sopenharmony_ci * We set the port uart clock rate if we succeed. 72462306a36Sopenharmony_ci */ 72562306a36Sopenharmony_cistatic int __enable_rsa(struct uart_8250_port *up) 72662306a36Sopenharmony_ci{ 72762306a36Sopenharmony_ci unsigned char mode; 72862306a36Sopenharmony_ci int result; 72962306a36Sopenharmony_ci 73062306a36Sopenharmony_ci mode = serial_in(up, UART_RSA_MSR); 73162306a36Sopenharmony_ci result = mode & UART_RSA_MSR_FIFO; 73262306a36Sopenharmony_ci 73362306a36Sopenharmony_ci if (!result) { 73462306a36Sopenharmony_ci serial_out(up, UART_RSA_MSR, mode | UART_RSA_MSR_FIFO); 73562306a36Sopenharmony_ci mode = serial_in(up, UART_RSA_MSR); 73662306a36Sopenharmony_ci result = mode & UART_RSA_MSR_FIFO; 73762306a36Sopenharmony_ci } 73862306a36Sopenharmony_ci 73962306a36Sopenharmony_ci if (result) 74062306a36Sopenharmony_ci up->port.uartclk = SERIAL_RSA_BAUD_BASE * 16; 74162306a36Sopenharmony_ci 74262306a36Sopenharmony_ci return result; 74362306a36Sopenharmony_ci} 74462306a36Sopenharmony_ci 74562306a36Sopenharmony_cistatic void enable_rsa(struct uart_8250_port *up) 74662306a36Sopenharmony_ci{ 74762306a36Sopenharmony_ci if (up->port.type == PORT_RSA) { 74862306a36Sopenharmony_ci if (up->port.uartclk != SERIAL_RSA_BAUD_BASE * 16) { 74962306a36Sopenharmony_ci spin_lock_irq(&up->port.lock); 75062306a36Sopenharmony_ci __enable_rsa(up); 75162306a36Sopenharmony_ci spin_unlock_irq(&up->port.lock); 75262306a36Sopenharmony_ci } 75362306a36Sopenharmony_ci if (up->port.uartclk == SERIAL_RSA_BAUD_BASE * 16) 75462306a36Sopenharmony_ci serial_out(up, UART_RSA_FRR, 0); 75562306a36Sopenharmony_ci } 75662306a36Sopenharmony_ci} 75762306a36Sopenharmony_ci 75862306a36Sopenharmony_ci/* 75962306a36Sopenharmony_ci * Attempts to turn off the RSA FIFO. Returns zero on failure. 76062306a36Sopenharmony_ci * It is unknown why interrupts were disabled in here. However, 76162306a36Sopenharmony_ci * the caller is expected to preserve this behaviour by grabbing 76262306a36Sopenharmony_ci * the spinlock before calling this function. 76362306a36Sopenharmony_ci */ 76462306a36Sopenharmony_cistatic void disable_rsa(struct uart_8250_port *up) 76562306a36Sopenharmony_ci{ 76662306a36Sopenharmony_ci unsigned char mode; 76762306a36Sopenharmony_ci int result; 76862306a36Sopenharmony_ci 76962306a36Sopenharmony_ci if (up->port.type == PORT_RSA && 77062306a36Sopenharmony_ci up->port.uartclk == SERIAL_RSA_BAUD_BASE * 16) { 77162306a36Sopenharmony_ci spin_lock_irq(&up->port.lock); 77262306a36Sopenharmony_ci 77362306a36Sopenharmony_ci mode = serial_in(up, UART_RSA_MSR); 77462306a36Sopenharmony_ci result = !(mode & UART_RSA_MSR_FIFO); 77562306a36Sopenharmony_ci 77662306a36Sopenharmony_ci if (!result) { 77762306a36Sopenharmony_ci serial_out(up, UART_RSA_MSR, mode & ~UART_RSA_MSR_FIFO); 77862306a36Sopenharmony_ci mode = serial_in(up, UART_RSA_MSR); 77962306a36Sopenharmony_ci result = !(mode & UART_RSA_MSR_FIFO); 78062306a36Sopenharmony_ci } 78162306a36Sopenharmony_ci 78262306a36Sopenharmony_ci if (result) 78362306a36Sopenharmony_ci up->port.uartclk = SERIAL_RSA_BAUD_BASE_LO * 16; 78462306a36Sopenharmony_ci spin_unlock_irq(&up->port.lock); 78562306a36Sopenharmony_ci } 78662306a36Sopenharmony_ci} 78762306a36Sopenharmony_ci#endif /* CONFIG_SERIAL_8250_RSA */ 78862306a36Sopenharmony_ci 78962306a36Sopenharmony_ci/* 79062306a36Sopenharmony_ci * This is a quickie test to see how big the FIFO is. 79162306a36Sopenharmony_ci * It doesn't work at all the time, more's the pity. 79262306a36Sopenharmony_ci */ 79362306a36Sopenharmony_cistatic int size_fifo(struct uart_8250_port *up) 79462306a36Sopenharmony_ci{ 79562306a36Sopenharmony_ci unsigned char old_fcr, old_mcr, old_lcr; 79662306a36Sopenharmony_ci u32 old_dl; 79762306a36Sopenharmony_ci int count; 79862306a36Sopenharmony_ci 79962306a36Sopenharmony_ci old_lcr = serial_in(up, UART_LCR); 80062306a36Sopenharmony_ci serial_out(up, UART_LCR, 0); 80162306a36Sopenharmony_ci old_fcr = serial_in(up, UART_FCR); 80262306a36Sopenharmony_ci old_mcr = serial8250_in_MCR(up); 80362306a36Sopenharmony_ci serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO | 80462306a36Sopenharmony_ci UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT); 80562306a36Sopenharmony_ci serial8250_out_MCR(up, UART_MCR_LOOP); 80662306a36Sopenharmony_ci serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A); 80762306a36Sopenharmony_ci old_dl = serial_dl_read(up); 80862306a36Sopenharmony_ci serial_dl_write(up, 0x0001); 80962306a36Sopenharmony_ci serial_out(up, UART_LCR, UART_LCR_WLEN8); 81062306a36Sopenharmony_ci for (count = 0; count < 256; count++) 81162306a36Sopenharmony_ci serial_out(up, UART_TX, count); 81262306a36Sopenharmony_ci mdelay(20);/* FIXME - schedule_timeout */ 81362306a36Sopenharmony_ci for (count = 0; (serial_in(up, UART_LSR) & UART_LSR_DR) && 81462306a36Sopenharmony_ci (count < 256); count++) 81562306a36Sopenharmony_ci serial_in(up, UART_RX); 81662306a36Sopenharmony_ci serial_out(up, UART_FCR, old_fcr); 81762306a36Sopenharmony_ci serial8250_out_MCR(up, old_mcr); 81862306a36Sopenharmony_ci serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A); 81962306a36Sopenharmony_ci serial_dl_write(up, old_dl); 82062306a36Sopenharmony_ci serial_out(up, UART_LCR, old_lcr); 82162306a36Sopenharmony_ci 82262306a36Sopenharmony_ci return count; 82362306a36Sopenharmony_ci} 82462306a36Sopenharmony_ci 82562306a36Sopenharmony_ci/* 82662306a36Sopenharmony_ci * Read UART ID using the divisor method - set DLL and DLM to zero 82762306a36Sopenharmony_ci * and the revision will be in DLL and device type in DLM. We 82862306a36Sopenharmony_ci * preserve the device state across this. 82962306a36Sopenharmony_ci */ 83062306a36Sopenharmony_cistatic unsigned int autoconfig_read_divisor_id(struct uart_8250_port *p) 83162306a36Sopenharmony_ci{ 83262306a36Sopenharmony_ci unsigned char old_lcr; 83362306a36Sopenharmony_ci unsigned int id, old_dl; 83462306a36Sopenharmony_ci 83562306a36Sopenharmony_ci old_lcr = serial_in(p, UART_LCR); 83662306a36Sopenharmony_ci serial_out(p, UART_LCR, UART_LCR_CONF_MODE_A); 83762306a36Sopenharmony_ci old_dl = serial_dl_read(p); 83862306a36Sopenharmony_ci serial_dl_write(p, 0); 83962306a36Sopenharmony_ci id = serial_dl_read(p); 84062306a36Sopenharmony_ci serial_dl_write(p, old_dl); 84162306a36Sopenharmony_ci 84262306a36Sopenharmony_ci serial_out(p, UART_LCR, old_lcr); 84362306a36Sopenharmony_ci 84462306a36Sopenharmony_ci return id; 84562306a36Sopenharmony_ci} 84662306a36Sopenharmony_ci 84762306a36Sopenharmony_ci/* 84862306a36Sopenharmony_ci * This is a helper routine to autodetect StarTech/Exar/Oxsemi UART's. 84962306a36Sopenharmony_ci * When this function is called we know it is at least a StarTech 85062306a36Sopenharmony_ci * 16650 V2, but it might be one of several StarTech UARTs, or one of 85162306a36Sopenharmony_ci * its clones. (We treat the broken original StarTech 16650 V1 as a 85262306a36Sopenharmony_ci * 16550, and why not? Startech doesn't seem to even acknowledge its 85362306a36Sopenharmony_ci * existence.) 85462306a36Sopenharmony_ci * 85562306a36Sopenharmony_ci * What evil have men's minds wrought... 85662306a36Sopenharmony_ci */ 85762306a36Sopenharmony_cistatic void autoconfig_has_efr(struct uart_8250_port *up) 85862306a36Sopenharmony_ci{ 85962306a36Sopenharmony_ci unsigned int id1, id2, id3, rev; 86062306a36Sopenharmony_ci 86162306a36Sopenharmony_ci /* 86262306a36Sopenharmony_ci * Everything with an EFR has SLEEP 86362306a36Sopenharmony_ci */ 86462306a36Sopenharmony_ci up->capabilities |= UART_CAP_EFR | UART_CAP_SLEEP; 86562306a36Sopenharmony_ci 86662306a36Sopenharmony_ci /* 86762306a36Sopenharmony_ci * First we check to see if it's an Oxford Semiconductor UART. 86862306a36Sopenharmony_ci * 86962306a36Sopenharmony_ci * If we have to do this here because some non-National 87062306a36Sopenharmony_ci * Semiconductor clone chips lock up if you try writing to the 87162306a36Sopenharmony_ci * LSR register (which serial_icr_read does) 87262306a36Sopenharmony_ci */ 87362306a36Sopenharmony_ci 87462306a36Sopenharmony_ci /* 87562306a36Sopenharmony_ci * Check for Oxford Semiconductor 16C950. 87662306a36Sopenharmony_ci * 87762306a36Sopenharmony_ci * EFR [4] must be set else this test fails. 87862306a36Sopenharmony_ci * 87962306a36Sopenharmony_ci * This shouldn't be necessary, but Mike Hudson (Exoray@isys.ca) 88062306a36Sopenharmony_ci * claims that it's needed for 952 dual UART's (which are not 88162306a36Sopenharmony_ci * recommended for new designs). 88262306a36Sopenharmony_ci */ 88362306a36Sopenharmony_ci up->acr = 0; 88462306a36Sopenharmony_ci serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); 88562306a36Sopenharmony_ci serial_out(up, UART_EFR, UART_EFR_ECB); 88662306a36Sopenharmony_ci serial_out(up, UART_LCR, 0x00); 88762306a36Sopenharmony_ci id1 = serial_icr_read(up, UART_ID1); 88862306a36Sopenharmony_ci id2 = serial_icr_read(up, UART_ID2); 88962306a36Sopenharmony_ci id3 = serial_icr_read(up, UART_ID3); 89062306a36Sopenharmony_ci rev = serial_icr_read(up, UART_REV); 89162306a36Sopenharmony_ci 89262306a36Sopenharmony_ci DEBUG_AUTOCONF("950id=%02x:%02x:%02x:%02x ", id1, id2, id3, rev); 89362306a36Sopenharmony_ci 89462306a36Sopenharmony_ci if (id1 == 0x16 && id2 == 0xC9 && 89562306a36Sopenharmony_ci (id3 == 0x50 || id3 == 0x52 || id3 == 0x54)) { 89662306a36Sopenharmony_ci up->port.type = PORT_16C950; 89762306a36Sopenharmony_ci 89862306a36Sopenharmony_ci /* 89962306a36Sopenharmony_ci * Enable work around for the Oxford Semiconductor 952 rev B 90062306a36Sopenharmony_ci * chip which causes it to seriously miscalculate baud rates 90162306a36Sopenharmony_ci * when DLL is 0. 90262306a36Sopenharmony_ci */ 90362306a36Sopenharmony_ci if (id3 == 0x52 && rev == 0x01) 90462306a36Sopenharmony_ci up->bugs |= UART_BUG_QUOT; 90562306a36Sopenharmony_ci return; 90662306a36Sopenharmony_ci } 90762306a36Sopenharmony_ci 90862306a36Sopenharmony_ci /* 90962306a36Sopenharmony_ci * We check for a XR16C850 by setting DLL and DLM to 0, and then 91062306a36Sopenharmony_ci * reading back DLL and DLM. The chip type depends on the DLM 91162306a36Sopenharmony_ci * value read back: 91262306a36Sopenharmony_ci * 0x10 - XR16C850 and the DLL contains the chip revision. 91362306a36Sopenharmony_ci * 0x12 - XR16C2850. 91462306a36Sopenharmony_ci * 0x14 - XR16C854. 91562306a36Sopenharmony_ci */ 91662306a36Sopenharmony_ci id1 = autoconfig_read_divisor_id(up); 91762306a36Sopenharmony_ci DEBUG_AUTOCONF("850id=%04x ", id1); 91862306a36Sopenharmony_ci 91962306a36Sopenharmony_ci id2 = id1 >> 8; 92062306a36Sopenharmony_ci if (id2 == 0x10 || id2 == 0x12 || id2 == 0x14) { 92162306a36Sopenharmony_ci up->port.type = PORT_16850; 92262306a36Sopenharmony_ci return; 92362306a36Sopenharmony_ci } 92462306a36Sopenharmony_ci 92562306a36Sopenharmony_ci /* 92662306a36Sopenharmony_ci * It wasn't an XR16C850. 92762306a36Sopenharmony_ci * 92862306a36Sopenharmony_ci * We distinguish between the '654 and the '650 by counting 92962306a36Sopenharmony_ci * how many bytes are in the FIFO. I'm using this for now, 93062306a36Sopenharmony_ci * since that's the technique that was sent to me in the 93162306a36Sopenharmony_ci * serial driver update, but I'm not convinced this works. 93262306a36Sopenharmony_ci * I've had problems doing this in the past. -TYT 93362306a36Sopenharmony_ci */ 93462306a36Sopenharmony_ci if (size_fifo(up) == 64) 93562306a36Sopenharmony_ci up->port.type = PORT_16654; 93662306a36Sopenharmony_ci else 93762306a36Sopenharmony_ci up->port.type = PORT_16650V2; 93862306a36Sopenharmony_ci} 93962306a36Sopenharmony_ci 94062306a36Sopenharmony_ci/* 94162306a36Sopenharmony_ci * We detected a chip without a FIFO. Only two fall into 94262306a36Sopenharmony_ci * this category - the original 8250 and the 16450. The 94362306a36Sopenharmony_ci * 16450 has a scratch register (accessible with LCR=0) 94462306a36Sopenharmony_ci */ 94562306a36Sopenharmony_cistatic void autoconfig_8250(struct uart_8250_port *up) 94662306a36Sopenharmony_ci{ 94762306a36Sopenharmony_ci unsigned char scratch, status1, status2; 94862306a36Sopenharmony_ci 94962306a36Sopenharmony_ci up->port.type = PORT_8250; 95062306a36Sopenharmony_ci 95162306a36Sopenharmony_ci scratch = serial_in(up, UART_SCR); 95262306a36Sopenharmony_ci serial_out(up, UART_SCR, 0xa5); 95362306a36Sopenharmony_ci status1 = serial_in(up, UART_SCR); 95462306a36Sopenharmony_ci serial_out(up, UART_SCR, 0x5a); 95562306a36Sopenharmony_ci status2 = serial_in(up, UART_SCR); 95662306a36Sopenharmony_ci serial_out(up, UART_SCR, scratch); 95762306a36Sopenharmony_ci 95862306a36Sopenharmony_ci if (status1 == 0xa5 && status2 == 0x5a) 95962306a36Sopenharmony_ci up->port.type = PORT_16450; 96062306a36Sopenharmony_ci} 96162306a36Sopenharmony_ci 96262306a36Sopenharmony_cistatic int broken_efr(struct uart_8250_port *up) 96362306a36Sopenharmony_ci{ 96462306a36Sopenharmony_ci /* 96562306a36Sopenharmony_ci * Exar ST16C2550 "A2" devices incorrectly detect as 96662306a36Sopenharmony_ci * having an EFR, and report an ID of 0x0201. See 96762306a36Sopenharmony_ci * http://linux.derkeiler.com/Mailing-Lists/Kernel/2004-11/4812.html 96862306a36Sopenharmony_ci */ 96962306a36Sopenharmony_ci if (autoconfig_read_divisor_id(up) == 0x0201 && size_fifo(up) == 16) 97062306a36Sopenharmony_ci return 1; 97162306a36Sopenharmony_ci 97262306a36Sopenharmony_ci return 0; 97362306a36Sopenharmony_ci} 97462306a36Sopenharmony_ci 97562306a36Sopenharmony_ci/* 97662306a36Sopenharmony_ci * We know that the chip has FIFOs. Does it have an EFR? The 97762306a36Sopenharmony_ci * EFR is located in the same register position as the IIR and 97862306a36Sopenharmony_ci * we know the top two bits of the IIR are currently set. The 97962306a36Sopenharmony_ci * EFR should contain zero. Try to read the EFR. 98062306a36Sopenharmony_ci */ 98162306a36Sopenharmony_cistatic void autoconfig_16550a(struct uart_8250_port *up) 98262306a36Sopenharmony_ci{ 98362306a36Sopenharmony_ci unsigned char status1, status2; 98462306a36Sopenharmony_ci unsigned int iersave; 98562306a36Sopenharmony_ci 98662306a36Sopenharmony_ci /* Port locked to synchronize UART_IER access against the console. */ 98762306a36Sopenharmony_ci lockdep_assert_held_once(&up->port.lock); 98862306a36Sopenharmony_ci 98962306a36Sopenharmony_ci up->port.type = PORT_16550A; 99062306a36Sopenharmony_ci up->capabilities |= UART_CAP_FIFO; 99162306a36Sopenharmony_ci 99262306a36Sopenharmony_ci if (!IS_ENABLED(CONFIG_SERIAL_8250_16550A_VARIANTS) && 99362306a36Sopenharmony_ci !(up->port.flags & UPF_FULL_PROBE)) 99462306a36Sopenharmony_ci return; 99562306a36Sopenharmony_ci 99662306a36Sopenharmony_ci /* 99762306a36Sopenharmony_ci * Check for presence of the EFR when DLAB is set. 99862306a36Sopenharmony_ci * Only ST16C650V1 UARTs pass this test. 99962306a36Sopenharmony_ci */ 100062306a36Sopenharmony_ci serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A); 100162306a36Sopenharmony_ci if (serial_in(up, UART_EFR) == 0) { 100262306a36Sopenharmony_ci serial_out(up, UART_EFR, 0xA8); 100362306a36Sopenharmony_ci if (serial_in(up, UART_EFR) != 0) { 100462306a36Sopenharmony_ci DEBUG_AUTOCONF("EFRv1 "); 100562306a36Sopenharmony_ci up->port.type = PORT_16650; 100662306a36Sopenharmony_ci up->capabilities |= UART_CAP_EFR | UART_CAP_SLEEP; 100762306a36Sopenharmony_ci } else { 100862306a36Sopenharmony_ci serial_out(up, UART_LCR, 0); 100962306a36Sopenharmony_ci serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO | 101062306a36Sopenharmony_ci UART_FCR7_64BYTE); 101162306a36Sopenharmony_ci status1 = serial_in(up, UART_IIR) & (UART_IIR_64BYTE_FIFO | 101262306a36Sopenharmony_ci UART_IIR_FIFO_ENABLED); 101362306a36Sopenharmony_ci serial_out(up, UART_FCR, 0); 101462306a36Sopenharmony_ci serial_out(up, UART_LCR, 0); 101562306a36Sopenharmony_ci 101662306a36Sopenharmony_ci if (status1 == (UART_IIR_64BYTE_FIFO | UART_IIR_FIFO_ENABLED)) 101762306a36Sopenharmony_ci up->port.type = PORT_16550A_FSL64; 101862306a36Sopenharmony_ci else 101962306a36Sopenharmony_ci DEBUG_AUTOCONF("Motorola 8xxx DUART "); 102062306a36Sopenharmony_ci } 102162306a36Sopenharmony_ci serial_out(up, UART_EFR, 0); 102262306a36Sopenharmony_ci return; 102362306a36Sopenharmony_ci } 102462306a36Sopenharmony_ci 102562306a36Sopenharmony_ci /* 102662306a36Sopenharmony_ci * Maybe it requires 0xbf to be written to the LCR. 102762306a36Sopenharmony_ci * (other ST16C650V2 UARTs, TI16C752A, etc) 102862306a36Sopenharmony_ci */ 102962306a36Sopenharmony_ci serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); 103062306a36Sopenharmony_ci if (serial_in(up, UART_EFR) == 0 && !broken_efr(up)) { 103162306a36Sopenharmony_ci DEBUG_AUTOCONF("EFRv2 "); 103262306a36Sopenharmony_ci autoconfig_has_efr(up); 103362306a36Sopenharmony_ci return; 103462306a36Sopenharmony_ci } 103562306a36Sopenharmony_ci 103662306a36Sopenharmony_ci /* 103762306a36Sopenharmony_ci * Check for a National Semiconductor SuperIO chip. 103862306a36Sopenharmony_ci * Attempt to switch to bank 2, read the value of the LOOP bit 103962306a36Sopenharmony_ci * from EXCR1. Switch back to bank 0, change it in MCR. Then 104062306a36Sopenharmony_ci * switch back to bank 2, read it from EXCR1 again and check 104162306a36Sopenharmony_ci * it's changed. If so, set baud_base in EXCR2 to 921600. -- dwmw2 104262306a36Sopenharmony_ci */ 104362306a36Sopenharmony_ci serial_out(up, UART_LCR, 0); 104462306a36Sopenharmony_ci status1 = serial8250_in_MCR(up); 104562306a36Sopenharmony_ci serial_out(up, UART_LCR, 0xE0); 104662306a36Sopenharmony_ci status2 = serial_in(up, 0x02); /* EXCR1 */ 104762306a36Sopenharmony_ci 104862306a36Sopenharmony_ci if (!((status2 ^ status1) & UART_MCR_LOOP)) { 104962306a36Sopenharmony_ci serial_out(up, UART_LCR, 0); 105062306a36Sopenharmony_ci serial8250_out_MCR(up, status1 ^ UART_MCR_LOOP); 105162306a36Sopenharmony_ci serial_out(up, UART_LCR, 0xE0); 105262306a36Sopenharmony_ci status2 = serial_in(up, 0x02); /* EXCR1 */ 105362306a36Sopenharmony_ci serial_out(up, UART_LCR, 0); 105462306a36Sopenharmony_ci serial8250_out_MCR(up, status1); 105562306a36Sopenharmony_ci 105662306a36Sopenharmony_ci if ((status2 ^ status1) & UART_MCR_LOOP) { 105762306a36Sopenharmony_ci unsigned short quot; 105862306a36Sopenharmony_ci 105962306a36Sopenharmony_ci serial_out(up, UART_LCR, 0xE0); 106062306a36Sopenharmony_ci 106162306a36Sopenharmony_ci quot = serial_dl_read(up); 106262306a36Sopenharmony_ci quot <<= 3; 106362306a36Sopenharmony_ci 106462306a36Sopenharmony_ci if (ns16550a_goto_highspeed(up)) 106562306a36Sopenharmony_ci serial_dl_write(up, quot); 106662306a36Sopenharmony_ci 106762306a36Sopenharmony_ci serial_out(up, UART_LCR, 0); 106862306a36Sopenharmony_ci 106962306a36Sopenharmony_ci up->port.uartclk = 921600*16; 107062306a36Sopenharmony_ci up->port.type = PORT_NS16550A; 107162306a36Sopenharmony_ci up->capabilities |= UART_NATSEMI; 107262306a36Sopenharmony_ci return; 107362306a36Sopenharmony_ci } 107462306a36Sopenharmony_ci } 107562306a36Sopenharmony_ci 107662306a36Sopenharmony_ci /* 107762306a36Sopenharmony_ci * No EFR. Try to detect a TI16750, which only sets bit 5 of 107862306a36Sopenharmony_ci * the IIR when 64 byte FIFO mode is enabled when DLAB is set. 107962306a36Sopenharmony_ci * Try setting it with and without DLAB set. Cheap clones 108062306a36Sopenharmony_ci * set bit 5 without DLAB set. 108162306a36Sopenharmony_ci */ 108262306a36Sopenharmony_ci serial_out(up, UART_LCR, 0); 108362306a36Sopenharmony_ci serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO | UART_FCR7_64BYTE); 108462306a36Sopenharmony_ci status1 = serial_in(up, UART_IIR) & (UART_IIR_64BYTE_FIFO | UART_IIR_FIFO_ENABLED); 108562306a36Sopenharmony_ci serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO); 108662306a36Sopenharmony_ci 108762306a36Sopenharmony_ci serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A); 108862306a36Sopenharmony_ci serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO | UART_FCR7_64BYTE); 108962306a36Sopenharmony_ci status2 = serial_in(up, UART_IIR) & (UART_IIR_64BYTE_FIFO | UART_IIR_FIFO_ENABLED); 109062306a36Sopenharmony_ci serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO); 109162306a36Sopenharmony_ci 109262306a36Sopenharmony_ci serial_out(up, UART_LCR, 0); 109362306a36Sopenharmony_ci 109462306a36Sopenharmony_ci DEBUG_AUTOCONF("iir1=%d iir2=%d ", status1, status2); 109562306a36Sopenharmony_ci 109662306a36Sopenharmony_ci if (status1 == UART_IIR_FIFO_ENABLED_16550A && 109762306a36Sopenharmony_ci status2 == (UART_IIR_64BYTE_FIFO | UART_IIR_FIFO_ENABLED_16550A)) { 109862306a36Sopenharmony_ci up->port.type = PORT_16750; 109962306a36Sopenharmony_ci up->capabilities |= UART_CAP_AFE | UART_CAP_SLEEP; 110062306a36Sopenharmony_ci return; 110162306a36Sopenharmony_ci } 110262306a36Sopenharmony_ci 110362306a36Sopenharmony_ci /* 110462306a36Sopenharmony_ci * Try writing and reading the UART_IER_UUE bit (b6). 110562306a36Sopenharmony_ci * If it works, this is probably one of the Xscale platform's 110662306a36Sopenharmony_ci * internal UARTs. 110762306a36Sopenharmony_ci * We're going to explicitly set the UUE bit to 0 before 110862306a36Sopenharmony_ci * trying to write and read a 1 just to make sure it's not 110962306a36Sopenharmony_ci * already a 1 and maybe locked there before we even start. 111062306a36Sopenharmony_ci */ 111162306a36Sopenharmony_ci iersave = serial_in(up, UART_IER); 111262306a36Sopenharmony_ci serial_out(up, UART_IER, iersave & ~UART_IER_UUE); 111362306a36Sopenharmony_ci if (!(serial_in(up, UART_IER) & UART_IER_UUE)) { 111462306a36Sopenharmony_ci /* 111562306a36Sopenharmony_ci * OK it's in a known zero state, try writing and reading 111662306a36Sopenharmony_ci * without disturbing the current state of the other bits. 111762306a36Sopenharmony_ci */ 111862306a36Sopenharmony_ci serial_out(up, UART_IER, iersave | UART_IER_UUE); 111962306a36Sopenharmony_ci if (serial_in(up, UART_IER) & UART_IER_UUE) { 112062306a36Sopenharmony_ci /* 112162306a36Sopenharmony_ci * It's an Xscale. 112262306a36Sopenharmony_ci * We'll leave the UART_IER_UUE bit set to 1 (enabled). 112362306a36Sopenharmony_ci */ 112462306a36Sopenharmony_ci DEBUG_AUTOCONF("Xscale "); 112562306a36Sopenharmony_ci up->port.type = PORT_XSCALE; 112662306a36Sopenharmony_ci up->capabilities |= UART_CAP_UUE | UART_CAP_RTOIE; 112762306a36Sopenharmony_ci return; 112862306a36Sopenharmony_ci } 112962306a36Sopenharmony_ci } else { 113062306a36Sopenharmony_ci /* 113162306a36Sopenharmony_ci * If we got here we couldn't force the IER_UUE bit to 0. 113262306a36Sopenharmony_ci * Log it and continue. 113362306a36Sopenharmony_ci */ 113462306a36Sopenharmony_ci DEBUG_AUTOCONF("Couldn't force IER_UUE to 0 "); 113562306a36Sopenharmony_ci } 113662306a36Sopenharmony_ci serial_out(up, UART_IER, iersave); 113762306a36Sopenharmony_ci 113862306a36Sopenharmony_ci /* 113962306a36Sopenharmony_ci * We distinguish between 16550A and U6 16550A by counting 114062306a36Sopenharmony_ci * how many bytes are in the FIFO. 114162306a36Sopenharmony_ci */ 114262306a36Sopenharmony_ci if (up->port.type == PORT_16550A && size_fifo(up) == 64) { 114362306a36Sopenharmony_ci up->port.type = PORT_U6_16550A; 114462306a36Sopenharmony_ci up->capabilities |= UART_CAP_AFE; 114562306a36Sopenharmony_ci } 114662306a36Sopenharmony_ci} 114762306a36Sopenharmony_ci 114862306a36Sopenharmony_ci/* 114962306a36Sopenharmony_ci * This routine is called by rs_init() to initialize a specific serial 115062306a36Sopenharmony_ci * port. It determines what type of UART chip this serial port is 115162306a36Sopenharmony_ci * using: 8250, 16450, 16550, 16550A. The important question is 115262306a36Sopenharmony_ci * whether or not this UART is a 16550A or not, since this will 115362306a36Sopenharmony_ci * determine whether or not we can use its FIFO features or not. 115462306a36Sopenharmony_ci */ 115562306a36Sopenharmony_cistatic void autoconfig(struct uart_8250_port *up) 115662306a36Sopenharmony_ci{ 115762306a36Sopenharmony_ci unsigned char status1, scratch, scratch2, scratch3; 115862306a36Sopenharmony_ci unsigned char save_lcr, save_mcr; 115962306a36Sopenharmony_ci struct uart_port *port = &up->port; 116062306a36Sopenharmony_ci unsigned long flags; 116162306a36Sopenharmony_ci unsigned int old_capabilities; 116262306a36Sopenharmony_ci 116362306a36Sopenharmony_ci if (!port->iobase && !port->mapbase && !port->membase) 116462306a36Sopenharmony_ci return; 116562306a36Sopenharmony_ci 116662306a36Sopenharmony_ci DEBUG_AUTOCONF("%s: autoconf (0x%04lx, 0x%p): ", 116762306a36Sopenharmony_ci port->name, port->iobase, port->membase); 116862306a36Sopenharmony_ci 116962306a36Sopenharmony_ci /* 117062306a36Sopenharmony_ci * We really do need global IRQs disabled here - we're going to 117162306a36Sopenharmony_ci * be frobbing the chips IRQ enable register to see if it exists. 117262306a36Sopenharmony_ci * 117362306a36Sopenharmony_ci * Synchronize UART_IER access against the console. 117462306a36Sopenharmony_ci */ 117562306a36Sopenharmony_ci spin_lock_irqsave(&port->lock, flags); 117662306a36Sopenharmony_ci 117762306a36Sopenharmony_ci up->capabilities = 0; 117862306a36Sopenharmony_ci up->bugs = 0; 117962306a36Sopenharmony_ci 118062306a36Sopenharmony_ci if (!(port->flags & UPF_BUGGY_UART)) { 118162306a36Sopenharmony_ci /* 118262306a36Sopenharmony_ci * Do a simple existence test first; if we fail this, 118362306a36Sopenharmony_ci * there's no point trying anything else. 118462306a36Sopenharmony_ci * 118562306a36Sopenharmony_ci * 0x80 is used as a nonsense port to prevent against 118662306a36Sopenharmony_ci * false positives due to ISA bus float. The 118762306a36Sopenharmony_ci * assumption is that 0x80 is a non-existent port; 118862306a36Sopenharmony_ci * which should be safe since include/asm/io.h also 118962306a36Sopenharmony_ci * makes this assumption. 119062306a36Sopenharmony_ci * 119162306a36Sopenharmony_ci * Note: this is safe as long as MCR bit 4 is clear 119262306a36Sopenharmony_ci * and the device is in "PC" mode. 119362306a36Sopenharmony_ci */ 119462306a36Sopenharmony_ci scratch = serial_in(up, UART_IER); 119562306a36Sopenharmony_ci serial_out(up, UART_IER, 0); 119662306a36Sopenharmony_ci#ifdef __i386__ 119762306a36Sopenharmony_ci outb(0xff, 0x080); 119862306a36Sopenharmony_ci#endif 119962306a36Sopenharmony_ci /* 120062306a36Sopenharmony_ci * Mask out IER[7:4] bits for test as some UARTs (e.g. TL 120162306a36Sopenharmony_ci * 16C754B) allow only to modify them if an EFR bit is set. 120262306a36Sopenharmony_ci */ 120362306a36Sopenharmony_ci scratch2 = serial_in(up, UART_IER) & UART_IER_ALL_INTR; 120462306a36Sopenharmony_ci serial_out(up, UART_IER, UART_IER_ALL_INTR); 120562306a36Sopenharmony_ci#ifdef __i386__ 120662306a36Sopenharmony_ci outb(0, 0x080); 120762306a36Sopenharmony_ci#endif 120862306a36Sopenharmony_ci scratch3 = serial_in(up, UART_IER) & UART_IER_ALL_INTR; 120962306a36Sopenharmony_ci serial_out(up, UART_IER, scratch); 121062306a36Sopenharmony_ci if (scratch2 != 0 || scratch3 != UART_IER_ALL_INTR) { 121162306a36Sopenharmony_ci /* 121262306a36Sopenharmony_ci * We failed; there's nothing here 121362306a36Sopenharmony_ci */ 121462306a36Sopenharmony_ci spin_unlock_irqrestore(&port->lock, flags); 121562306a36Sopenharmony_ci DEBUG_AUTOCONF("IER test failed (%02x, %02x) ", 121662306a36Sopenharmony_ci scratch2, scratch3); 121762306a36Sopenharmony_ci goto out; 121862306a36Sopenharmony_ci } 121962306a36Sopenharmony_ci } 122062306a36Sopenharmony_ci 122162306a36Sopenharmony_ci save_mcr = serial8250_in_MCR(up); 122262306a36Sopenharmony_ci save_lcr = serial_in(up, UART_LCR); 122362306a36Sopenharmony_ci 122462306a36Sopenharmony_ci /* 122562306a36Sopenharmony_ci * Check to see if a UART is really there. Certain broken 122662306a36Sopenharmony_ci * internal modems based on the Rockwell chipset fail this 122762306a36Sopenharmony_ci * test, because they apparently don't implement the loopback 122862306a36Sopenharmony_ci * test mode. So this test is skipped on the COM 1 through 122962306a36Sopenharmony_ci * COM 4 ports. This *should* be safe, since no board 123062306a36Sopenharmony_ci * manufacturer would be stupid enough to design a board 123162306a36Sopenharmony_ci * that conflicts with COM 1-4 --- we hope! 123262306a36Sopenharmony_ci */ 123362306a36Sopenharmony_ci if (!(port->flags & UPF_SKIP_TEST)) { 123462306a36Sopenharmony_ci serial8250_out_MCR(up, UART_MCR_LOOP | UART_MCR_OUT2 | UART_MCR_RTS); 123562306a36Sopenharmony_ci status1 = serial_in(up, UART_MSR) & UART_MSR_STATUS_BITS; 123662306a36Sopenharmony_ci serial8250_out_MCR(up, save_mcr); 123762306a36Sopenharmony_ci if (status1 != (UART_MSR_DCD | UART_MSR_CTS)) { 123862306a36Sopenharmony_ci spin_unlock_irqrestore(&port->lock, flags); 123962306a36Sopenharmony_ci DEBUG_AUTOCONF("LOOP test failed (%02x) ", 124062306a36Sopenharmony_ci status1); 124162306a36Sopenharmony_ci goto out; 124262306a36Sopenharmony_ci } 124362306a36Sopenharmony_ci } 124462306a36Sopenharmony_ci 124562306a36Sopenharmony_ci /* 124662306a36Sopenharmony_ci * We're pretty sure there's a port here. Lets find out what 124762306a36Sopenharmony_ci * type of port it is. The IIR top two bits allows us to find 124862306a36Sopenharmony_ci * out if it's 8250 or 16450, 16550, 16550A or later. This 124962306a36Sopenharmony_ci * determines what we test for next. 125062306a36Sopenharmony_ci * 125162306a36Sopenharmony_ci * We also initialise the EFR (if any) to zero for later. The 125262306a36Sopenharmony_ci * EFR occupies the same register location as the FCR and IIR. 125362306a36Sopenharmony_ci */ 125462306a36Sopenharmony_ci serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); 125562306a36Sopenharmony_ci serial_out(up, UART_EFR, 0); 125662306a36Sopenharmony_ci serial_out(up, UART_LCR, 0); 125762306a36Sopenharmony_ci 125862306a36Sopenharmony_ci serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO); 125962306a36Sopenharmony_ci 126062306a36Sopenharmony_ci switch (serial_in(up, UART_IIR) & UART_IIR_FIFO_ENABLED) { 126162306a36Sopenharmony_ci case UART_IIR_FIFO_ENABLED_8250: 126262306a36Sopenharmony_ci autoconfig_8250(up); 126362306a36Sopenharmony_ci break; 126462306a36Sopenharmony_ci case UART_IIR_FIFO_ENABLED_16550: 126562306a36Sopenharmony_ci port->type = PORT_16550; 126662306a36Sopenharmony_ci break; 126762306a36Sopenharmony_ci case UART_IIR_FIFO_ENABLED_16550A: 126862306a36Sopenharmony_ci autoconfig_16550a(up); 126962306a36Sopenharmony_ci break; 127062306a36Sopenharmony_ci default: 127162306a36Sopenharmony_ci port->type = PORT_UNKNOWN; 127262306a36Sopenharmony_ci break; 127362306a36Sopenharmony_ci } 127462306a36Sopenharmony_ci 127562306a36Sopenharmony_ci#ifdef CONFIG_SERIAL_8250_RSA 127662306a36Sopenharmony_ci /* 127762306a36Sopenharmony_ci * Only probe for RSA ports if we got the region. 127862306a36Sopenharmony_ci */ 127962306a36Sopenharmony_ci if (port->type == PORT_16550A && up->probe & UART_PROBE_RSA && 128062306a36Sopenharmony_ci __enable_rsa(up)) 128162306a36Sopenharmony_ci port->type = PORT_RSA; 128262306a36Sopenharmony_ci#endif 128362306a36Sopenharmony_ci 128462306a36Sopenharmony_ci serial_out(up, UART_LCR, save_lcr); 128562306a36Sopenharmony_ci 128662306a36Sopenharmony_ci port->fifosize = uart_config[up->port.type].fifo_size; 128762306a36Sopenharmony_ci old_capabilities = up->capabilities; 128862306a36Sopenharmony_ci up->capabilities = uart_config[port->type].flags; 128962306a36Sopenharmony_ci up->tx_loadsz = uart_config[port->type].tx_loadsz; 129062306a36Sopenharmony_ci 129162306a36Sopenharmony_ci if (port->type == PORT_UNKNOWN) 129262306a36Sopenharmony_ci goto out_unlock; 129362306a36Sopenharmony_ci 129462306a36Sopenharmony_ci /* 129562306a36Sopenharmony_ci * Reset the UART. 129662306a36Sopenharmony_ci */ 129762306a36Sopenharmony_ci#ifdef CONFIG_SERIAL_8250_RSA 129862306a36Sopenharmony_ci if (port->type == PORT_RSA) 129962306a36Sopenharmony_ci serial_out(up, UART_RSA_FRR, 0); 130062306a36Sopenharmony_ci#endif 130162306a36Sopenharmony_ci serial8250_out_MCR(up, save_mcr); 130262306a36Sopenharmony_ci serial8250_clear_fifos(up); 130362306a36Sopenharmony_ci serial_in(up, UART_RX); 130462306a36Sopenharmony_ci serial8250_clear_IER(up); 130562306a36Sopenharmony_ci 130662306a36Sopenharmony_ciout_unlock: 130762306a36Sopenharmony_ci spin_unlock_irqrestore(&port->lock, flags); 130862306a36Sopenharmony_ci 130962306a36Sopenharmony_ci /* 131062306a36Sopenharmony_ci * Check if the device is a Fintek F81216A 131162306a36Sopenharmony_ci */ 131262306a36Sopenharmony_ci if (port->type == PORT_16550A && port->iotype == UPIO_PORT) 131362306a36Sopenharmony_ci fintek_8250_probe(up); 131462306a36Sopenharmony_ci 131562306a36Sopenharmony_ci if (up->capabilities != old_capabilities) { 131662306a36Sopenharmony_ci dev_warn(port->dev, "detected caps %08x should be %08x\n", 131762306a36Sopenharmony_ci old_capabilities, up->capabilities); 131862306a36Sopenharmony_ci } 131962306a36Sopenharmony_ciout: 132062306a36Sopenharmony_ci DEBUG_AUTOCONF("iir=%d ", scratch); 132162306a36Sopenharmony_ci DEBUG_AUTOCONF("type=%s\n", uart_config[port->type].name); 132262306a36Sopenharmony_ci} 132362306a36Sopenharmony_ci 132462306a36Sopenharmony_cistatic void autoconfig_irq(struct uart_8250_port *up) 132562306a36Sopenharmony_ci{ 132662306a36Sopenharmony_ci struct uart_port *port = &up->port; 132762306a36Sopenharmony_ci unsigned char save_mcr, save_ier; 132862306a36Sopenharmony_ci unsigned char save_ICP = 0; 132962306a36Sopenharmony_ci unsigned int ICP = 0; 133062306a36Sopenharmony_ci unsigned long irqs; 133162306a36Sopenharmony_ci int irq; 133262306a36Sopenharmony_ci 133362306a36Sopenharmony_ci if (port->flags & UPF_FOURPORT) { 133462306a36Sopenharmony_ci ICP = (port->iobase & 0xfe0) | 0x1f; 133562306a36Sopenharmony_ci save_ICP = inb_p(ICP); 133662306a36Sopenharmony_ci outb_p(0x80, ICP); 133762306a36Sopenharmony_ci inb_p(ICP); 133862306a36Sopenharmony_ci } 133962306a36Sopenharmony_ci 134062306a36Sopenharmony_ci /* forget possible initially masked and pending IRQ */ 134162306a36Sopenharmony_ci probe_irq_off(probe_irq_on()); 134262306a36Sopenharmony_ci save_mcr = serial8250_in_MCR(up); 134362306a36Sopenharmony_ci /* Synchronize UART_IER access against the console. */ 134462306a36Sopenharmony_ci spin_lock_irq(&port->lock); 134562306a36Sopenharmony_ci save_ier = serial_in(up, UART_IER); 134662306a36Sopenharmony_ci spin_unlock_irq(&port->lock); 134762306a36Sopenharmony_ci serial8250_out_MCR(up, UART_MCR_OUT1 | UART_MCR_OUT2); 134862306a36Sopenharmony_ci 134962306a36Sopenharmony_ci irqs = probe_irq_on(); 135062306a36Sopenharmony_ci serial8250_out_MCR(up, 0); 135162306a36Sopenharmony_ci udelay(10); 135262306a36Sopenharmony_ci if (port->flags & UPF_FOURPORT) { 135362306a36Sopenharmony_ci serial8250_out_MCR(up, UART_MCR_DTR | UART_MCR_RTS); 135462306a36Sopenharmony_ci } else { 135562306a36Sopenharmony_ci serial8250_out_MCR(up, 135662306a36Sopenharmony_ci UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2); 135762306a36Sopenharmony_ci } 135862306a36Sopenharmony_ci /* Synchronize UART_IER access against the console. */ 135962306a36Sopenharmony_ci spin_lock_irq(&port->lock); 136062306a36Sopenharmony_ci serial_out(up, UART_IER, UART_IER_ALL_INTR); 136162306a36Sopenharmony_ci spin_unlock_irq(&port->lock); 136262306a36Sopenharmony_ci serial_in(up, UART_LSR); 136362306a36Sopenharmony_ci serial_in(up, UART_RX); 136462306a36Sopenharmony_ci serial_in(up, UART_IIR); 136562306a36Sopenharmony_ci serial_in(up, UART_MSR); 136662306a36Sopenharmony_ci serial_out(up, UART_TX, 0xFF); 136762306a36Sopenharmony_ci udelay(20); 136862306a36Sopenharmony_ci irq = probe_irq_off(irqs); 136962306a36Sopenharmony_ci 137062306a36Sopenharmony_ci serial8250_out_MCR(up, save_mcr); 137162306a36Sopenharmony_ci /* Synchronize UART_IER access against the console. */ 137262306a36Sopenharmony_ci spin_lock_irq(&port->lock); 137362306a36Sopenharmony_ci serial_out(up, UART_IER, save_ier); 137462306a36Sopenharmony_ci spin_unlock_irq(&port->lock); 137562306a36Sopenharmony_ci 137662306a36Sopenharmony_ci if (port->flags & UPF_FOURPORT) 137762306a36Sopenharmony_ci outb_p(save_ICP, ICP); 137862306a36Sopenharmony_ci 137962306a36Sopenharmony_ci port->irq = (irq > 0) ? irq : 0; 138062306a36Sopenharmony_ci} 138162306a36Sopenharmony_ci 138262306a36Sopenharmony_cistatic void serial8250_stop_rx(struct uart_port *port) 138362306a36Sopenharmony_ci{ 138462306a36Sopenharmony_ci struct uart_8250_port *up = up_to_u8250p(port); 138562306a36Sopenharmony_ci 138662306a36Sopenharmony_ci /* Port locked to synchronize UART_IER access against the console. */ 138762306a36Sopenharmony_ci lockdep_assert_held_once(&port->lock); 138862306a36Sopenharmony_ci 138962306a36Sopenharmony_ci serial8250_rpm_get(up); 139062306a36Sopenharmony_ci 139162306a36Sopenharmony_ci up->ier &= ~(UART_IER_RLSI | UART_IER_RDI); 139262306a36Sopenharmony_ci up->port.read_status_mask &= ~UART_LSR_DR; 139362306a36Sopenharmony_ci serial_port_out(port, UART_IER, up->ier); 139462306a36Sopenharmony_ci 139562306a36Sopenharmony_ci serial8250_rpm_put(up); 139662306a36Sopenharmony_ci} 139762306a36Sopenharmony_ci 139862306a36Sopenharmony_ci/** 139962306a36Sopenharmony_ci * serial8250_em485_stop_tx() - generic ->rs485_stop_tx() callback 140062306a36Sopenharmony_ci * @p: uart 8250 port 140162306a36Sopenharmony_ci * 140262306a36Sopenharmony_ci * Generic callback usable by 8250 uart drivers to stop rs485 transmission. 140362306a36Sopenharmony_ci */ 140462306a36Sopenharmony_civoid serial8250_em485_stop_tx(struct uart_8250_port *p) 140562306a36Sopenharmony_ci{ 140662306a36Sopenharmony_ci unsigned char mcr = serial8250_in_MCR(p); 140762306a36Sopenharmony_ci 140862306a36Sopenharmony_ci /* Port locked to synchronize UART_IER access against the console. */ 140962306a36Sopenharmony_ci lockdep_assert_held_once(&p->port.lock); 141062306a36Sopenharmony_ci 141162306a36Sopenharmony_ci if (p->port.rs485.flags & SER_RS485_RTS_AFTER_SEND) 141262306a36Sopenharmony_ci mcr |= UART_MCR_RTS; 141362306a36Sopenharmony_ci else 141462306a36Sopenharmony_ci mcr &= ~UART_MCR_RTS; 141562306a36Sopenharmony_ci serial8250_out_MCR(p, mcr); 141662306a36Sopenharmony_ci 141762306a36Sopenharmony_ci /* 141862306a36Sopenharmony_ci * Empty the RX FIFO, we are not interested in anything 141962306a36Sopenharmony_ci * received during the half-duplex transmission. 142062306a36Sopenharmony_ci * Enable previously disabled RX interrupts. 142162306a36Sopenharmony_ci */ 142262306a36Sopenharmony_ci if (!(p->port.rs485.flags & SER_RS485_RX_DURING_TX)) { 142362306a36Sopenharmony_ci serial8250_clear_and_reinit_fifos(p); 142462306a36Sopenharmony_ci 142562306a36Sopenharmony_ci p->ier |= UART_IER_RLSI | UART_IER_RDI; 142662306a36Sopenharmony_ci serial_port_out(&p->port, UART_IER, p->ier); 142762306a36Sopenharmony_ci } 142862306a36Sopenharmony_ci} 142962306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(serial8250_em485_stop_tx); 143062306a36Sopenharmony_ci 143162306a36Sopenharmony_cistatic enum hrtimer_restart serial8250_em485_handle_stop_tx(struct hrtimer *t) 143262306a36Sopenharmony_ci{ 143362306a36Sopenharmony_ci struct uart_8250_em485 *em485 = container_of(t, struct uart_8250_em485, 143462306a36Sopenharmony_ci stop_tx_timer); 143562306a36Sopenharmony_ci struct uart_8250_port *p = em485->port; 143662306a36Sopenharmony_ci unsigned long flags; 143762306a36Sopenharmony_ci 143862306a36Sopenharmony_ci serial8250_rpm_get(p); 143962306a36Sopenharmony_ci spin_lock_irqsave(&p->port.lock, flags); 144062306a36Sopenharmony_ci if (em485->active_timer == &em485->stop_tx_timer) { 144162306a36Sopenharmony_ci p->rs485_stop_tx(p); 144262306a36Sopenharmony_ci em485->active_timer = NULL; 144362306a36Sopenharmony_ci em485->tx_stopped = true; 144462306a36Sopenharmony_ci } 144562306a36Sopenharmony_ci spin_unlock_irqrestore(&p->port.lock, flags); 144662306a36Sopenharmony_ci serial8250_rpm_put(p); 144762306a36Sopenharmony_ci 144862306a36Sopenharmony_ci return HRTIMER_NORESTART; 144962306a36Sopenharmony_ci} 145062306a36Sopenharmony_ci 145162306a36Sopenharmony_cistatic void start_hrtimer_ms(struct hrtimer *hrt, unsigned long msec) 145262306a36Sopenharmony_ci{ 145362306a36Sopenharmony_ci hrtimer_start(hrt, ms_to_ktime(msec), HRTIMER_MODE_REL); 145462306a36Sopenharmony_ci} 145562306a36Sopenharmony_ci 145662306a36Sopenharmony_cistatic void __stop_tx_rs485(struct uart_8250_port *p, u64 stop_delay) 145762306a36Sopenharmony_ci{ 145862306a36Sopenharmony_ci struct uart_8250_em485 *em485 = p->em485; 145962306a36Sopenharmony_ci 146062306a36Sopenharmony_ci /* Port locked to synchronize UART_IER access against the console. */ 146162306a36Sopenharmony_ci lockdep_assert_held_once(&p->port.lock); 146262306a36Sopenharmony_ci 146362306a36Sopenharmony_ci stop_delay += (u64)p->port.rs485.delay_rts_after_send * NSEC_PER_MSEC; 146462306a36Sopenharmony_ci 146562306a36Sopenharmony_ci /* 146662306a36Sopenharmony_ci * rs485_stop_tx() is going to set RTS according to config 146762306a36Sopenharmony_ci * AND flush RX FIFO if required. 146862306a36Sopenharmony_ci */ 146962306a36Sopenharmony_ci if (stop_delay > 0) { 147062306a36Sopenharmony_ci em485->active_timer = &em485->stop_tx_timer; 147162306a36Sopenharmony_ci hrtimer_start(&em485->stop_tx_timer, ns_to_ktime(stop_delay), HRTIMER_MODE_REL); 147262306a36Sopenharmony_ci } else { 147362306a36Sopenharmony_ci p->rs485_stop_tx(p); 147462306a36Sopenharmony_ci em485->active_timer = NULL; 147562306a36Sopenharmony_ci em485->tx_stopped = true; 147662306a36Sopenharmony_ci } 147762306a36Sopenharmony_ci} 147862306a36Sopenharmony_ci 147962306a36Sopenharmony_cistatic inline void __stop_tx(struct uart_8250_port *p) 148062306a36Sopenharmony_ci{ 148162306a36Sopenharmony_ci struct uart_8250_em485 *em485 = p->em485; 148262306a36Sopenharmony_ci 148362306a36Sopenharmony_ci if (em485) { 148462306a36Sopenharmony_ci u16 lsr = serial_lsr_in(p); 148562306a36Sopenharmony_ci u64 stop_delay = 0; 148662306a36Sopenharmony_ci 148762306a36Sopenharmony_ci if (!(lsr & UART_LSR_THRE)) 148862306a36Sopenharmony_ci return; 148962306a36Sopenharmony_ci /* 149062306a36Sopenharmony_ci * To provide required timing and allow FIFO transfer, 149162306a36Sopenharmony_ci * __stop_tx_rs485() must be called only when both FIFO and 149262306a36Sopenharmony_ci * shift register are empty. The device driver should either 149362306a36Sopenharmony_ci * enable interrupt on TEMT or set UART_CAP_NOTEMT that will 149462306a36Sopenharmony_ci * enlarge stop_tx_timer by the tx time of one frame to cover 149562306a36Sopenharmony_ci * for emptying of the shift register. 149662306a36Sopenharmony_ci */ 149762306a36Sopenharmony_ci if (!(lsr & UART_LSR_TEMT)) { 149862306a36Sopenharmony_ci if (!(p->capabilities & UART_CAP_NOTEMT)) 149962306a36Sopenharmony_ci return; 150062306a36Sopenharmony_ci /* 150162306a36Sopenharmony_ci * RTS might get deasserted too early with the normal 150262306a36Sopenharmony_ci * frame timing formula. It seems to suggest THRE might 150362306a36Sopenharmony_ci * get asserted already during tx of the stop bit 150462306a36Sopenharmony_ci * rather than after it is fully sent. 150562306a36Sopenharmony_ci * Roughly estimate 1 extra bit here with / 7. 150662306a36Sopenharmony_ci */ 150762306a36Sopenharmony_ci stop_delay = p->port.frame_time + DIV_ROUND_UP(p->port.frame_time, 7); 150862306a36Sopenharmony_ci } 150962306a36Sopenharmony_ci 151062306a36Sopenharmony_ci __stop_tx_rs485(p, stop_delay); 151162306a36Sopenharmony_ci } 151262306a36Sopenharmony_ci 151362306a36Sopenharmony_ci if (serial8250_clear_THRI(p)) 151462306a36Sopenharmony_ci serial8250_rpm_put_tx(p); 151562306a36Sopenharmony_ci} 151662306a36Sopenharmony_ci 151762306a36Sopenharmony_cistatic void serial8250_stop_tx(struct uart_port *port) 151862306a36Sopenharmony_ci{ 151962306a36Sopenharmony_ci struct uart_8250_port *up = up_to_u8250p(port); 152062306a36Sopenharmony_ci 152162306a36Sopenharmony_ci serial8250_rpm_get(up); 152262306a36Sopenharmony_ci __stop_tx(up); 152362306a36Sopenharmony_ci 152462306a36Sopenharmony_ci /* 152562306a36Sopenharmony_ci * We really want to stop the transmitter from sending. 152662306a36Sopenharmony_ci */ 152762306a36Sopenharmony_ci if (port->type == PORT_16C950) { 152862306a36Sopenharmony_ci up->acr |= UART_ACR_TXDIS; 152962306a36Sopenharmony_ci serial_icr_write(up, UART_ACR, up->acr); 153062306a36Sopenharmony_ci } 153162306a36Sopenharmony_ci serial8250_rpm_put(up); 153262306a36Sopenharmony_ci} 153362306a36Sopenharmony_ci 153462306a36Sopenharmony_cistatic inline void __start_tx(struct uart_port *port) 153562306a36Sopenharmony_ci{ 153662306a36Sopenharmony_ci struct uart_8250_port *up = up_to_u8250p(port); 153762306a36Sopenharmony_ci 153862306a36Sopenharmony_ci if (up->dma && !up->dma->tx_dma(up)) 153962306a36Sopenharmony_ci return; 154062306a36Sopenharmony_ci 154162306a36Sopenharmony_ci if (serial8250_set_THRI(up)) { 154262306a36Sopenharmony_ci if (up->bugs & UART_BUG_TXEN) { 154362306a36Sopenharmony_ci u16 lsr = serial_lsr_in(up); 154462306a36Sopenharmony_ci 154562306a36Sopenharmony_ci if (lsr & UART_LSR_THRE) 154662306a36Sopenharmony_ci serial8250_tx_chars(up); 154762306a36Sopenharmony_ci } 154862306a36Sopenharmony_ci } 154962306a36Sopenharmony_ci 155062306a36Sopenharmony_ci /* 155162306a36Sopenharmony_ci * Re-enable the transmitter if we disabled it. 155262306a36Sopenharmony_ci */ 155362306a36Sopenharmony_ci if (port->type == PORT_16C950 && up->acr & UART_ACR_TXDIS) { 155462306a36Sopenharmony_ci up->acr &= ~UART_ACR_TXDIS; 155562306a36Sopenharmony_ci serial_icr_write(up, UART_ACR, up->acr); 155662306a36Sopenharmony_ci } 155762306a36Sopenharmony_ci} 155862306a36Sopenharmony_ci 155962306a36Sopenharmony_ci/** 156062306a36Sopenharmony_ci * serial8250_em485_start_tx() - generic ->rs485_start_tx() callback 156162306a36Sopenharmony_ci * @up: uart 8250 port 156262306a36Sopenharmony_ci * 156362306a36Sopenharmony_ci * Generic callback usable by 8250 uart drivers to start rs485 transmission. 156462306a36Sopenharmony_ci * Assumes that setting the RTS bit in the MCR register means RTS is high. 156562306a36Sopenharmony_ci * (Some chips use inverse semantics.) Further assumes that reception is 156662306a36Sopenharmony_ci * stoppable by disabling the UART_IER_RDI interrupt. (Some chips set the 156762306a36Sopenharmony_ci * UART_LSR_DR bit even when UART_IER_RDI is disabled, foiling this approach.) 156862306a36Sopenharmony_ci */ 156962306a36Sopenharmony_civoid serial8250_em485_start_tx(struct uart_8250_port *up) 157062306a36Sopenharmony_ci{ 157162306a36Sopenharmony_ci unsigned char mcr = serial8250_in_MCR(up); 157262306a36Sopenharmony_ci 157362306a36Sopenharmony_ci if (!(up->port.rs485.flags & SER_RS485_RX_DURING_TX)) 157462306a36Sopenharmony_ci serial8250_stop_rx(&up->port); 157562306a36Sopenharmony_ci 157662306a36Sopenharmony_ci if (up->port.rs485.flags & SER_RS485_RTS_ON_SEND) 157762306a36Sopenharmony_ci mcr |= UART_MCR_RTS; 157862306a36Sopenharmony_ci else 157962306a36Sopenharmony_ci mcr &= ~UART_MCR_RTS; 158062306a36Sopenharmony_ci serial8250_out_MCR(up, mcr); 158162306a36Sopenharmony_ci} 158262306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(serial8250_em485_start_tx); 158362306a36Sopenharmony_ci 158462306a36Sopenharmony_ci/* Returns false, if start_tx_timer was setup to defer TX start */ 158562306a36Sopenharmony_cistatic bool start_tx_rs485(struct uart_port *port) 158662306a36Sopenharmony_ci{ 158762306a36Sopenharmony_ci struct uart_8250_port *up = up_to_u8250p(port); 158862306a36Sopenharmony_ci struct uart_8250_em485 *em485 = up->em485; 158962306a36Sopenharmony_ci 159062306a36Sopenharmony_ci /* 159162306a36Sopenharmony_ci * While serial8250_em485_handle_stop_tx() is a noop if 159262306a36Sopenharmony_ci * em485->active_timer != &em485->stop_tx_timer, it might happen that 159362306a36Sopenharmony_ci * the timer is still armed and triggers only after the current bunch of 159462306a36Sopenharmony_ci * chars is send and em485->active_timer == &em485->stop_tx_timer again. 159562306a36Sopenharmony_ci * So cancel the timer. There is still a theoretical race condition if 159662306a36Sopenharmony_ci * the timer is already running and only comes around to check for 159762306a36Sopenharmony_ci * em485->active_timer when &em485->stop_tx_timer is armed again. 159862306a36Sopenharmony_ci */ 159962306a36Sopenharmony_ci if (em485->active_timer == &em485->stop_tx_timer) 160062306a36Sopenharmony_ci hrtimer_try_to_cancel(&em485->stop_tx_timer); 160162306a36Sopenharmony_ci 160262306a36Sopenharmony_ci em485->active_timer = NULL; 160362306a36Sopenharmony_ci 160462306a36Sopenharmony_ci if (em485->tx_stopped) { 160562306a36Sopenharmony_ci em485->tx_stopped = false; 160662306a36Sopenharmony_ci 160762306a36Sopenharmony_ci up->rs485_start_tx(up); 160862306a36Sopenharmony_ci 160962306a36Sopenharmony_ci if (up->port.rs485.delay_rts_before_send > 0) { 161062306a36Sopenharmony_ci em485->active_timer = &em485->start_tx_timer; 161162306a36Sopenharmony_ci start_hrtimer_ms(&em485->start_tx_timer, 161262306a36Sopenharmony_ci up->port.rs485.delay_rts_before_send); 161362306a36Sopenharmony_ci return false; 161462306a36Sopenharmony_ci } 161562306a36Sopenharmony_ci } 161662306a36Sopenharmony_ci 161762306a36Sopenharmony_ci return true; 161862306a36Sopenharmony_ci} 161962306a36Sopenharmony_ci 162062306a36Sopenharmony_cistatic enum hrtimer_restart serial8250_em485_handle_start_tx(struct hrtimer *t) 162162306a36Sopenharmony_ci{ 162262306a36Sopenharmony_ci struct uart_8250_em485 *em485 = container_of(t, struct uart_8250_em485, 162362306a36Sopenharmony_ci start_tx_timer); 162462306a36Sopenharmony_ci struct uart_8250_port *p = em485->port; 162562306a36Sopenharmony_ci unsigned long flags; 162662306a36Sopenharmony_ci 162762306a36Sopenharmony_ci spin_lock_irqsave(&p->port.lock, flags); 162862306a36Sopenharmony_ci if (em485->active_timer == &em485->start_tx_timer) { 162962306a36Sopenharmony_ci __start_tx(&p->port); 163062306a36Sopenharmony_ci em485->active_timer = NULL; 163162306a36Sopenharmony_ci } 163262306a36Sopenharmony_ci spin_unlock_irqrestore(&p->port.lock, flags); 163362306a36Sopenharmony_ci 163462306a36Sopenharmony_ci return HRTIMER_NORESTART; 163562306a36Sopenharmony_ci} 163662306a36Sopenharmony_ci 163762306a36Sopenharmony_cistatic void serial8250_start_tx(struct uart_port *port) 163862306a36Sopenharmony_ci{ 163962306a36Sopenharmony_ci struct uart_8250_port *up = up_to_u8250p(port); 164062306a36Sopenharmony_ci struct uart_8250_em485 *em485 = up->em485; 164162306a36Sopenharmony_ci 164262306a36Sopenharmony_ci /* Port locked to synchronize UART_IER access against the console. */ 164362306a36Sopenharmony_ci lockdep_assert_held_once(&port->lock); 164462306a36Sopenharmony_ci 164562306a36Sopenharmony_ci if (!port->x_char && uart_circ_empty(&port->state->xmit)) 164662306a36Sopenharmony_ci return; 164762306a36Sopenharmony_ci 164862306a36Sopenharmony_ci serial8250_rpm_get_tx(up); 164962306a36Sopenharmony_ci 165062306a36Sopenharmony_ci if (em485) { 165162306a36Sopenharmony_ci if ((em485->active_timer == &em485->start_tx_timer) || 165262306a36Sopenharmony_ci !start_tx_rs485(port)) 165362306a36Sopenharmony_ci return; 165462306a36Sopenharmony_ci } 165562306a36Sopenharmony_ci __start_tx(port); 165662306a36Sopenharmony_ci} 165762306a36Sopenharmony_ci 165862306a36Sopenharmony_cistatic void serial8250_throttle(struct uart_port *port) 165962306a36Sopenharmony_ci{ 166062306a36Sopenharmony_ci port->throttle(port); 166162306a36Sopenharmony_ci} 166262306a36Sopenharmony_ci 166362306a36Sopenharmony_cistatic void serial8250_unthrottle(struct uart_port *port) 166462306a36Sopenharmony_ci{ 166562306a36Sopenharmony_ci port->unthrottle(port); 166662306a36Sopenharmony_ci} 166762306a36Sopenharmony_ci 166862306a36Sopenharmony_cistatic void serial8250_disable_ms(struct uart_port *port) 166962306a36Sopenharmony_ci{ 167062306a36Sopenharmony_ci struct uart_8250_port *up = up_to_u8250p(port); 167162306a36Sopenharmony_ci 167262306a36Sopenharmony_ci /* Port locked to synchronize UART_IER access against the console. */ 167362306a36Sopenharmony_ci lockdep_assert_held_once(&port->lock); 167462306a36Sopenharmony_ci 167562306a36Sopenharmony_ci /* no MSR capabilities */ 167662306a36Sopenharmony_ci if (up->bugs & UART_BUG_NOMSR) 167762306a36Sopenharmony_ci return; 167862306a36Sopenharmony_ci 167962306a36Sopenharmony_ci mctrl_gpio_disable_ms(up->gpios); 168062306a36Sopenharmony_ci 168162306a36Sopenharmony_ci up->ier &= ~UART_IER_MSI; 168262306a36Sopenharmony_ci serial_port_out(port, UART_IER, up->ier); 168362306a36Sopenharmony_ci} 168462306a36Sopenharmony_ci 168562306a36Sopenharmony_cistatic void serial8250_enable_ms(struct uart_port *port) 168662306a36Sopenharmony_ci{ 168762306a36Sopenharmony_ci struct uart_8250_port *up = up_to_u8250p(port); 168862306a36Sopenharmony_ci 168962306a36Sopenharmony_ci /* Port locked to synchronize UART_IER access against the console. */ 169062306a36Sopenharmony_ci lockdep_assert_held_once(&port->lock); 169162306a36Sopenharmony_ci 169262306a36Sopenharmony_ci /* no MSR capabilities */ 169362306a36Sopenharmony_ci if (up->bugs & UART_BUG_NOMSR) 169462306a36Sopenharmony_ci return; 169562306a36Sopenharmony_ci 169662306a36Sopenharmony_ci mctrl_gpio_enable_ms(up->gpios); 169762306a36Sopenharmony_ci 169862306a36Sopenharmony_ci up->ier |= UART_IER_MSI; 169962306a36Sopenharmony_ci 170062306a36Sopenharmony_ci serial8250_rpm_get(up); 170162306a36Sopenharmony_ci serial_port_out(port, UART_IER, up->ier); 170262306a36Sopenharmony_ci serial8250_rpm_put(up); 170362306a36Sopenharmony_ci} 170462306a36Sopenharmony_ci 170562306a36Sopenharmony_civoid serial8250_read_char(struct uart_8250_port *up, u16 lsr) 170662306a36Sopenharmony_ci{ 170762306a36Sopenharmony_ci struct uart_port *port = &up->port; 170862306a36Sopenharmony_ci u8 ch, flag = TTY_NORMAL; 170962306a36Sopenharmony_ci 171062306a36Sopenharmony_ci if (likely(lsr & UART_LSR_DR)) 171162306a36Sopenharmony_ci ch = serial_in(up, UART_RX); 171262306a36Sopenharmony_ci else 171362306a36Sopenharmony_ci /* 171462306a36Sopenharmony_ci * Intel 82571 has a Serial Over Lan device that will 171562306a36Sopenharmony_ci * set UART_LSR_BI without setting UART_LSR_DR when 171662306a36Sopenharmony_ci * it receives a break. To avoid reading from the 171762306a36Sopenharmony_ci * receive buffer without UART_LSR_DR bit set, we 171862306a36Sopenharmony_ci * just force the read character to be 0 171962306a36Sopenharmony_ci */ 172062306a36Sopenharmony_ci ch = 0; 172162306a36Sopenharmony_ci 172262306a36Sopenharmony_ci port->icount.rx++; 172362306a36Sopenharmony_ci 172462306a36Sopenharmony_ci lsr |= up->lsr_saved_flags; 172562306a36Sopenharmony_ci up->lsr_saved_flags = 0; 172662306a36Sopenharmony_ci 172762306a36Sopenharmony_ci if (unlikely(lsr & UART_LSR_BRK_ERROR_BITS)) { 172862306a36Sopenharmony_ci if (lsr & UART_LSR_BI) { 172962306a36Sopenharmony_ci lsr &= ~(UART_LSR_FE | UART_LSR_PE); 173062306a36Sopenharmony_ci port->icount.brk++; 173162306a36Sopenharmony_ci /* 173262306a36Sopenharmony_ci * We do the SysRQ and SAK checking 173362306a36Sopenharmony_ci * here because otherwise the break 173462306a36Sopenharmony_ci * may get masked by ignore_status_mask 173562306a36Sopenharmony_ci * or read_status_mask. 173662306a36Sopenharmony_ci */ 173762306a36Sopenharmony_ci if (uart_handle_break(port)) 173862306a36Sopenharmony_ci return; 173962306a36Sopenharmony_ci } else if (lsr & UART_LSR_PE) 174062306a36Sopenharmony_ci port->icount.parity++; 174162306a36Sopenharmony_ci else if (lsr & UART_LSR_FE) 174262306a36Sopenharmony_ci port->icount.frame++; 174362306a36Sopenharmony_ci if (lsr & UART_LSR_OE) 174462306a36Sopenharmony_ci port->icount.overrun++; 174562306a36Sopenharmony_ci 174662306a36Sopenharmony_ci /* 174762306a36Sopenharmony_ci * Mask off conditions which should be ignored. 174862306a36Sopenharmony_ci */ 174962306a36Sopenharmony_ci lsr &= port->read_status_mask; 175062306a36Sopenharmony_ci 175162306a36Sopenharmony_ci if (lsr & UART_LSR_BI) { 175262306a36Sopenharmony_ci dev_dbg(port->dev, "handling break\n"); 175362306a36Sopenharmony_ci flag = TTY_BREAK; 175462306a36Sopenharmony_ci } else if (lsr & UART_LSR_PE) 175562306a36Sopenharmony_ci flag = TTY_PARITY; 175662306a36Sopenharmony_ci else if (lsr & UART_LSR_FE) 175762306a36Sopenharmony_ci flag = TTY_FRAME; 175862306a36Sopenharmony_ci } 175962306a36Sopenharmony_ci if (uart_prepare_sysrq_char(port, ch)) 176062306a36Sopenharmony_ci return; 176162306a36Sopenharmony_ci 176262306a36Sopenharmony_ci uart_insert_char(port, lsr, UART_LSR_OE, ch, flag); 176362306a36Sopenharmony_ci} 176462306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(serial8250_read_char); 176562306a36Sopenharmony_ci 176662306a36Sopenharmony_ci/* 176762306a36Sopenharmony_ci * serial8250_rx_chars - Read characters. The first LSR value must be passed in. 176862306a36Sopenharmony_ci * 176962306a36Sopenharmony_ci * Returns LSR bits. The caller should rely only on non-Rx related LSR bits 177062306a36Sopenharmony_ci * (such as THRE) because the LSR value might come from an already consumed 177162306a36Sopenharmony_ci * character. 177262306a36Sopenharmony_ci */ 177362306a36Sopenharmony_ciu16 serial8250_rx_chars(struct uart_8250_port *up, u16 lsr) 177462306a36Sopenharmony_ci{ 177562306a36Sopenharmony_ci struct uart_port *port = &up->port; 177662306a36Sopenharmony_ci int max_count = 256; 177762306a36Sopenharmony_ci 177862306a36Sopenharmony_ci do { 177962306a36Sopenharmony_ci serial8250_read_char(up, lsr); 178062306a36Sopenharmony_ci if (--max_count == 0) 178162306a36Sopenharmony_ci break; 178262306a36Sopenharmony_ci lsr = serial_in(up, UART_LSR); 178362306a36Sopenharmony_ci } while (lsr & (UART_LSR_DR | UART_LSR_BI)); 178462306a36Sopenharmony_ci 178562306a36Sopenharmony_ci tty_flip_buffer_push(&port->state->port); 178662306a36Sopenharmony_ci return lsr; 178762306a36Sopenharmony_ci} 178862306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(serial8250_rx_chars); 178962306a36Sopenharmony_ci 179062306a36Sopenharmony_civoid serial8250_tx_chars(struct uart_8250_port *up) 179162306a36Sopenharmony_ci{ 179262306a36Sopenharmony_ci struct uart_port *port = &up->port; 179362306a36Sopenharmony_ci struct circ_buf *xmit = &port->state->xmit; 179462306a36Sopenharmony_ci int count; 179562306a36Sopenharmony_ci 179662306a36Sopenharmony_ci if (port->x_char) { 179762306a36Sopenharmony_ci uart_xchar_out(port, UART_TX); 179862306a36Sopenharmony_ci return; 179962306a36Sopenharmony_ci } 180062306a36Sopenharmony_ci if (uart_tx_stopped(port)) { 180162306a36Sopenharmony_ci serial8250_stop_tx(port); 180262306a36Sopenharmony_ci return; 180362306a36Sopenharmony_ci } 180462306a36Sopenharmony_ci if (uart_circ_empty(xmit)) { 180562306a36Sopenharmony_ci __stop_tx(up); 180662306a36Sopenharmony_ci return; 180762306a36Sopenharmony_ci } 180862306a36Sopenharmony_ci 180962306a36Sopenharmony_ci count = up->tx_loadsz; 181062306a36Sopenharmony_ci do { 181162306a36Sopenharmony_ci serial_out(up, UART_TX, xmit->buf[xmit->tail]); 181262306a36Sopenharmony_ci if (up->bugs & UART_BUG_TXRACE) { 181362306a36Sopenharmony_ci /* 181462306a36Sopenharmony_ci * The Aspeed BMC virtual UARTs have a bug where data 181562306a36Sopenharmony_ci * may get stuck in the BMC's Tx FIFO from bursts of 181662306a36Sopenharmony_ci * writes on the APB interface. 181762306a36Sopenharmony_ci * 181862306a36Sopenharmony_ci * Delay back-to-back writes by a read cycle to avoid 181962306a36Sopenharmony_ci * stalling the VUART. Read a register that won't have 182062306a36Sopenharmony_ci * side-effects and discard the result. 182162306a36Sopenharmony_ci */ 182262306a36Sopenharmony_ci serial_in(up, UART_SCR); 182362306a36Sopenharmony_ci } 182462306a36Sopenharmony_ci uart_xmit_advance(port, 1); 182562306a36Sopenharmony_ci if (uart_circ_empty(xmit)) 182662306a36Sopenharmony_ci break; 182762306a36Sopenharmony_ci if ((up->capabilities & UART_CAP_HFIFO) && 182862306a36Sopenharmony_ci !uart_lsr_tx_empty(serial_in(up, UART_LSR))) 182962306a36Sopenharmony_ci break; 183062306a36Sopenharmony_ci /* The BCM2835 MINI UART THRE bit is really a not-full bit. */ 183162306a36Sopenharmony_ci if ((up->capabilities & UART_CAP_MINI) && 183262306a36Sopenharmony_ci !(serial_in(up, UART_LSR) & UART_LSR_THRE)) 183362306a36Sopenharmony_ci break; 183462306a36Sopenharmony_ci } while (--count > 0); 183562306a36Sopenharmony_ci 183662306a36Sopenharmony_ci if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) 183762306a36Sopenharmony_ci uart_write_wakeup(port); 183862306a36Sopenharmony_ci 183962306a36Sopenharmony_ci /* 184062306a36Sopenharmony_ci * With RPM enabled, we have to wait until the FIFO is empty before the 184162306a36Sopenharmony_ci * HW can go idle. So we get here once again with empty FIFO and disable 184262306a36Sopenharmony_ci * the interrupt and RPM in __stop_tx() 184362306a36Sopenharmony_ci */ 184462306a36Sopenharmony_ci if (uart_circ_empty(xmit) && !(up->capabilities & UART_CAP_RPM)) 184562306a36Sopenharmony_ci __stop_tx(up); 184662306a36Sopenharmony_ci} 184762306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(serial8250_tx_chars); 184862306a36Sopenharmony_ci 184962306a36Sopenharmony_ci/* Caller holds uart port lock */ 185062306a36Sopenharmony_ciunsigned int serial8250_modem_status(struct uart_8250_port *up) 185162306a36Sopenharmony_ci{ 185262306a36Sopenharmony_ci struct uart_port *port = &up->port; 185362306a36Sopenharmony_ci unsigned int status = serial_in(up, UART_MSR); 185462306a36Sopenharmony_ci 185562306a36Sopenharmony_ci status |= up->msr_saved_flags; 185662306a36Sopenharmony_ci up->msr_saved_flags = 0; 185762306a36Sopenharmony_ci if (status & UART_MSR_ANY_DELTA && up->ier & UART_IER_MSI && 185862306a36Sopenharmony_ci port->state != NULL) { 185962306a36Sopenharmony_ci if (status & UART_MSR_TERI) 186062306a36Sopenharmony_ci port->icount.rng++; 186162306a36Sopenharmony_ci if (status & UART_MSR_DDSR) 186262306a36Sopenharmony_ci port->icount.dsr++; 186362306a36Sopenharmony_ci if (status & UART_MSR_DDCD) 186462306a36Sopenharmony_ci uart_handle_dcd_change(port, status & UART_MSR_DCD); 186562306a36Sopenharmony_ci if (status & UART_MSR_DCTS) 186662306a36Sopenharmony_ci uart_handle_cts_change(port, status & UART_MSR_CTS); 186762306a36Sopenharmony_ci 186862306a36Sopenharmony_ci wake_up_interruptible(&port->state->port.delta_msr_wait); 186962306a36Sopenharmony_ci } 187062306a36Sopenharmony_ci 187162306a36Sopenharmony_ci return status; 187262306a36Sopenharmony_ci} 187362306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(serial8250_modem_status); 187462306a36Sopenharmony_ci 187562306a36Sopenharmony_cistatic bool handle_rx_dma(struct uart_8250_port *up, unsigned int iir) 187662306a36Sopenharmony_ci{ 187762306a36Sopenharmony_ci switch (iir & 0x3f) { 187862306a36Sopenharmony_ci case UART_IIR_THRI: 187962306a36Sopenharmony_ci /* 188062306a36Sopenharmony_ci * Postpone DMA or not decision to IIR_RDI or IIR_RX_TIMEOUT 188162306a36Sopenharmony_ci * because it's impossible to do an informed decision about 188262306a36Sopenharmony_ci * that with IIR_THRI. 188362306a36Sopenharmony_ci * 188462306a36Sopenharmony_ci * This also fixes one known DMA Rx corruption issue where 188562306a36Sopenharmony_ci * DR is asserted but DMA Rx only gets a corrupted zero byte 188662306a36Sopenharmony_ci * (too early DR?). 188762306a36Sopenharmony_ci */ 188862306a36Sopenharmony_ci return false; 188962306a36Sopenharmony_ci case UART_IIR_RDI: 189062306a36Sopenharmony_ci if (!up->dma->rx_running) 189162306a36Sopenharmony_ci break; 189262306a36Sopenharmony_ci fallthrough; 189362306a36Sopenharmony_ci case UART_IIR_RLSI: 189462306a36Sopenharmony_ci case UART_IIR_RX_TIMEOUT: 189562306a36Sopenharmony_ci serial8250_rx_dma_flush(up); 189662306a36Sopenharmony_ci return true; 189762306a36Sopenharmony_ci } 189862306a36Sopenharmony_ci return up->dma->rx_dma(up); 189962306a36Sopenharmony_ci} 190062306a36Sopenharmony_ci 190162306a36Sopenharmony_ci/* 190262306a36Sopenharmony_ci * This handles the interrupt from one port. 190362306a36Sopenharmony_ci */ 190462306a36Sopenharmony_ciint serial8250_handle_irq(struct uart_port *port, unsigned int iir) 190562306a36Sopenharmony_ci{ 190662306a36Sopenharmony_ci struct uart_8250_port *up = up_to_u8250p(port); 190762306a36Sopenharmony_ci struct tty_port *tport = &port->state->port; 190862306a36Sopenharmony_ci bool skip_rx = false; 190962306a36Sopenharmony_ci unsigned long flags; 191062306a36Sopenharmony_ci u16 status; 191162306a36Sopenharmony_ci 191262306a36Sopenharmony_ci if (iir & UART_IIR_NO_INT) 191362306a36Sopenharmony_ci return 0; 191462306a36Sopenharmony_ci 191562306a36Sopenharmony_ci spin_lock_irqsave(&port->lock, flags); 191662306a36Sopenharmony_ci 191762306a36Sopenharmony_ci status = serial_lsr_in(up); 191862306a36Sopenharmony_ci 191962306a36Sopenharmony_ci /* 192062306a36Sopenharmony_ci * If port is stopped and there are no error conditions in the 192162306a36Sopenharmony_ci * FIFO, then don't drain the FIFO, as this may lead to TTY buffer 192262306a36Sopenharmony_ci * overflow. Not servicing, RX FIFO would trigger auto HW flow 192362306a36Sopenharmony_ci * control when FIFO occupancy reaches preset threshold, thus 192462306a36Sopenharmony_ci * halting RX. This only works when auto HW flow control is 192562306a36Sopenharmony_ci * available. 192662306a36Sopenharmony_ci */ 192762306a36Sopenharmony_ci if (!(status & (UART_LSR_FIFOE | UART_LSR_BRK_ERROR_BITS)) && 192862306a36Sopenharmony_ci (port->status & (UPSTAT_AUTOCTS | UPSTAT_AUTORTS)) && 192962306a36Sopenharmony_ci !(port->read_status_mask & UART_LSR_DR)) 193062306a36Sopenharmony_ci skip_rx = true; 193162306a36Sopenharmony_ci 193262306a36Sopenharmony_ci if (status & (UART_LSR_DR | UART_LSR_BI) && !skip_rx) { 193362306a36Sopenharmony_ci struct irq_data *d; 193462306a36Sopenharmony_ci 193562306a36Sopenharmony_ci d = irq_get_irq_data(port->irq); 193662306a36Sopenharmony_ci if (d && irqd_is_wakeup_set(d)) 193762306a36Sopenharmony_ci pm_wakeup_event(tport->tty->dev, 0); 193862306a36Sopenharmony_ci if (!up->dma || handle_rx_dma(up, iir)) 193962306a36Sopenharmony_ci status = serial8250_rx_chars(up, status); 194062306a36Sopenharmony_ci } 194162306a36Sopenharmony_ci serial8250_modem_status(up); 194262306a36Sopenharmony_ci if ((status & UART_LSR_THRE) && (up->ier & UART_IER_THRI)) { 194362306a36Sopenharmony_ci if (!up->dma || up->dma->tx_err) 194462306a36Sopenharmony_ci serial8250_tx_chars(up); 194562306a36Sopenharmony_ci else if (!up->dma->tx_running) 194662306a36Sopenharmony_ci __stop_tx(up); 194762306a36Sopenharmony_ci } 194862306a36Sopenharmony_ci 194962306a36Sopenharmony_ci uart_unlock_and_check_sysrq_irqrestore(port, flags); 195062306a36Sopenharmony_ci 195162306a36Sopenharmony_ci return 1; 195262306a36Sopenharmony_ci} 195362306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(serial8250_handle_irq); 195462306a36Sopenharmony_ci 195562306a36Sopenharmony_cistatic int serial8250_default_handle_irq(struct uart_port *port) 195662306a36Sopenharmony_ci{ 195762306a36Sopenharmony_ci struct uart_8250_port *up = up_to_u8250p(port); 195862306a36Sopenharmony_ci unsigned int iir; 195962306a36Sopenharmony_ci int ret; 196062306a36Sopenharmony_ci 196162306a36Sopenharmony_ci serial8250_rpm_get(up); 196262306a36Sopenharmony_ci 196362306a36Sopenharmony_ci iir = serial_port_in(port, UART_IIR); 196462306a36Sopenharmony_ci ret = serial8250_handle_irq(port, iir); 196562306a36Sopenharmony_ci 196662306a36Sopenharmony_ci serial8250_rpm_put(up); 196762306a36Sopenharmony_ci return ret; 196862306a36Sopenharmony_ci} 196962306a36Sopenharmony_ci 197062306a36Sopenharmony_ci/* 197162306a36Sopenharmony_ci * Newer 16550 compatible parts such as the SC16C650 & Altera 16550 Soft IP 197262306a36Sopenharmony_ci * have a programmable TX threshold that triggers the THRE interrupt in 197362306a36Sopenharmony_ci * the IIR register. In this case, the THRE interrupt indicates the FIFO 197462306a36Sopenharmony_ci * has space available. Load it up with tx_loadsz bytes. 197562306a36Sopenharmony_ci */ 197662306a36Sopenharmony_cistatic int serial8250_tx_threshold_handle_irq(struct uart_port *port) 197762306a36Sopenharmony_ci{ 197862306a36Sopenharmony_ci unsigned long flags; 197962306a36Sopenharmony_ci unsigned int iir = serial_port_in(port, UART_IIR); 198062306a36Sopenharmony_ci 198162306a36Sopenharmony_ci /* TX Threshold IRQ triggered so load up FIFO */ 198262306a36Sopenharmony_ci if ((iir & UART_IIR_ID) == UART_IIR_THRI) { 198362306a36Sopenharmony_ci struct uart_8250_port *up = up_to_u8250p(port); 198462306a36Sopenharmony_ci 198562306a36Sopenharmony_ci spin_lock_irqsave(&port->lock, flags); 198662306a36Sopenharmony_ci serial8250_tx_chars(up); 198762306a36Sopenharmony_ci spin_unlock_irqrestore(&port->lock, flags); 198862306a36Sopenharmony_ci } 198962306a36Sopenharmony_ci 199062306a36Sopenharmony_ci iir = serial_port_in(port, UART_IIR); 199162306a36Sopenharmony_ci return serial8250_handle_irq(port, iir); 199262306a36Sopenharmony_ci} 199362306a36Sopenharmony_ci 199462306a36Sopenharmony_cistatic unsigned int serial8250_tx_empty(struct uart_port *port) 199562306a36Sopenharmony_ci{ 199662306a36Sopenharmony_ci struct uart_8250_port *up = up_to_u8250p(port); 199762306a36Sopenharmony_ci unsigned int result = 0; 199862306a36Sopenharmony_ci unsigned long flags; 199962306a36Sopenharmony_ci 200062306a36Sopenharmony_ci serial8250_rpm_get(up); 200162306a36Sopenharmony_ci 200262306a36Sopenharmony_ci spin_lock_irqsave(&port->lock, flags); 200362306a36Sopenharmony_ci if (!serial8250_tx_dma_running(up) && uart_lsr_tx_empty(serial_lsr_in(up))) 200462306a36Sopenharmony_ci result = TIOCSER_TEMT; 200562306a36Sopenharmony_ci spin_unlock_irqrestore(&port->lock, flags); 200662306a36Sopenharmony_ci 200762306a36Sopenharmony_ci serial8250_rpm_put(up); 200862306a36Sopenharmony_ci 200962306a36Sopenharmony_ci return result; 201062306a36Sopenharmony_ci} 201162306a36Sopenharmony_ci 201262306a36Sopenharmony_ciunsigned int serial8250_do_get_mctrl(struct uart_port *port) 201362306a36Sopenharmony_ci{ 201462306a36Sopenharmony_ci struct uart_8250_port *up = up_to_u8250p(port); 201562306a36Sopenharmony_ci unsigned int status; 201662306a36Sopenharmony_ci unsigned int val; 201762306a36Sopenharmony_ci 201862306a36Sopenharmony_ci serial8250_rpm_get(up); 201962306a36Sopenharmony_ci status = serial8250_modem_status(up); 202062306a36Sopenharmony_ci serial8250_rpm_put(up); 202162306a36Sopenharmony_ci 202262306a36Sopenharmony_ci val = serial8250_MSR_to_TIOCM(status); 202362306a36Sopenharmony_ci if (up->gpios) 202462306a36Sopenharmony_ci return mctrl_gpio_get(up->gpios, &val); 202562306a36Sopenharmony_ci 202662306a36Sopenharmony_ci return val; 202762306a36Sopenharmony_ci} 202862306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(serial8250_do_get_mctrl); 202962306a36Sopenharmony_ci 203062306a36Sopenharmony_cistatic unsigned int serial8250_get_mctrl(struct uart_port *port) 203162306a36Sopenharmony_ci{ 203262306a36Sopenharmony_ci if (port->get_mctrl) 203362306a36Sopenharmony_ci return port->get_mctrl(port); 203462306a36Sopenharmony_ci return serial8250_do_get_mctrl(port); 203562306a36Sopenharmony_ci} 203662306a36Sopenharmony_ci 203762306a36Sopenharmony_civoid serial8250_do_set_mctrl(struct uart_port *port, unsigned int mctrl) 203862306a36Sopenharmony_ci{ 203962306a36Sopenharmony_ci struct uart_8250_port *up = up_to_u8250p(port); 204062306a36Sopenharmony_ci unsigned char mcr; 204162306a36Sopenharmony_ci 204262306a36Sopenharmony_ci mcr = serial8250_TIOCM_to_MCR(mctrl); 204362306a36Sopenharmony_ci 204462306a36Sopenharmony_ci mcr |= up->mcr; 204562306a36Sopenharmony_ci 204662306a36Sopenharmony_ci serial8250_out_MCR(up, mcr); 204762306a36Sopenharmony_ci} 204862306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(serial8250_do_set_mctrl); 204962306a36Sopenharmony_ci 205062306a36Sopenharmony_cistatic void serial8250_set_mctrl(struct uart_port *port, unsigned int mctrl) 205162306a36Sopenharmony_ci{ 205262306a36Sopenharmony_ci if (port->rs485.flags & SER_RS485_ENABLED) 205362306a36Sopenharmony_ci return; 205462306a36Sopenharmony_ci 205562306a36Sopenharmony_ci if (port->set_mctrl) 205662306a36Sopenharmony_ci port->set_mctrl(port, mctrl); 205762306a36Sopenharmony_ci else 205862306a36Sopenharmony_ci serial8250_do_set_mctrl(port, mctrl); 205962306a36Sopenharmony_ci} 206062306a36Sopenharmony_ci 206162306a36Sopenharmony_cistatic void serial8250_break_ctl(struct uart_port *port, int break_state) 206262306a36Sopenharmony_ci{ 206362306a36Sopenharmony_ci struct uart_8250_port *up = up_to_u8250p(port); 206462306a36Sopenharmony_ci unsigned long flags; 206562306a36Sopenharmony_ci 206662306a36Sopenharmony_ci serial8250_rpm_get(up); 206762306a36Sopenharmony_ci spin_lock_irqsave(&port->lock, flags); 206862306a36Sopenharmony_ci if (break_state == -1) 206962306a36Sopenharmony_ci up->lcr |= UART_LCR_SBC; 207062306a36Sopenharmony_ci else 207162306a36Sopenharmony_ci up->lcr &= ~UART_LCR_SBC; 207262306a36Sopenharmony_ci serial_port_out(port, UART_LCR, up->lcr); 207362306a36Sopenharmony_ci spin_unlock_irqrestore(&port->lock, flags); 207462306a36Sopenharmony_ci serial8250_rpm_put(up); 207562306a36Sopenharmony_ci} 207662306a36Sopenharmony_ci 207762306a36Sopenharmony_cistatic void wait_for_lsr(struct uart_8250_port *up, int bits) 207862306a36Sopenharmony_ci{ 207962306a36Sopenharmony_ci unsigned int status, tmout = 10000; 208062306a36Sopenharmony_ci 208162306a36Sopenharmony_ci /* Wait up to 10ms for the character(s) to be sent. */ 208262306a36Sopenharmony_ci for (;;) { 208362306a36Sopenharmony_ci status = serial_lsr_in(up); 208462306a36Sopenharmony_ci 208562306a36Sopenharmony_ci if ((status & bits) == bits) 208662306a36Sopenharmony_ci break; 208762306a36Sopenharmony_ci if (--tmout == 0) 208862306a36Sopenharmony_ci break; 208962306a36Sopenharmony_ci udelay(1); 209062306a36Sopenharmony_ci touch_nmi_watchdog(); 209162306a36Sopenharmony_ci } 209262306a36Sopenharmony_ci} 209362306a36Sopenharmony_ci 209462306a36Sopenharmony_ci/* 209562306a36Sopenharmony_ci * Wait for transmitter & holding register to empty 209662306a36Sopenharmony_ci */ 209762306a36Sopenharmony_cistatic void wait_for_xmitr(struct uart_8250_port *up, int bits) 209862306a36Sopenharmony_ci{ 209962306a36Sopenharmony_ci unsigned int tmout; 210062306a36Sopenharmony_ci 210162306a36Sopenharmony_ci wait_for_lsr(up, bits); 210262306a36Sopenharmony_ci 210362306a36Sopenharmony_ci /* Wait up to 1s for flow control if necessary */ 210462306a36Sopenharmony_ci if (up->port.flags & UPF_CONS_FLOW) { 210562306a36Sopenharmony_ci for (tmout = 1000000; tmout; tmout--) { 210662306a36Sopenharmony_ci unsigned int msr = serial_in(up, UART_MSR); 210762306a36Sopenharmony_ci up->msr_saved_flags |= msr & MSR_SAVE_FLAGS; 210862306a36Sopenharmony_ci if (msr & UART_MSR_CTS) 210962306a36Sopenharmony_ci break; 211062306a36Sopenharmony_ci udelay(1); 211162306a36Sopenharmony_ci touch_nmi_watchdog(); 211262306a36Sopenharmony_ci } 211362306a36Sopenharmony_ci } 211462306a36Sopenharmony_ci} 211562306a36Sopenharmony_ci 211662306a36Sopenharmony_ci#ifdef CONFIG_CONSOLE_POLL 211762306a36Sopenharmony_ci/* 211862306a36Sopenharmony_ci * Console polling routines for writing and reading from the uart while 211962306a36Sopenharmony_ci * in an interrupt or debug context. 212062306a36Sopenharmony_ci */ 212162306a36Sopenharmony_ci 212262306a36Sopenharmony_cistatic int serial8250_get_poll_char(struct uart_port *port) 212362306a36Sopenharmony_ci{ 212462306a36Sopenharmony_ci struct uart_8250_port *up = up_to_u8250p(port); 212562306a36Sopenharmony_ci int status; 212662306a36Sopenharmony_ci u16 lsr; 212762306a36Sopenharmony_ci 212862306a36Sopenharmony_ci serial8250_rpm_get(up); 212962306a36Sopenharmony_ci 213062306a36Sopenharmony_ci lsr = serial_port_in(port, UART_LSR); 213162306a36Sopenharmony_ci 213262306a36Sopenharmony_ci if (!(lsr & UART_LSR_DR)) { 213362306a36Sopenharmony_ci status = NO_POLL_CHAR; 213462306a36Sopenharmony_ci goto out; 213562306a36Sopenharmony_ci } 213662306a36Sopenharmony_ci 213762306a36Sopenharmony_ci status = serial_port_in(port, UART_RX); 213862306a36Sopenharmony_ciout: 213962306a36Sopenharmony_ci serial8250_rpm_put(up); 214062306a36Sopenharmony_ci return status; 214162306a36Sopenharmony_ci} 214262306a36Sopenharmony_ci 214362306a36Sopenharmony_ci 214462306a36Sopenharmony_cistatic void serial8250_put_poll_char(struct uart_port *port, 214562306a36Sopenharmony_ci unsigned char c) 214662306a36Sopenharmony_ci{ 214762306a36Sopenharmony_ci unsigned int ier; 214862306a36Sopenharmony_ci struct uart_8250_port *up = up_to_u8250p(port); 214962306a36Sopenharmony_ci 215062306a36Sopenharmony_ci /* 215162306a36Sopenharmony_ci * Normally the port is locked to synchronize UART_IER access 215262306a36Sopenharmony_ci * against the console. However, this function is only used by 215362306a36Sopenharmony_ci * KDB/KGDB, where it may not be possible to acquire the port 215462306a36Sopenharmony_ci * lock because all other CPUs are quiesced. The quiescence 215562306a36Sopenharmony_ci * should allow safe lockless usage here. 215662306a36Sopenharmony_ci */ 215762306a36Sopenharmony_ci 215862306a36Sopenharmony_ci serial8250_rpm_get(up); 215962306a36Sopenharmony_ci /* 216062306a36Sopenharmony_ci * First save the IER then disable the interrupts 216162306a36Sopenharmony_ci */ 216262306a36Sopenharmony_ci ier = serial_port_in(port, UART_IER); 216362306a36Sopenharmony_ci serial8250_clear_IER(up); 216462306a36Sopenharmony_ci 216562306a36Sopenharmony_ci wait_for_xmitr(up, UART_LSR_BOTH_EMPTY); 216662306a36Sopenharmony_ci /* 216762306a36Sopenharmony_ci * Send the character out. 216862306a36Sopenharmony_ci */ 216962306a36Sopenharmony_ci serial_port_out(port, UART_TX, c); 217062306a36Sopenharmony_ci 217162306a36Sopenharmony_ci /* 217262306a36Sopenharmony_ci * Finally, wait for transmitter to become empty 217362306a36Sopenharmony_ci * and restore the IER 217462306a36Sopenharmony_ci */ 217562306a36Sopenharmony_ci wait_for_xmitr(up, UART_LSR_BOTH_EMPTY); 217662306a36Sopenharmony_ci serial_port_out(port, UART_IER, ier); 217762306a36Sopenharmony_ci serial8250_rpm_put(up); 217862306a36Sopenharmony_ci} 217962306a36Sopenharmony_ci 218062306a36Sopenharmony_ci#endif /* CONFIG_CONSOLE_POLL */ 218162306a36Sopenharmony_ci 218262306a36Sopenharmony_ciint serial8250_do_startup(struct uart_port *port) 218362306a36Sopenharmony_ci{ 218462306a36Sopenharmony_ci struct uart_8250_port *up = up_to_u8250p(port); 218562306a36Sopenharmony_ci unsigned long flags; 218662306a36Sopenharmony_ci unsigned char iir; 218762306a36Sopenharmony_ci int retval; 218862306a36Sopenharmony_ci u16 lsr; 218962306a36Sopenharmony_ci 219062306a36Sopenharmony_ci if (!port->fifosize) 219162306a36Sopenharmony_ci port->fifosize = uart_config[port->type].fifo_size; 219262306a36Sopenharmony_ci if (!up->tx_loadsz) 219362306a36Sopenharmony_ci up->tx_loadsz = uart_config[port->type].tx_loadsz; 219462306a36Sopenharmony_ci if (!up->capabilities) 219562306a36Sopenharmony_ci up->capabilities = uart_config[port->type].flags; 219662306a36Sopenharmony_ci up->mcr = 0; 219762306a36Sopenharmony_ci 219862306a36Sopenharmony_ci if (port->iotype != up->cur_iotype) 219962306a36Sopenharmony_ci set_io_from_upio(port); 220062306a36Sopenharmony_ci 220162306a36Sopenharmony_ci serial8250_rpm_get(up); 220262306a36Sopenharmony_ci if (port->type == PORT_16C950) { 220362306a36Sopenharmony_ci /* 220462306a36Sopenharmony_ci * Wake up and initialize UART 220562306a36Sopenharmony_ci * 220662306a36Sopenharmony_ci * Synchronize UART_IER access against the console. 220762306a36Sopenharmony_ci */ 220862306a36Sopenharmony_ci spin_lock_irqsave(&port->lock, flags); 220962306a36Sopenharmony_ci up->acr = 0; 221062306a36Sopenharmony_ci serial_port_out(port, UART_LCR, UART_LCR_CONF_MODE_B); 221162306a36Sopenharmony_ci serial_port_out(port, UART_EFR, UART_EFR_ECB); 221262306a36Sopenharmony_ci serial_port_out(port, UART_IER, 0); 221362306a36Sopenharmony_ci serial_port_out(port, UART_LCR, 0); 221462306a36Sopenharmony_ci serial_icr_write(up, UART_CSR, 0); /* Reset the UART */ 221562306a36Sopenharmony_ci serial_port_out(port, UART_LCR, UART_LCR_CONF_MODE_B); 221662306a36Sopenharmony_ci serial_port_out(port, UART_EFR, UART_EFR_ECB); 221762306a36Sopenharmony_ci serial_port_out(port, UART_LCR, 0); 221862306a36Sopenharmony_ci spin_unlock_irqrestore(&port->lock, flags); 221962306a36Sopenharmony_ci } 222062306a36Sopenharmony_ci 222162306a36Sopenharmony_ci if (port->type == PORT_DA830) { 222262306a36Sopenharmony_ci /* 222362306a36Sopenharmony_ci * Reset the port 222462306a36Sopenharmony_ci * 222562306a36Sopenharmony_ci * Synchronize UART_IER access against the console. 222662306a36Sopenharmony_ci */ 222762306a36Sopenharmony_ci spin_lock_irqsave(&port->lock, flags); 222862306a36Sopenharmony_ci serial_port_out(port, UART_IER, 0); 222962306a36Sopenharmony_ci serial_port_out(port, UART_DA830_PWREMU_MGMT, 0); 223062306a36Sopenharmony_ci spin_unlock_irqrestore(&port->lock, flags); 223162306a36Sopenharmony_ci mdelay(10); 223262306a36Sopenharmony_ci 223362306a36Sopenharmony_ci /* Enable Tx, Rx and free run mode */ 223462306a36Sopenharmony_ci serial_port_out(port, UART_DA830_PWREMU_MGMT, 223562306a36Sopenharmony_ci UART_DA830_PWREMU_MGMT_UTRST | 223662306a36Sopenharmony_ci UART_DA830_PWREMU_MGMT_URRST | 223762306a36Sopenharmony_ci UART_DA830_PWREMU_MGMT_FREE); 223862306a36Sopenharmony_ci } 223962306a36Sopenharmony_ci 224062306a36Sopenharmony_ci if (port->type == PORT_NPCM) { 224162306a36Sopenharmony_ci /* 224262306a36Sopenharmony_ci * Nuvoton calls the scratch register 'UART_TOR' (timeout 224362306a36Sopenharmony_ci * register). Enable it, and set TIOC (timeout interrupt 224462306a36Sopenharmony_ci * comparator) to be 0x20 for correct operation. 224562306a36Sopenharmony_ci */ 224662306a36Sopenharmony_ci serial_port_out(port, UART_NPCM_TOR, UART_NPCM_TOIE | 0x20); 224762306a36Sopenharmony_ci } 224862306a36Sopenharmony_ci 224962306a36Sopenharmony_ci#ifdef CONFIG_SERIAL_8250_RSA 225062306a36Sopenharmony_ci /* 225162306a36Sopenharmony_ci * If this is an RSA port, see if we can kick it up to the 225262306a36Sopenharmony_ci * higher speed clock. 225362306a36Sopenharmony_ci */ 225462306a36Sopenharmony_ci enable_rsa(up); 225562306a36Sopenharmony_ci#endif 225662306a36Sopenharmony_ci 225762306a36Sopenharmony_ci /* 225862306a36Sopenharmony_ci * Clear the FIFO buffers and disable them. 225962306a36Sopenharmony_ci * (they will be reenabled in set_termios()) 226062306a36Sopenharmony_ci */ 226162306a36Sopenharmony_ci serial8250_clear_fifos(up); 226262306a36Sopenharmony_ci 226362306a36Sopenharmony_ci /* 226462306a36Sopenharmony_ci * Clear the interrupt registers. 226562306a36Sopenharmony_ci */ 226662306a36Sopenharmony_ci serial_port_in(port, UART_LSR); 226762306a36Sopenharmony_ci serial_port_in(port, UART_RX); 226862306a36Sopenharmony_ci serial_port_in(port, UART_IIR); 226962306a36Sopenharmony_ci serial_port_in(port, UART_MSR); 227062306a36Sopenharmony_ci 227162306a36Sopenharmony_ci /* 227262306a36Sopenharmony_ci * At this point, there's no way the LSR could still be 0xff; 227362306a36Sopenharmony_ci * if it is, then bail out, because there's likely no UART 227462306a36Sopenharmony_ci * here. 227562306a36Sopenharmony_ci */ 227662306a36Sopenharmony_ci if (!(port->flags & UPF_BUGGY_UART) && 227762306a36Sopenharmony_ci (serial_port_in(port, UART_LSR) == 0xff)) { 227862306a36Sopenharmony_ci dev_info_ratelimited(port->dev, "LSR safety check engaged!\n"); 227962306a36Sopenharmony_ci retval = -ENODEV; 228062306a36Sopenharmony_ci goto out; 228162306a36Sopenharmony_ci } 228262306a36Sopenharmony_ci 228362306a36Sopenharmony_ci /* 228462306a36Sopenharmony_ci * For a XR16C850, we need to set the trigger levels 228562306a36Sopenharmony_ci */ 228662306a36Sopenharmony_ci if (port->type == PORT_16850) { 228762306a36Sopenharmony_ci unsigned char fctr; 228862306a36Sopenharmony_ci 228962306a36Sopenharmony_ci serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); 229062306a36Sopenharmony_ci 229162306a36Sopenharmony_ci fctr = serial_in(up, UART_FCTR) & ~(UART_FCTR_RX|UART_FCTR_TX); 229262306a36Sopenharmony_ci serial_port_out(port, UART_FCTR, 229362306a36Sopenharmony_ci fctr | UART_FCTR_TRGD | UART_FCTR_RX); 229462306a36Sopenharmony_ci serial_port_out(port, UART_TRG, UART_TRG_96); 229562306a36Sopenharmony_ci serial_port_out(port, UART_FCTR, 229662306a36Sopenharmony_ci fctr | UART_FCTR_TRGD | UART_FCTR_TX); 229762306a36Sopenharmony_ci serial_port_out(port, UART_TRG, UART_TRG_96); 229862306a36Sopenharmony_ci 229962306a36Sopenharmony_ci serial_port_out(port, UART_LCR, 0); 230062306a36Sopenharmony_ci } 230162306a36Sopenharmony_ci 230262306a36Sopenharmony_ci /* 230362306a36Sopenharmony_ci * For the Altera 16550 variants, set TX threshold trigger level. 230462306a36Sopenharmony_ci */ 230562306a36Sopenharmony_ci if (((port->type == PORT_ALTR_16550_F32) || 230662306a36Sopenharmony_ci (port->type == PORT_ALTR_16550_F64) || 230762306a36Sopenharmony_ci (port->type == PORT_ALTR_16550_F128)) && (port->fifosize > 1)) { 230862306a36Sopenharmony_ci /* Bounds checking of TX threshold (valid 0 to fifosize-2) */ 230962306a36Sopenharmony_ci if ((up->tx_loadsz < 2) || (up->tx_loadsz > port->fifosize)) { 231062306a36Sopenharmony_ci dev_err(port->dev, "TX FIFO Threshold errors, skipping\n"); 231162306a36Sopenharmony_ci } else { 231262306a36Sopenharmony_ci serial_port_out(port, UART_ALTR_AFR, 231362306a36Sopenharmony_ci UART_ALTR_EN_TXFIFO_LW); 231462306a36Sopenharmony_ci serial_port_out(port, UART_ALTR_TX_LOW, 231562306a36Sopenharmony_ci port->fifosize - up->tx_loadsz); 231662306a36Sopenharmony_ci port->handle_irq = serial8250_tx_threshold_handle_irq; 231762306a36Sopenharmony_ci } 231862306a36Sopenharmony_ci } 231962306a36Sopenharmony_ci 232062306a36Sopenharmony_ci /* Check if we need to have shared IRQs */ 232162306a36Sopenharmony_ci if (port->irq && (up->port.flags & UPF_SHARE_IRQ)) 232262306a36Sopenharmony_ci up->port.irqflags |= IRQF_SHARED; 232362306a36Sopenharmony_ci 232462306a36Sopenharmony_ci retval = up->ops->setup_irq(up); 232562306a36Sopenharmony_ci if (retval) 232662306a36Sopenharmony_ci goto out; 232762306a36Sopenharmony_ci 232862306a36Sopenharmony_ci if (port->irq && !(up->port.flags & UPF_NO_THRE_TEST)) { 232962306a36Sopenharmony_ci unsigned char iir1; 233062306a36Sopenharmony_ci 233162306a36Sopenharmony_ci if (port->irqflags & IRQF_SHARED) 233262306a36Sopenharmony_ci disable_irq_nosync(port->irq); 233362306a36Sopenharmony_ci 233462306a36Sopenharmony_ci /* 233562306a36Sopenharmony_ci * Test for UARTs that do not reassert THRE when the 233662306a36Sopenharmony_ci * transmitter is idle and the interrupt has already 233762306a36Sopenharmony_ci * been cleared. Real 16550s should always reassert 233862306a36Sopenharmony_ci * this interrupt whenever the transmitter is idle and 233962306a36Sopenharmony_ci * the interrupt is enabled. Delays are necessary to 234062306a36Sopenharmony_ci * allow register changes to become visible. 234162306a36Sopenharmony_ci * 234262306a36Sopenharmony_ci * Synchronize UART_IER access against the console. 234362306a36Sopenharmony_ci */ 234462306a36Sopenharmony_ci spin_lock_irqsave(&port->lock, flags); 234562306a36Sopenharmony_ci 234662306a36Sopenharmony_ci wait_for_xmitr(up, UART_LSR_THRE); 234762306a36Sopenharmony_ci serial_port_out_sync(port, UART_IER, UART_IER_THRI); 234862306a36Sopenharmony_ci udelay(1); /* allow THRE to set */ 234962306a36Sopenharmony_ci iir1 = serial_port_in(port, UART_IIR); 235062306a36Sopenharmony_ci serial_port_out(port, UART_IER, 0); 235162306a36Sopenharmony_ci serial_port_out_sync(port, UART_IER, UART_IER_THRI); 235262306a36Sopenharmony_ci udelay(1); /* allow a working UART time to re-assert THRE */ 235362306a36Sopenharmony_ci iir = serial_port_in(port, UART_IIR); 235462306a36Sopenharmony_ci serial_port_out(port, UART_IER, 0); 235562306a36Sopenharmony_ci 235662306a36Sopenharmony_ci spin_unlock_irqrestore(&port->lock, flags); 235762306a36Sopenharmony_ci 235862306a36Sopenharmony_ci if (port->irqflags & IRQF_SHARED) 235962306a36Sopenharmony_ci enable_irq(port->irq); 236062306a36Sopenharmony_ci 236162306a36Sopenharmony_ci /* 236262306a36Sopenharmony_ci * If the interrupt is not reasserted, or we otherwise 236362306a36Sopenharmony_ci * don't trust the iir, setup a timer to kick the UART 236462306a36Sopenharmony_ci * on a regular basis. 236562306a36Sopenharmony_ci */ 236662306a36Sopenharmony_ci if ((!(iir1 & UART_IIR_NO_INT) && (iir & UART_IIR_NO_INT)) || 236762306a36Sopenharmony_ci up->port.flags & UPF_BUG_THRE) { 236862306a36Sopenharmony_ci up->bugs |= UART_BUG_THRE; 236962306a36Sopenharmony_ci } 237062306a36Sopenharmony_ci } 237162306a36Sopenharmony_ci 237262306a36Sopenharmony_ci up->ops->setup_timer(up); 237362306a36Sopenharmony_ci 237462306a36Sopenharmony_ci /* 237562306a36Sopenharmony_ci * Now, initialize the UART 237662306a36Sopenharmony_ci */ 237762306a36Sopenharmony_ci serial_port_out(port, UART_LCR, UART_LCR_WLEN8); 237862306a36Sopenharmony_ci 237962306a36Sopenharmony_ci spin_lock_irqsave(&port->lock, flags); 238062306a36Sopenharmony_ci if (up->port.flags & UPF_FOURPORT) { 238162306a36Sopenharmony_ci if (!up->port.irq) 238262306a36Sopenharmony_ci up->port.mctrl |= TIOCM_OUT1; 238362306a36Sopenharmony_ci } else 238462306a36Sopenharmony_ci /* 238562306a36Sopenharmony_ci * Most PC uarts need OUT2 raised to enable interrupts. 238662306a36Sopenharmony_ci */ 238762306a36Sopenharmony_ci if (port->irq) 238862306a36Sopenharmony_ci up->port.mctrl |= TIOCM_OUT2; 238962306a36Sopenharmony_ci 239062306a36Sopenharmony_ci serial8250_set_mctrl(port, port->mctrl); 239162306a36Sopenharmony_ci 239262306a36Sopenharmony_ci /* 239362306a36Sopenharmony_ci * Serial over Lan (SoL) hack: 239462306a36Sopenharmony_ci * Intel 8257x Gigabit ethernet chips have a 16550 emulation, to be 239562306a36Sopenharmony_ci * used for Serial Over Lan. Those chips take a longer time than a 239662306a36Sopenharmony_ci * normal serial device to signalize that a transmission data was 239762306a36Sopenharmony_ci * queued. Due to that, the above test generally fails. One solution 239862306a36Sopenharmony_ci * would be to delay the reading of iir. However, this is not 239962306a36Sopenharmony_ci * reliable, since the timeout is variable. So, let's just don't 240062306a36Sopenharmony_ci * test if we receive TX irq. This way, we'll never enable 240162306a36Sopenharmony_ci * UART_BUG_TXEN. 240262306a36Sopenharmony_ci */ 240362306a36Sopenharmony_ci if (up->port.quirks & UPQ_NO_TXEN_TEST) 240462306a36Sopenharmony_ci goto dont_test_tx_en; 240562306a36Sopenharmony_ci 240662306a36Sopenharmony_ci /* 240762306a36Sopenharmony_ci * Do a quick test to see if we receive an interrupt when we enable 240862306a36Sopenharmony_ci * the TX irq. 240962306a36Sopenharmony_ci */ 241062306a36Sopenharmony_ci serial_port_out(port, UART_IER, UART_IER_THRI); 241162306a36Sopenharmony_ci lsr = serial_port_in(port, UART_LSR); 241262306a36Sopenharmony_ci iir = serial_port_in(port, UART_IIR); 241362306a36Sopenharmony_ci serial_port_out(port, UART_IER, 0); 241462306a36Sopenharmony_ci 241562306a36Sopenharmony_ci if (lsr & UART_LSR_TEMT && iir & UART_IIR_NO_INT) { 241662306a36Sopenharmony_ci if (!(up->bugs & UART_BUG_TXEN)) { 241762306a36Sopenharmony_ci up->bugs |= UART_BUG_TXEN; 241862306a36Sopenharmony_ci dev_dbg(port->dev, "enabling bad tx status workarounds\n"); 241962306a36Sopenharmony_ci } 242062306a36Sopenharmony_ci } else { 242162306a36Sopenharmony_ci up->bugs &= ~UART_BUG_TXEN; 242262306a36Sopenharmony_ci } 242362306a36Sopenharmony_ci 242462306a36Sopenharmony_cidont_test_tx_en: 242562306a36Sopenharmony_ci spin_unlock_irqrestore(&port->lock, flags); 242662306a36Sopenharmony_ci 242762306a36Sopenharmony_ci /* 242862306a36Sopenharmony_ci * Clear the interrupt registers again for luck, and clear the 242962306a36Sopenharmony_ci * saved flags to avoid getting false values from polling 243062306a36Sopenharmony_ci * routines or the previous session. 243162306a36Sopenharmony_ci */ 243262306a36Sopenharmony_ci serial_port_in(port, UART_LSR); 243362306a36Sopenharmony_ci serial_port_in(port, UART_RX); 243462306a36Sopenharmony_ci serial_port_in(port, UART_IIR); 243562306a36Sopenharmony_ci serial_port_in(port, UART_MSR); 243662306a36Sopenharmony_ci up->lsr_saved_flags = 0; 243762306a36Sopenharmony_ci up->msr_saved_flags = 0; 243862306a36Sopenharmony_ci 243962306a36Sopenharmony_ci /* 244062306a36Sopenharmony_ci * Request DMA channels for both RX and TX. 244162306a36Sopenharmony_ci */ 244262306a36Sopenharmony_ci if (up->dma) { 244362306a36Sopenharmony_ci const char *msg = NULL; 244462306a36Sopenharmony_ci 244562306a36Sopenharmony_ci if (uart_console(port)) 244662306a36Sopenharmony_ci msg = "forbid DMA for kernel console"; 244762306a36Sopenharmony_ci else if (serial8250_request_dma(up)) 244862306a36Sopenharmony_ci msg = "failed to request DMA"; 244962306a36Sopenharmony_ci if (msg) { 245062306a36Sopenharmony_ci dev_warn_ratelimited(port->dev, "%s\n", msg); 245162306a36Sopenharmony_ci up->dma = NULL; 245262306a36Sopenharmony_ci } 245362306a36Sopenharmony_ci } 245462306a36Sopenharmony_ci 245562306a36Sopenharmony_ci /* 245662306a36Sopenharmony_ci * Set the IER shadow for rx interrupts but defer actual interrupt 245762306a36Sopenharmony_ci * enable until after the FIFOs are enabled; otherwise, an already- 245862306a36Sopenharmony_ci * active sender can swamp the interrupt handler with "too much work". 245962306a36Sopenharmony_ci */ 246062306a36Sopenharmony_ci up->ier = UART_IER_RLSI | UART_IER_RDI; 246162306a36Sopenharmony_ci 246262306a36Sopenharmony_ci if (port->flags & UPF_FOURPORT) { 246362306a36Sopenharmony_ci unsigned int icp; 246462306a36Sopenharmony_ci /* 246562306a36Sopenharmony_ci * Enable interrupts on the AST Fourport board 246662306a36Sopenharmony_ci */ 246762306a36Sopenharmony_ci icp = (port->iobase & 0xfe0) | 0x01f; 246862306a36Sopenharmony_ci outb_p(0x80, icp); 246962306a36Sopenharmony_ci inb_p(icp); 247062306a36Sopenharmony_ci } 247162306a36Sopenharmony_ci retval = 0; 247262306a36Sopenharmony_ciout: 247362306a36Sopenharmony_ci serial8250_rpm_put(up); 247462306a36Sopenharmony_ci return retval; 247562306a36Sopenharmony_ci} 247662306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(serial8250_do_startup); 247762306a36Sopenharmony_ci 247862306a36Sopenharmony_cistatic int serial8250_startup(struct uart_port *port) 247962306a36Sopenharmony_ci{ 248062306a36Sopenharmony_ci if (port->startup) 248162306a36Sopenharmony_ci return port->startup(port); 248262306a36Sopenharmony_ci return serial8250_do_startup(port); 248362306a36Sopenharmony_ci} 248462306a36Sopenharmony_ci 248562306a36Sopenharmony_civoid serial8250_do_shutdown(struct uart_port *port) 248662306a36Sopenharmony_ci{ 248762306a36Sopenharmony_ci struct uart_8250_port *up = up_to_u8250p(port); 248862306a36Sopenharmony_ci unsigned long flags; 248962306a36Sopenharmony_ci 249062306a36Sopenharmony_ci serial8250_rpm_get(up); 249162306a36Sopenharmony_ci /* 249262306a36Sopenharmony_ci * Disable interrupts from this port 249362306a36Sopenharmony_ci * 249462306a36Sopenharmony_ci * Synchronize UART_IER access against the console. 249562306a36Sopenharmony_ci */ 249662306a36Sopenharmony_ci spin_lock_irqsave(&port->lock, flags); 249762306a36Sopenharmony_ci up->ier = 0; 249862306a36Sopenharmony_ci serial_port_out(port, UART_IER, 0); 249962306a36Sopenharmony_ci spin_unlock_irqrestore(&port->lock, flags); 250062306a36Sopenharmony_ci 250162306a36Sopenharmony_ci synchronize_irq(port->irq); 250262306a36Sopenharmony_ci 250362306a36Sopenharmony_ci if (up->dma) 250462306a36Sopenharmony_ci serial8250_release_dma(up); 250562306a36Sopenharmony_ci 250662306a36Sopenharmony_ci spin_lock_irqsave(&port->lock, flags); 250762306a36Sopenharmony_ci if (port->flags & UPF_FOURPORT) { 250862306a36Sopenharmony_ci /* reset interrupts on the AST Fourport board */ 250962306a36Sopenharmony_ci inb((port->iobase & 0xfe0) | 0x1f); 251062306a36Sopenharmony_ci port->mctrl |= TIOCM_OUT1; 251162306a36Sopenharmony_ci } else 251262306a36Sopenharmony_ci port->mctrl &= ~TIOCM_OUT2; 251362306a36Sopenharmony_ci 251462306a36Sopenharmony_ci serial8250_set_mctrl(port, port->mctrl); 251562306a36Sopenharmony_ci spin_unlock_irqrestore(&port->lock, flags); 251662306a36Sopenharmony_ci 251762306a36Sopenharmony_ci /* 251862306a36Sopenharmony_ci * Disable break condition and FIFOs 251962306a36Sopenharmony_ci */ 252062306a36Sopenharmony_ci serial_port_out(port, UART_LCR, 252162306a36Sopenharmony_ci serial_port_in(port, UART_LCR) & ~UART_LCR_SBC); 252262306a36Sopenharmony_ci serial8250_clear_fifos(up); 252362306a36Sopenharmony_ci 252462306a36Sopenharmony_ci#ifdef CONFIG_SERIAL_8250_RSA 252562306a36Sopenharmony_ci /* 252662306a36Sopenharmony_ci * Reset the RSA board back to 115kbps compat mode. 252762306a36Sopenharmony_ci */ 252862306a36Sopenharmony_ci disable_rsa(up); 252962306a36Sopenharmony_ci#endif 253062306a36Sopenharmony_ci 253162306a36Sopenharmony_ci /* 253262306a36Sopenharmony_ci * Read data port to reset things, and then unlink from 253362306a36Sopenharmony_ci * the IRQ chain. 253462306a36Sopenharmony_ci */ 253562306a36Sopenharmony_ci serial_port_in(port, UART_RX); 253662306a36Sopenharmony_ci serial8250_rpm_put(up); 253762306a36Sopenharmony_ci 253862306a36Sopenharmony_ci up->ops->release_irq(up); 253962306a36Sopenharmony_ci} 254062306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(serial8250_do_shutdown); 254162306a36Sopenharmony_ci 254262306a36Sopenharmony_cistatic void serial8250_shutdown(struct uart_port *port) 254362306a36Sopenharmony_ci{ 254462306a36Sopenharmony_ci if (port->shutdown) 254562306a36Sopenharmony_ci port->shutdown(port); 254662306a36Sopenharmony_ci else 254762306a36Sopenharmony_ci serial8250_do_shutdown(port); 254862306a36Sopenharmony_ci} 254962306a36Sopenharmony_ci 255062306a36Sopenharmony_ci/* Nuvoton NPCM UARTs have a custom divisor calculation */ 255162306a36Sopenharmony_cistatic unsigned int npcm_get_divisor(struct uart_8250_port *up, 255262306a36Sopenharmony_ci unsigned int baud) 255362306a36Sopenharmony_ci{ 255462306a36Sopenharmony_ci struct uart_port *port = &up->port; 255562306a36Sopenharmony_ci 255662306a36Sopenharmony_ci return DIV_ROUND_CLOSEST(port->uartclk, 16 * baud + 2) - 2; 255762306a36Sopenharmony_ci} 255862306a36Sopenharmony_ci 255962306a36Sopenharmony_cistatic unsigned int serial8250_do_get_divisor(struct uart_port *port, 256062306a36Sopenharmony_ci unsigned int baud, 256162306a36Sopenharmony_ci unsigned int *frac) 256262306a36Sopenharmony_ci{ 256362306a36Sopenharmony_ci upf_t magic_multiplier = port->flags & UPF_MAGIC_MULTIPLIER; 256462306a36Sopenharmony_ci struct uart_8250_port *up = up_to_u8250p(port); 256562306a36Sopenharmony_ci unsigned int quot; 256662306a36Sopenharmony_ci 256762306a36Sopenharmony_ci /* 256862306a36Sopenharmony_ci * Handle magic divisors for baud rates above baud_base on SMSC 256962306a36Sopenharmony_ci * Super I/O chips. We clamp custom rates from clk/6 and clk/12 257062306a36Sopenharmony_ci * up to clk/4 (0x8001) and clk/8 (0x8002) respectively. These 257162306a36Sopenharmony_ci * magic divisors actually reprogram the baud rate generator's 257262306a36Sopenharmony_ci * reference clock derived from chips's 14.318MHz clock input. 257362306a36Sopenharmony_ci * 257462306a36Sopenharmony_ci * Documentation claims that with these magic divisors the base 257562306a36Sopenharmony_ci * frequencies of 7.3728MHz and 3.6864MHz are used respectively 257662306a36Sopenharmony_ci * for the extra baud rates of 460800bps and 230400bps rather 257762306a36Sopenharmony_ci * than the usual base frequency of 1.8462MHz. However empirical 257862306a36Sopenharmony_ci * evidence contradicts that. 257962306a36Sopenharmony_ci * 258062306a36Sopenharmony_ci * Instead bit 7 of the DLM register (bit 15 of the divisor) is 258162306a36Sopenharmony_ci * effectively used as a clock prescaler selection bit for the 258262306a36Sopenharmony_ci * base frequency of 7.3728MHz, always used. If set to 0, then 258362306a36Sopenharmony_ci * the base frequency is divided by 4 for use by the Baud Rate 258462306a36Sopenharmony_ci * Generator, for the usual arrangement where the value of 1 of 258562306a36Sopenharmony_ci * the divisor produces the baud rate of 115200bps. Conversely, 258662306a36Sopenharmony_ci * if set to 1 and high-speed operation has been enabled with the 258762306a36Sopenharmony_ci * Serial Port Mode Register in the Device Configuration Space, 258862306a36Sopenharmony_ci * then the base frequency is supplied directly to the Baud Rate 258962306a36Sopenharmony_ci * Generator, so for the divisor values of 0x8001, 0x8002, 0x8003, 259062306a36Sopenharmony_ci * 0x8004, etc. the respective baud rates produced are 460800bps, 259162306a36Sopenharmony_ci * 230400bps, 153600bps, 115200bps, etc. 259262306a36Sopenharmony_ci * 259362306a36Sopenharmony_ci * In all cases only low 15 bits of the divisor are used to divide 259462306a36Sopenharmony_ci * the baud base and therefore 32767 is the maximum divisor value 259562306a36Sopenharmony_ci * possible, even though documentation says that the programmable 259662306a36Sopenharmony_ci * Baud Rate Generator is capable of dividing the internal PLL 259762306a36Sopenharmony_ci * clock by any divisor from 1 to 65535. 259862306a36Sopenharmony_ci */ 259962306a36Sopenharmony_ci if (magic_multiplier && baud >= port->uartclk / 6) 260062306a36Sopenharmony_ci quot = 0x8001; 260162306a36Sopenharmony_ci else if (magic_multiplier && baud >= port->uartclk / 12) 260262306a36Sopenharmony_ci quot = 0x8002; 260362306a36Sopenharmony_ci else if (up->port.type == PORT_NPCM) 260462306a36Sopenharmony_ci quot = npcm_get_divisor(up, baud); 260562306a36Sopenharmony_ci else 260662306a36Sopenharmony_ci quot = uart_get_divisor(port, baud); 260762306a36Sopenharmony_ci 260862306a36Sopenharmony_ci /* 260962306a36Sopenharmony_ci * Oxford Semi 952 rev B workaround 261062306a36Sopenharmony_ci */ 261162306a36Sopenharmony_ci if (up->bugs & UART_BUG_QUOT && (quot & 0xff) == 0) 261262306a36Sopenharmony_ci quot++; 261362306a36Sopenharmony_ci 261462306a36Sopenharmony_ci return quot; 261562306a36Sopenharmony_ci} 261662306a36Sopenharmony_ci 261762306a36Sopenharmony_cistatic unsigned int serial8250_get_divisor(struct uart_port *port, 261862306a36Sopenharmony_ci unsigned int baud, 261962306a36Sopenharmony_ci unsigned int *frac) 262062306a36Sopenharmony_ci{ 262162306a36Sopenharmony_ci if (port->get_divisor) 262262306a36Sopenharmony_ci return port->get_divisor(port, baud, frac); 262362306a36Sopenharmony_ci 262462306a36Sopenharmony_ci return serial8250_do_get_divisor(port, baud, frac); 262562306a36Sopenharmony_ci} 262662306a36Sopenharmony_ci 262762306a36Sopenharmony_cistatic unsigned char serial8250_compute_lcr(struct uart_8250_port *up, 262862306a36Sopenharmony_ci tcflag_t c_cflag) 262962306a36Sopenharmony_ci{ 263062306a36Sopenharmony_ci unsigned char cval; 263162306a36Sopenharmony_ci 263262306a36Sopenharmony_ci cval = UART_LCR_WLEN(tty_get_char_size(c_cflag)); 263362306a36Sopenharmony_ci 263462306a36Sopenharmony_ci if (c_cflag & CSTOPB) 263562306a36Sopenharmony_ci cval |= UART_LCR_STOP; 263662306a36Sopenharmony_ci if (c_cflag & PARENB) 263762306a36Sopenharmony_ci cval |= UART_LCR_PARITY; 263862306a36Sopenharmony_ci if (!(c_cflag & PARODD)) 263962306a36Sopenharmony_ci cval |= UART_LCR_EPAR; 264062306a36Sopenharmony_ci if (c_cflag & CMSPAR) 264162306a36Sopenharmony_ci cval |= UART_LCR_SPAR; 264262306a36Sopenharmony_ci 264362306a36Sopenharmony_ci return cval; 264462306a36Sopenharmony_ci} 264562306a36Sopenharmony_ci 264662306a36Sopenharmony_civoid serial8250_do_set_divisor(struct uart_port *port, unsigned int baud, 264762306a36Sopenharmony_ci unsigned int quot, unsigned int quot_frac) 264862306a36Sopenharmony_ci{ 264962306a36Sopenharmony_ci struct uart_8250_port *up = up_to_u8250p(port); 265062306a36Sopenharmony_ci 265162306a36Sopenharmony_ci /* Workaround to enable 115200 baud on OMAP1510 internal ports */ 265262306a36Sopenharmony_ci if (is_omap1510_8250(up)) { 265362306a36Sopenharmony_ci if (baud == 115200) { 265462306a36Sopenharmony_ci quot = 1; 265562306a36Sopenharmony_ci serial_port_out(port, UART_OMAP_OSC_12M_SEL, 1); 265662306a36Sopenharmony_ci } else 265762306a36Sopenharmony_ci serial_port_out(port, UART_OMAP_OSC_12M_SEL, 0); 265862306a36Sopenharmony_ci } 265962306a36Sopenharmony_ci 266062306a36Sopenharmony_ci /* 266162306a36Sopenharmony_ci * For NatSemi, switch to bank 2 not bank 1, to avoid resetting EXCR2, 266262306a36Sopenharmony_ci * otherwise just set DLAB 266362306a36Sopenharmony_ci */ 266462306a36Sopenharmony_ci if (up->capabilities & UART_NATSEMI) 266562306a36Sopenharmony_ci serial_port_out(port, UART_LCR, 0xe0); 266662306a36Sopenharmony_ci else 266762306a36Sopenharmony_ci serial_port_out(port, UART_LCR, up->lcr | UART_LCR_DLAB); 266862306a36Sopenharmony_ci 266962306a36Sopenharmony_ci serial_dl_write(up, quot); 267062306a36Sopenharmony_ci} 267162306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(serial8250_do_set_divisor); 267262306a36Sopenharmony_ci 267362306a36Sopenharmony_cistatic void serial8250_set_divisor(struct uart_port *port, unsigned int baud, 267462306a36Sopenharmony_ci unsigned int quot, unsigned int quot_frac) 267562306a36Sopenharmony_ci{ 267662306a36Sopenharmony_ci if (port->set_divisor) 267762306a36Sopenharmony_ci port->set_divisor(port, baud, quot, quot_frac); 267862306a36Sopenharmony_ci else 267962306a36Sopenharmony_ci serial8250_do_set_divisor(port, baud, quot, quot_frac); 268062306a36Sopenharmony_ci} 268162306a36Sopenharmony_ci 268262306a36Sopenharmony_cistatic unsigned int serial8250_get_baud_rate(struct uart_port *port, 268362306a36Sopenharmony_ci struct ktermios *termios, 268462306a36Sopenharmony_ci const struct ktermios *old) 268562306a36Sopenharmony_ci{ 268662306a36Sopenharmony_ci unsigned int tolerance = port->uartclk / 100; 268762306a36Sopenharmony_ci unsigned int min; 268862306a36Sopenharmony_ci unsigned int max; 268962306a36Sopenharmony_ci 269062306a36Sopenharmony_ci /* 269162306a36Sopenharmony_ci * Handle magic divisors for baud rates above baud_base on SMSC 269262306a36Sopenharmony_ci * Super I/O chips. Enable custom rates of clk/4 and clk/8, but 269362306a36Sopenharmony_ci * disable divisor values beyond 32767, which are unavailable. 269462306a36Sopenharmony_ci */ 269562306a36Sopenharmony_ci if (port->flags & UPF_MAGIC_MULTIPLIER) { 269662306a36Sopenharmony_ci min = port->uartclk / 16 / UART_DIV_MAX >> 1; 269762306a36Sopenharmony_ci max = (port->uartclk + tolerance) / 4; 269862306a36Sopenharmony_ci } else { 269962306a36Sopenharmony_ci min = port->uartclk / 16 / UART_DIV_MAX; 270062306a36Sopenharmony_ci max = (port->uartclk + tolerance) / 16; 270162306a36Sopenharmony_ci } 270262306a36Sopenharmony_ci 270362306a36Sopenharmony_ci /* 270462306a36Sopenharmony_ci * Ask the core to calculate the divisor for us. 270562306a36Sopenharmony_ci * Allow 1% tolerance at the upper limit so uart clks marginally 270662306a36Sopenharmony_ci * slower than nominal still match standard baud rates without 270762306a36Sopenharmony_ci * causing transmission errors. 270862306a36Sopenharmony_ci */ 270962306a36Sopenharmony_ci return uart_get_baud_rate(port, termios, old, min, max); 271062306a36Sopenharmony_ci} 271162306a36Sopenharmony_ci 271262306a36Sopenharmony_ci/* 271362306a36Sopenharmony_ci * Note in order to avoid the tty port mutex deadlock don't use the next method 271462306a36Sopenharmony_ci * within the uart port callbacks. Primarily it's supposed to be utilized to 271562306a36Sopenharmony_ci * handle a sudden reference clock rate change. 271662306a36Sopenharmony_ci */ 271762306a36Sopenharmony_civoid serial8250_update_uartclk(struct uart_port *port, unsigned int uartclk) 271862306a36Sopenharmony_ci{ 271962306a36Sopenharmony_ci struct uart_8250_port *up = up_to_u8250p(port); 272062306a36Sopenharmony_ci struct tty_port *tport = &port->state->port; 272162306a36Sopenharmony_ci unsigned int baud, quot, frac = 0; 272262306a36Sopenharmony_ci struct ktermios *termios; 272362306a36Sopenharmony_ci struct tty_struct *tty; 272462306a36Sopenharmony_ci unsigned long flags; 272562306a36Sopenharmony_ci 272662306a36Sopenharmony_ci tty = tty_port_tty_get(tport); 272762306a36Sopenharmony_ci if (!tty) { 272862306a36Sopenharmony_ci mutex_lock(&tport->mutex); 272962306a36Sopenharmony_ci port->uartclk = uartclk; 273062306a36Sopenharmony_ci mutex_unlock(&tport->mutex); 273162306a36Sopenharmony_ci return; 273262306a36Sopenharmony_ci } 273362306a36Sopenharmony_ci 273462306a36Sopenharmony_ci down_write(&tty->termios_rwsem); 273562306a36Sopenharmony_ci mutex_lock(&tport->mutex); 273662306a36Sopenharmony_ci 273762306a36Sopenharmony_ci if (port->uartclk == uartclk) 273862306a36Sopenharmony_ci goto out_unlock; 273962306a36Sopenharmony_ci 274062306a36Sopenharmony_ci port->uartclk = uartclk; 274162306a36Sopenharmony_ci 274262306a36Sopenharmony_ci if (!tty_port_initialized(tport)) 274362306a36Sopenharmony_ci goto out_unlock; 274462306a36Sopenharmony_ci 274562306a36Sopenharmony_ci termios = &tty->termios; 274662306a36Sopenharmony_ci 274762306a36Sopenharmony_ci baud = serial8250_get_baud_rate(port, termios, NULL); 274862306a36Sopenharmony_ci quot = serial8250_get_divisor(port, baud, &frac); 274962306a36Sopenharmony_ci 275062306a36Sopenharmony_ci serial8250_rpm_get(up); 275162306a36Sopenharmony_ci spin_lock_irqsave(&port->lock, flags); 275262306a36Sopenharmony_ci 275362306a36Sopenharmony_ci uart_update_timeout(port, termios->c_cflag, baud); 275462306a36Sopenharmony_ci 275562306a36Sopenharmony_ci serial8250_set_divisor(port, baud, quot, frac); 275662306a36Sopenharmony_ci serial_port_out(port, UART_LCR, up->lcr); 275762306a36Sopenharmony_ci 275862306a36Sopenharmony_ci spin_unlock_irqrestore(&port->lock, flags); 275962306a36Sopenharmony_ci serial8250_rpm_put(up); 276062306a36Sopenharmony_ci 276162306a36Sopenharmony_ciout_unlock: 276262306a36Sopenharmony_ci mutex_unlock(&tport->mutex); 276362306a36Sopenharmony_ci up_write(&tty->termios_rwsem); 276462306a36Sopenharmony_ci tty_kref_put(tty); 276562306a36Sopenharmony_ci} 276662306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(serial8250_update_uartclk); 276762306a36Sopenharmony_ci 276862306a36Sopenharmony_civoid 276962306a36Sopenharmony_ciserial8250_do_set_termios(struct uart_port *port, struct ktermios *termios, 277062306a36Sopenharmony_ci const struct ktermios *old) 277162306a36Sopenharmony_ci{ 277262306a36Sopenharmony_ci struct uart_8250_port *up = up_to_u8250p(port); 277362306a36Sopenharmony_ci unsigned char cval; 277462306a36Sopenharmony_ci unsigned long flags; 277562306a36Sopenharmony_ci unsigned int baud, quot, frac = 0; 277662306a36Sopenharmony_ci 277762306a36Sopenharmony_ci if (up->capabilities & UART_CAP_MINI) { 277862306a36Sopenharmony_ci termios->c_cflag &= ~(CSTOPB | PARENB | PARODD | CMSPAR); 277962306a36Sopenharmony_ci if ((termios->c_cflag & CSIZE) == CS5 || 278062306a36Sopenharmony_ci (termios->c_cflag & CSIZE) == CS6) 278162306a36Sopenharmony_ci termios->c_cflag = (termios->c_cflag & ~CSIZE) | CS7; 278262306a36Sopenharmony_ci } 278362306a36Sopenharmony_ci cval = serial8250_compute_lcr(up, termios->c_cflag); 278462306a36Sopenharmony_ci 278562306a36Sopenharmony_ci baud = serial8250_get_baud_rate(port, termios, old); 278662306a36Sopenharmony_ci quot = serial8250_get_divisor(port, baud, &frac); 278762306a36Sopenharmony_ci 278862306a36Sopenharmony_ci /* 278962306a36Sopenharmony_ci * Ok, we're now changing the port state. Do it with 279062306a36Sopenharmony_ci * interrupts disabled. 279162306a36Sopenharmony_ci * 279262306a36Sopenharmony_ci * Synchronize UART_IER access against the console. 279362306a36Sopenharmony_ci */ 279462306a36Sopenharmony_ci serial8250_rpm_get(up); 279562306a36Sopenharmony_ci spin_lock_irqsave(&port->lock, flags); 279662306a36Sopenharmony_ci 279762306a36Sopenharmony_ci up->lcr = cval; /* Save computed LCR */ 279862306a36Sopenharmony_ci 279962306a36Sopenharmony_ci if (up->capabilities & UART_CAP_FIFO && port->fifosize > 1) { 280062306a36Sopenharmony_ci if (baud < 2400 && !up->dma) { 280162306a36Sopenharmony_ci up->fcr &= ~UART_FCR_TRIGGER_MASK; 280262306a36Sopenharmony_ci up->fcr |= UART_FCR_TRIGGER_1; 280362306a36Sopenharmony_ci } 280462306a36Sopenharmony_ci } 280562306a36Sopenharmony_ci 280662306a36Sopenharmony_ci /* 280762306a36Sopenharmony_ci * MCR-based auto flow control. When AFE is enabled, RTS will be 280862306a36Sopenharmony_ci * deasserted when the receive FIFO contains more characters than 280962306a36Sopenharmony_ci * the trigger, or the MCR RTS bit is cleared. 281062306a36Sopenharmony_ci */ 281162306a36Sopenharmony_ci if (up->capabilities & UART_CAP_AFE) { 281262306a36Sopenharmony_ci up->mcr &= ~UART_MCR_AFE; 281362306a36Sopenharmony_ci if (termios->c_cflag & CRTSCTS) 281462306a36Sopenharmony_ci up->mcr |= UART_MCR_AFE; 281562306a36Sopenharmony_ci } 281662306a36Sopenharmony_ci 281762306a36Sopenharmony_ci /* 281862306a36Sopenharmony_ci * Update the per-port timeout. 281962306a36Sopenharmony_ci */ 282062306a36Sopenharmony_ci uart_update_timeout(port, termios->c_cflag, baud); 282162306a36Sopenharmony_ci 282262306a36Sopenharmony_ci port->read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR; 282362306a36Sopenharmony_ci if (termios->c_iflag & INPCK) 282462306a36Sopenharmony_ci port->read_status_mask |= UART_LSR_FE | UART_LSR_PE; 282562306a36Sopenharmony_ci if (termios->c_iflag & (IGNBRK | BRKINT | PARMRK)) 282662306a36Sopenharmony_ci port->read_status_mask |= UART_LSR_BI; 282762306a36Sopenharmony_ci 282862306a36Sopenharmony_ci /* 282962306a36Sopenharmony_ci * Characters to ignore 283062306a36Sopenharmony_ci */ 283162306a36Sopenharmony_ci port->ignore_status_mask = 0; 283262306a36Sopenharmony_ci if (termios->c_iflag & IGNPAR) 283362306a36Sopenharmony_ci port->ignore_status_mask |= UART_LSR_PE | UART_LSR_FE; 283462306a36Sopenharmony_ci if (termios->c_iflag & IGNBRK) { 283562306a36Sopenharmony_ci port->ignore_status_mask |= UART_LSR_BI; 283662306a36Sopenharmony_ci /* 283762306a36Sopenharmony_ci * If we're ignoring parity and break indicators, 283862306a36Sopenharmony_ci * ignore overruns too (for real raw support). 283962306a36Sopenharmony_ci */ 284062306a36Sopenharmony_ci if (termios->c_iflag & IGNPAR) 284162306a36Sopenharmony_ci port->ignore_status_mask |= UART_LSR_OE; 284262306a36Sopenharmony_ci } 284362306a36Sopenharmony_ci 284462306a36Sopenharmony_ci /* 284562306a36Sopenharmony_ci * ignore all characters if CREAD is not set 284662306a36Sopenharmony_ci */ 284762306a36Sopenharmony_ci if ((termios->c_cflag & CREAD) == 0) 284862306a36Sopenharmony_ci port->ignore_status_mask |= UART_LSR_DR; 284962306a36Sopenharmony_ci 285062306a36Sopenharmony_ci /* 285162306a36Sopenharmony_ci * CTS flow control flag and modem status interrupts 285262306a36Sopenharmony_ci */ 285362306a36Sopenharmony_ci up->ier &= ~UART_IER_MSI; 285462306a36Sopenharmony_ci if (!(up->bugs & UART_BUG_NOMSR) && 285562306a36Sopenharmony_ci UART_ENABLE_MS(&up->port, termios->c_cflag)) 285662306a36Sopenharmony_ci up->ier |= UART_IER_MSI; 285762306a36Sopenharmony_ci if (up->capabilities & UART_CAP_UUE) 285862306a36Sopenharmony_ci up->ier |= UART_IER_UUE; 285962306a36Sopenharmony_ci if (up->capabilities & UART_CAP_RTOIE) 286062306a36Sopenharmony_ci up->ier |= UART_IER_RTOIE; 286162306a36Sopenharmony_ci 286262306a36Sopenharmony_ci serial_port_out(port, UART_IER, up->ier); 286362306a36Sopenharmony_ci 286462306a36Sopenharmony_ci if (up->capabilities & UART_CAP_EFR) { 286562306a36Sopenharmony_ci unsigned char efr = 0; 286662306a36Sopenharmony_ci /* 286762306a36Sopenharmony_ci * TI16C752/Startech hardware flow control. FIXME: 286862306a36Sopenharmony_ci * - TI16C752 requires control thresholds to be set. 286962306a36Sopenharmony_ci * - UART_MCR_RTS is ineffective if auto-RTS mode is enabled. 287062306a36Sopenharmony_ci */ 287162306a36Sopenharmony_ci if (termios->c_cflag & CRTSCTS) 287262306a36Sopenharmony_ci efr |= UART_EFR_CTS; 287362306a36Sopenharmony_ci 287462306a36Sopenharmony_ci serial_port_out(port, UART_LCR, UART_LCR_CONF_MODE_B); 287562306a36Sopenharmony_ci if (port->flags & UPF_EXAR_EFR) 287662306a36Sopenharmony_ci serial_port_out(port, UART_XR_EFR, efr); 287762306a36Sopenharmony_ci else 287862306a36Sopenharmony_ci serial_port_out(port, UART_EFR, efr); 287962306a36Sopenharmony_ci } 288062306a36Sopenharmony_ci 288162306a36Sopenharmony_ci serial8250_set_divisor(port, baud, quot, frac); 288262306a36Sopenharmony_ci 288362306a36Sopenharmony_ci /* 288462306a36Sopenharmony_ci * LCR DLAB must be set to enable 64-byte FIFO mode. If the FCR 288562306a36Sopenharmony_ci * is written without DLAB set, this mode will be disabled. 288662306a36Sopenharmony_ci */ 288762306a36Sopenharmony_ci if (port->type == PORT_16750) 288862306a36Sopenharmony_ci serial_port_out(port, UART_FCR, up->fcr); 288962306a36Sopenharmony_ci 289062306a36Sopenharmony_ci serial_port_out(port, UART_LCR, up->lcr); /* reset DLAB */ 289162306a36Sopenharmony_ci if (port->type != PORT_16750) { 289262306a36Sopenharmony_ci /* emulated UARTs (Lucent Venus 167x) need two steps */ 289362306a36Sopenharmony_ci if (up->fcr & UART_FCR_ENABLE_FIFO) 289462306a36Sopenharmony_ci serial_port_out(port, UART_FCR, UART_FCR_ENABLE_FIFO); 289562306a36Sopenharmony_ci serial_port_out(port, UART_FCR, up->fcr); /* set fcr */ 289662306a36Sopenharmony_ci } 289762306a36Sopenharmony_ci serial8250_set_mctrl(port, port->mctrl); 289862306a36Sopenharmony_ci spin_unlock_irqrestore(&port->lock, flags); 289962306a36Sopenharmony_ci serial8250_rpm_put(up); 290062306a36Sopenharmony_ci 290162306a36Sopenharmony_ci /* Don't rewrite B0 */ 290262306a36Sopenharmony_ci if (tty_termios_baud_rate(termios)) 290362306a36Sopenharmony_ci tty_termios_encode_baud_rate(termios, baud, baud); 290462306a36Sopenharmony_ci} 290562306a36Sopenharmony_ciEXPORT_SYMBOL(serial8250_do_set_termios); 290662306a36Sopenharmony_ci 290762306a36Sopenharmony_cistatic void 290862306a36Sopenharmony_ciserial8250_set_termios(struct uart_port *port, struct ktermios *termios, 290962306a36Sopenharmony_ci const struct ktermios *old) 291062306a36Sopenharmony_ci{ 291162306a36Sopenharmony_ci if (port->set_termios) 291262306a36Sopenharmony_ci port->set_termios(port, termios, old); 291362306a36Sopenharmony_ci else 291462306a36Sopenharmony_ci serial8250_do_set_termios(port, termios, old); 291562306a36Sopenharmony_ci} 291662306a36Sopenharmony_ci 291762306a36Sopenharmony_civoid serial8250_do_set_ldisc(struct uart_port *port, struct ktermios *termios) 291862306a36Sopenharmony_ci{ 291962306a36Sopenharmony_ci if (termios->c_line == N_PPS) { 292062306a36Sopenharmony_ci port->flags |= UPF_HARDPPS_CD; 292162306a36Sopenharmony_ci spin_lock_irq(&port->lock); 292262306a36Sopenharmony_ci serial8250_enable_ms(port); 292362306a36Sopenharmony_ci spin_unlock_irq(&port->lock); 292462306a36Sopenharmony_ci } else { 292562306a36Sopenharmony_ci port->flags &= ~UPF_HARDPPS_CD; 292662306a36Sopenharmony_ci if (!UART_ENABLE_MS(port, termios->c_cflag)) { 292762306a36Sopenharmony_ci spin_lock_irq(&port->lock); 292862306a36Sopenharmony_ci serial8250_disable_ms(port); 292962306a36Sopenharmony_ci spin_unlock_irq(&port->lock); 293062306a36Sopenharmony_ci } 293162306a36Sopenharmony_ci } 293262306a36Sopenharmony_ci} 293362306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(serial8250_do_set_ldisc); 293462306a36Sopenharmony_ci 293562306a36Sopenharmony_cistatic void 293662306a36Sopenharmony_ciserial8250_set_ldisc(struct uart_port *port, struct ktermios *termios) 293762306a36Sopenharmony_ci{ 293862306a36Sopenharmony_ci if (port->set_ldisc) 293962306a36Sopenharmony_ci port->set_ldisc(port, termios); 294062306a36Sopenharmony_ci else 294162306a36Sopenharmony_ci serial8250_do_set_ldisc(port, termios); 294262306a36Sopenharmony_ci} 294362306a36Sopenharmony_ci 294462306a36Sopenharmony_civoid serial8250_do_pm(struct uart_port *port, unsigned int state, 294562306a36Sopenharmony_ci unsigned int oldstate) 294662306a36Sopenharmony_ci{ 294762306a36Sopenharmony_ci struct uart_8250_port *p = up_to_u8250p(port); 294862306a36Sopenharmony_ci 294962306a36Sopenharmony_ci serial8250_set_sleep(p, state != 0); 295062306a36Sopenharmony_ci} 295162306a36Sopenharmony_ciEXPORT_SYMBOL(serial8250_do_pm); 295262306a36Sopenharmony_ci 295362306a36Sopenharmony_cistatic void 295462306a36Sopenharmony_ciserial8250_pm(struct uart_port *port, unsigned int state, 295562306a36Sopenharmony_ci unsigned int oldstate) 295662306a36Sopenharmony_ci{ 295762306a36Sopenharmony_ci if (port->pm) 295862306a36Sopenharmony_ci port->pm(port, state, oldstate); 295962306a36Sopenharmony_ci else 296062306a36Sopenharmony_ci serial8250_do_pm(port, state, oldstate); 296162306a36Sopenharmony_ci} 296262306a36Sopenharmony_ci 296362306a36Sopenharmony_cistatic unsigned int serial8250_port_size(struct uart_8250_port *pt) 296462306a36Sopenharmony_ci{ 296562306a36Sopenharmony_ci if (pt->port.mapsize) 296662306a36Sopenharmony_ci return pt->port.mapsize; 296762306a36Sopenharmony_ci if (is_omap1_8250(pt)) 296862306a36Sopenharmony_ci return 0x16 << pt->port.regshift; 296962306a36Sopenharmony_ci 297062306a36Sopenharmony_ci return 8 << pt->port.regshift; 297162306a36Sopenharmony_ci} 297262306a36Sopenharmony_ci 297362306a36Sopenharmony_ci/* 297462306a36Sopenharmony_ci * Resource handling. 297562306a36Sopenharmony_ci */ 297662306a36Sopenharmony_cistatic int serial8250_request_std_resource(struct uart_8250_port *up) 297762306a36Sopenharmony_ci{ 297862306a36Sopenharmony_ci unsigned int size = serial8250_port_size(up); 297962306a36Sopenharmony_ci struct uart_port *port = &up->port; 298062306a36Sopenharmony_ci int ret = 0; 298162306a36Sopenharmony_ci 298262306a36Sopenharmony_ci switch (port->iotype) { 298362306a36Sopenharmony_ci case UPIO_AU: 298462306a36Sopenharmony_ci case UPIO_TSI: 298562306a36Sopenharmony_ci case UPIO_MEM32: 298662306a36Sopenharmony_ci case UPIO_MEM32BE: 298762306a36Sopenharmony_ci case UPIO_MEM16: 298862306a36Sopenharmony_ci case UPIO_MEM: 298962306a36Sopenharmony_ci if (!port->mapbase) { 299062306a36Sopenharmony_ci ret = -EINVAL; 299162306a36Sopenharmony_ci break; 299262306a36Sopenharmony_ci } 299362306a36Sopenharmony_ci 299462306a36Sopenharmony_ci if (!request_mem_region(port->mapbase, size, "serial")) { 299562306a36Sopenharmony_ci ret = -EBUSY; 299662306a36Sopenharmony_ci break; 299762306a36Sopenharmony_ci } 299862306a36Sopenharmony_ci 299962306a36Sopenharmony_ci if (port->flags & UPF_IOREMAP) { 300062306a36Sopenharmony_ci port->membase = ioremap(port->mapbase, size); 300162306a36Sopenharmony_ci if (!port->membase) { 300262306a36Sopenharmony_ci release_mem_region(port->mapbase, size); 300362306a36Sopenharmony_ci ret = -ENOMEM; 300462306a36Sopenharmony_ci } 300562306a36Sopenharmony_ci } 300662306a36Sopenharmony_ci break; 300762306a36Sopenharmony_ci 300862306a36Sopenharmony_ci case UPIO_HUB6: 300962306a36Sopenharmony_ci case UPIO_PORT: 301062306a36Sopenharmony_ci if (!request_region(port->iobase, size, "serial")) 301162306a36Sopenharmony_ci ret = -EBUSY; 301262306a36Sopenharmony_ci break; 301362306a36Sopenharmony_ci } 301462306a36Sopenharmony_ci return ret; 301562306a36Sopenharmony_ci} 301662306a36Sopenharmony_ci 301762306a36Sopenharmony_cistatic void serial8250_release_std_resource(struct uart_8250_port *up) 301862306a36Sopenharmony_ci{ 301962306a36Sopenharmony_ci unsigned int size = serial8250_port_size(up); 302062306a36Sopenharmony_ci struct uart_port *port = &up->port; 302162306a36Sopenharmony_ci 302262306a36Sopenharmony_ci switch (port->iotype) { 302362306a36Sopenharmony_ci case UPIO_AU: 302462306a36Sopenharmony_ci case UPIO_TSI: 302562306a36Sopenharmony_ci case UPIO_MEM32: 302662306a36Sopenharmony_ci case UPIO_MEM32BE: 302762306a36Sopenharmony_ci case UPIO_MEM16: 302862306a36Sopenharmony_ci case UPIO_MEM: 302962306a36Sopenharmony_ci if (!port->mapbase) 303062306a36Sopenharmony_ci break; 303162306a36Sopenharmony_ci 303262306a36Sopenharmony_ci if (port->flags & UPF_IOREMAP) { 303362306a36Sopenharmony_ci iounmap(port->membase); 303462306a36Sopenharmony_ci port->membase = NULL; 303562306a36Sopenharmony_ci } 303662306a36Sopenharmony_ci 303762306a36Sopenharmony_ci release_mem_region(port->mapbase, size); 303862306a36Sopenharmony_ci break; 303962306a36Sopenharmony_ci 304062306a36Sopenharmony_ci case UPIO_HUB6: 304162306a36Sopenharmony_ci case UPIO_PORT: 304262306a36Sopenharmony_ci release_region(port->iobase, size); 304362306a36Sopenharmony_ci break; 304462306a36Sopenharmony_ci } 304562306a36Sopenharmony_ci} 304662306a36Sopenharmony_ci 304762306a36Sopenharmony_cistatic void serial8250_release_port(struct uart_port *port) 304862306a36Sopenharmony_ci{ 304962306a36Sopenharmony_ci struct uart_8250_port *up = up_to_u8250p(port); 305062306a36Sopenharmony_ci 305162306a36Sopenharmony_ci serial8250_release_std_resource(up); 305262306a36Sopenharmony_ci} 305362306a36Sopenharmony_ci 305462306a36Sopenharmony_cistatic int serial8250_request_port(struct uart_port *port) 305562306a36Sopenharmony_ci{ 305662306a36Sopenharmony_ci struct uart_8250_port *up = up_to_u8250p(port); 305762306a36Sopenharmony_ci 305862306a36Sopenharmony_ci return serial8250_request_std_resource(up); 305962306a36Sopenharmony_ci} 306062306a36Sopenharmony_ci 306162306a36Sopenharmony_cistatic int fcr_get_rxtrig_bytes(struct uart_8250_port *up) 306262306a36Sopenharmony_ci{ 306362306a36Sopenharmony_ci const struct serial8250_config *conf_type = &uart_config[up->port.type]; 306462306a36Sopenharmony_ci unsigned char bytes; 306562306a36Sopenharmony_ci 306662306a36Sopenharmony_ci bytes = conf_type->rxtrig_bytes[UART_FCR_R_TRIG_BITS(up->fcr)]; 306762306a36Sopenharmony_ci 306862306a36Sopenharmony_ci return bytes ? bytes : -EOPNOTSUPP; 306962306a36Sopenharmony_ci} 307062306a36Sopenharmony_ci 307162306a36Sopenharmony_cistatic int bytes_to_fcr_rxtrig(struct uart_8250_port *up, unsigned char bytes) 307262306a36Sopenharmony_ci{ 307362306a36Sopenharmony_ci const struct serial8250_config *conf_type = &uart_config[up->port.type]; 307462306a36Sopenharmony_ci int i; 307562306a36Sopenharmony_ci 307662306a36Sopenharmony_ci if (!conf_type->rxtrig_bytes[UART_FCR_R_TRIG_BITS(UART_FCR_R_TRIG_00)]) 307762306a36Sopenharmony_ci return -EOPNOTSUPP; 307862306a36Sopenharmony_ci 307962306a36Sopenharmony_ci for (i = 1; i < UART_FCR_R_TRIG_MAX_STATE; i++) { 308062306a36Sopenharmony_ci if (bytes < conf_type->rxtrig_bytes[i]) 308162306a36Sopenharmony_ci /* Use the nearest lower value */ 308262306a36Sopenharmony_ci return (--i) << UART_FCR_R_TRIG_SHIFT; 308362306a36Sopenharmony_ci } 308462306a36Sopenharmony_ci 308562306a36Sopenharmony_ci return UART_FCR_R_TRIG_11; 308662306a36Sopenharmony_ci} 308762306a36Sopenharmony_ci 308862306a36Sopenharmony_cistatic int do_get_rxtrig(struct tty_port *port) 308962306a36Sopenharmony_ci{ 309062306a36Sopenharmony_ci struct uart_state *state = container_of(port, struct uart_state, port); 309162306a36Sopenharmony_ci struct uart_port *uport = state->uart_port; 309262306a36Sopenharmony_ci struct uart_8250_port *up = up_to_u8250p(uport); 309362306a36Sopenharmony_ci 309462306a36Sopenharmony_ci if (!(up->capabilities & UART_CAP_FIFO) || uport->fifosize <= 1) 309562306a36Sopenharmony_ci return -EINVAL; 309662306a36Sopenharmony_ci 309762306a36Sopenharmony_ci return fcr_get_rxtrig_bytes(up); 309862306a36Sopenharmony_ci} 309962306a36Sopenharmony_ci 310062306a36Sopenharmony_cistatic int do_serial8250_get_rxtrig(struct tty_port *port) 310162306a36Sopenharmony_ci{ 310262306a36Sopenharmony_ci int rxtrig_bytes; 310362306a36Sopenharmony_ci 310462306a36Sopenharmony_ci mutex_lock(&port->mutex); 310562306a36Sopenharmony_ci rxtrig_bytes = do_get_rxtrig(port); 310662306a36Sopenharmony_ci mutex_unlock(&port->mutex); 310762306a36Sopenharmony_ci 310862306a36Sopenharmony_ci return rxtrig_bytes; 310962306a36Sopenharmony_ci} 311062306a36Sopenharmony_ci 311162306a36Sopenharmony_cistatic ssize_t rx_trig_bytes_show(struct device *dev, 311262306a36Sopenharmony_ci struct device_attribute *attr, char *buf) 311362306a36Sopenharmony_ci{ 311462306a36Sopenharmony_ci struct tty_port *port = dev_get_drvdata(dev); 311562306a36Sopenharmony_ci int rxtrig_bytes; 311662306a36Sopenharmony_ci 311762306a36Sopenharmony_ci rxtrig_bytes = do_serial8250_get_rxtrig(port); 311862306a36Sopenharmony_ci if (rxtrig_bytes < 0) 311962306a36Sopenharmony_ci return rxtrig_bytes; 312062306a36Sopenharmony_ci 312162306a36Sopenharmony_ci return sysfs_emit(buf, "%d\n", rxtrig_bytes); 312262306a36Sopenharmony_ci} 312362306a36Sopenharmony_ci 312462306a36Sopenharmony_cistatic int do_set_rxtrig(struct tty_port *port, unsigned char bytes) 312562306a36Sopenharmony_ci{ 312662306a36Sopenharmony_ci struct uart_state *state = container_of(port, struct uart_state, port); 312762306a36Sopenharmony_ci struct uart_port *uport = state->uart_port; 312862306a36Sopenharmony_ci struct uart_8250_port *up = up_to_u8250p(uport); 312962306a36Sopenharmony_ci int rxtrig; 313062306a36Sopenharmony_ci 313162306a36Sopenharmony_ci if (!(up->capabilities & UART_CAP_FIFO) || uport->fifosize <= 1) 313262306a36Sopenharmony_ci return -EINVAL; 313362306a36Sopenharmony_ci 313462306a36Sopenharmony_ci rxtrig = bytes_to_fcr_rxtrig(up, bytes); 313562306a36Sopenharmony_ci if (rxtrig < 0) 313662306a36Sopenharmony_ci return rxtrig; 313762306a36Sopenharmony_ci 313862306a36Sopenharmony_ci serial8250_clear_fifos(up); 313962306a36Sopenharmony_ci up->fcr &= ~UART_FCR_TRIGGER_MASK; 314062306a36Sopenharmony_ci up->fcr |= (unsigned char)rxtrig; 314162306a36Sopenharmony_ci serial_out(up, UART_FCR, up->fcr); 314262306a36Sopenharmony_ci return 0; 314362306a36Sopenharmony_ci} 314462306a36Sopenharmony_ci 314562306a36Sopenharmony_cistatic int do_serial8250_set_rxtrig(struct tty_port *port, unsigned char bytes) 314662306a36Sopenharmony_ci{ 314762306a36Sopenharmony_ci int ret; 314862306a36Sopenharmony_ci 314962306a36Sopenharmony_ci mutex_lock(&port->mutex); 315062306a36Sopenharmony_ci ret = do_set_rxtrig(port, bytes); 315162306a36Sopenharmony_ci mutex_unlock(&port->mutex); 315262306a36Sopenharmony_ci 315362306a36Sopenharmony_ci return ret; 315462306a36Sopenharmony_ci} 315562306a36Sopenharmony_ci 315662306a36Sopenharmony_cistatic ssize_t rx_trig_bytes_store(struct device *dev, 315762306a36Sopenharmony_ci struct device_attribute *attr, const char *buf, size_t count) 315862306a36Sopenharmony_ci{ 315962306a36Sopenharmony_ci struct tty_port *port = dev_get_drvdata(dev); 316062306a36Sopenharmony_ci unsigned char bytes; 316162306a36Sopenharmony_ci int ret; 316262306a36Sopenharmony_ci 316362306a36Sopenharmony_ci if (!count) 316462306a36Sopenharmony_ci return -EINVAL; 316562306a36Sopenharmony_ci 316662306a36Sopenharmony_ci ret = kstrtou8(buf, 10, &bytes); 316762306a36Sopenharmony_ci if (ret < 0) 316862306a36Sopenharmony_ci return ret; 316962306a36Sopenharmony_ci 317062306a36Sopenharmony_ci ret = do_serial8250_set_rxtrig(port, bytes); 317162306a36Sopenharmony_ci if (ret < 0) 317262306a36Sopenharmony_ci return ret; 317362306a36Sopenharmony_ci 317462306a36Sopenharmony_ci return count; 317562306a36Sopenharmony_ci} 317662306a36Sopenharmony_ci 317762306a36Sopenharmony_cistatic DEVICE_ATTR_RW(rx_trig_bytes); 317862306a36Sopenharmony_ci 317962306a36Sopenharmony_cistatic struct attribute *serial8250_dev_attrs[] = { 318062306a36Sopenharmony_ci &dev_attr_rx_trig_bytes.attr, 318162306a36Sopenharmony_ci NULL 318262306a36Sopenharmony_ci}; 318362306a36Sopenharmony_ci 318462306a36Sopenharmony_cistatic struct attribute_group serial8250_dev_attr_group = { 318562306a36Sopenharmony_ci .attrs = serial8250_dev_attrs, 318662306a36Sopenharmony_ci}; 318762306a36Sopenharmony_ci 318862306a36Sopenharmony_cistatic void register_dev_spec_attr_grp(struct uart_8250_port *up) 318962306a36Sopenharmony_ci{ 319062306a36Sopenharmony_ci const struct serial8250_config *conf_type = &uart_config[up->port.type]; 319162306a36Sopenharmony_ci 319262306a36Sopenharmony_ci if (conf_type->rxtrig_bytes[0]) 319362306a36Sopenharmony_ci up->port.attr_group = &serial8250_dev_attr_group; 319462306a36Sopenharmony_ci} 319562306a36Sopenharmony_ci 319662306a36Sopenharmony_cistatic void serial8250_config_port(struct uart_port *port, int flags) 319762306a36Sopenharmony_ci{ 319862306a36Sopenharmony_ci struct uart_8250_port *up = up_to_u8250p(port); 319962306a36Sopenharmony_ci int ret; 320062306a36Sopenharmony_ci 320162306a36Sopenharmony_ci /* 320262306a36Sopenharmony_ci * Find the region that we can probe for. This in turn 320362306a36Sopenharmony_ci * tells us whether we can probe for the type of port. 320462306a36Sopenharmony_ci */ 320562306a36Sopenharmony_ci ret = serial8250_request_std_resource(up); 320662306a36Sopenharmony_ci if (ret < 0) 320762306a36Sopenharmony_ci return; 320862306a36Sopenharmony_ci 320962306a36Sopenharmony_ci if (port->iotype != up->cur_iotype) 321062306a36Sopenharmony_ci set_io_from_upio(port); 321162306a36Sopenharmony_ci 321262306a36Sopenharmony_ci if (flags & UART_CONFIG_TYPE) 321362306a36Sopenharmony_ci autoconfig(up); 321462306a36Sopenharmony_ci 321562306a36Sopenharmony_ci /* HW bugs may trigger IRQ while IIR == NO_INT */ 321662306a36Sopenharmony_ci if (port->type == PORT_TEGRA) 321762306a36Sopenharmony_ci up->bugs |= UART_BUG_NOMSR; 321862306a36Sopenharmony_ci 321962306a36Sopenharmony_ci if (port->type != PORT_UNKNOWN && flags & UART_CONFIG_IRQ) 322062306a36Sopenharmony_ci autoconfig_irq(up); 322162306a36Sopenharmony_ci 322262306a36Sopenharmony_ci if (port->type == PORT_UNKNOWN) 322362306a36Sopenharmony_ci serial8250_release_std_resource(up); 322462306a36Sopenharmony_ci 322562306a36Sopenharmony_ci register_dev_spec_attr_grp(up); 322662306a36Sopenharmony_ci up->fcr = uart_config[up->port.type].fcr; 322762306a36Sopenharmony_ci} 322862306a36Sopenharmony_ci 322962306a36Sopenharmony_cistatic int 323062306a36Sopenharmony_ciserial8250_verify_port(struct uart_port *port, struct serial_struct *ser) 323162306a36Sopenharmony_ci{ 323262306a36Sopenharmony_ci if (ser->irq >= nr_irqs || ser->irq < 0 || 323362306a36Sopenharmony_ci ser->baud_base < 9600 || ser->type < PORT_UNKNOWN || 323462306a36Sopenharmony_ci ser->type >= ARRAY_SIZE(uart_config) || ser->type == PORT_CIRRUS || 323562306a36Sopenharmony_ci ser->type == PORT_STARTECH) 323662306a36Sopenharmony_ci return -EINVAL; 323762306a36Sopenharmony_ci return 0; 323862306a36Sopenharmony_ci} 323962306a36Sopenharmony_ci 324062306a36Sopenharmony_cistatic const char *serial8250_type(struct uart_port *port) 324162306a36Sopenharmony_ci{ 324262306a36Sopenharmony_ci int type = port->type; 324362306a36Sopenharmony_ci 324462306a36Sopenharmony_ci if (type >= ARRAY_SIZE(uart_config)) 324562306a36Sopenharmony_ci type = 0; 324662306a36Sopenharmony_ci return uart_config[type].name; 324762306a36Sopenharmony_ci} 324862306a36Sopenharmony_ci 324962306a36Sopenharmony_cistatic const struct uart_ops serial8250_pops = { 325062306a36Sopenharmony_ci .tx_empty = serial8250_tx_empty, 325162306a36Sopenharmony_ci .set_mctrl = serial8250_set_mctrl, 325262306a36Sopenharmony_ci .get_mctrl = serial8250_get_mctrl, 325362306a36Sopenharmony_ci .stop_tx = serial8250_stop_tx, 325462306a36Sopenharmony_ci .start_tx = serial8250_start_tx, 325562306a36Sopenharmony_ci .throttle = serial8250_throttle, 325662306a36Sopenharmony_ci .unthrottle = serial8250_unthrottle, 325762306a36Sopenharmony_ci .stop_rx = serial8250_stop_rx, 325862306a36Sopenharmony_ci .enable_ms = serial8250_enable_ms, 325962306a36Sopenharmony_ci .break_ctl = serial8250_break_ctl, 326062306a36Sopenharmony_ci .startup = serial8250_startup, 326162306a36Sopenharmony_ci .shutdown = serial8250_shutdown, 326262306a36Sopenharmony_ci .set_termios = serial8250_set_termios, 326362306a36Sopenharmony_ci .set_ldisc = serial8250_set_ldisc, 326462306a36Sopenharmony_ci .pm = serial8250_pm, 326562306a36Sopenharmony_ci .type = serial8250_type, 326662306a36Sopenharmony_ci .release_port = serial8250_release_port, 326762306a36Sopenharmony_ci .request_port = serial8250_request_port, 326862306a36Sopenharmony_ci .config_port = serial8250_config_port, 326962306a36Sopenharmony_ci .verify_port = serial8250_verify_port, 327062306a36Sopenharmony_ci#ifdef CONFIG_CONSOLE_POLL 327162306a36Sopenharmony_ci .poll_get_char = serial8250_get_poll_char, 327262306a36Sopenharmony_ci .poll_put_char = serial8250_put_poll_char, 327362306a36Sopenharmony_ci#endif 327462306a36Sopenharmony_ci}; 327562306a36Sopenharmony_ci 327662306a36Sopenharmony_civoid serial8250_init_port(struct uart_8250_port *up) 327762306a36Sopenharmony_ci{ 327862306a36Sopenharmony_ci struct uart_port *port = &up->port; 327962306a36Sopenharmony_ci 328062306a36Sopenharmony_ci spin_lock_init(&port->lock); 328162306a36Sopenharmony_ci port->ctrl_id = 0; 328262306a36Sopenharmony_ci port->pm = NULL; 328362306a36Sopenharmony_ci port->ops = &serial8250_pops; 328462306a36Sopenharmony_ci port->has_sysrq = IS_ENABLED(CONFIG_SERIAL_8250_CONSOLE); 328562306a36Sopenharmony_ci 328662306a36Sopenharmony_ci up->cur_iotype = 0xFF; 328762306a36Sopenharmony_ci} 328862306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(serial8250_init_port); 328962306a36Sopenharmony_ci 329062306a36Sopenharmony_civoid serial8250_set_defaults(struct uart_8250_port *up) 329162306a36Sopenharmony_ci{ 329262306a36Sopenharmony_ci struct uart_port *port = &up->port; 329362306a36Sopenharmony_ci 329462306a36Sopenharmony_ci if (up->port.flags & UPF_FIXED_TYPE) { 329562306a36Sopenharmony_ci unsigned int type = up->port.type; 329662306a36Sopenharmony_ci 329762306a36Sopenharmony_ci if (!up->port.fifosize) 329862306a36Sopenharmony_ci up->port.fifosize = uart_config[type].fifo_size; 329962306a36Sopenharmony_ci if (!up->tx_loadsz) 330062306a36Sopenharmony_ci up->tx_loadsz = uart_config[type].tx_loadsz; 330162306a36Sopenharmony_ci if (!up->capabilities) 330262306a36Sopenharmony_ci up->capabilities = uart_config[type].flags; 330362306a36Sopenharmony_ci } 330462306a36Sopenharmony_ci 330562306a36Sopenharmony_ci set_io_from_upio(port); 330662306a36Sopenharmony_ci 330762306a36Sopenharmony_ci /* default dma handlers */ 330862306a36Sopenharmony_ci if (up->dma) { 330962306a36Sopenharmony_ci if (!up->dma->tx_dma) 331062306a36Sopenharmony_ci up->dma->tx_dma = serial8250_tx_dma; 331162306a36Sopenharmony_ci if (!up->dma->rx_dma) 331262306a36Sopenharmony_ci up->dma->rx_dma = serial8250_rx_dma; 331362306a36Sopenharmony_ci } 331462306a36Sopenharmony_ci} 331562306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(serial8250_set_defaults); 331662306a36Sopenharmony_ci 331762306a36Sopenharmony_ci#ifdef CONFIG_SERIAL_8250_CONSOLE 331862306a36Sopenharmony_ci 331962306a36Sopenharmony_cistatic void serial8250_console_putchar(struct uart_port *port, unsigned char ch) 332062306a36Sopenharmony_ci{ 332162306a36Sopenharmony_ci struct uart_8250_port *up = up_to_u8250p(port); 332262306a36Sopenharmony_ci 332362306a36Sopenharmony_ci wait_for_xmitr(up, UART_LSR_THRE); 332462306a36Sopenharmony_ci serial_port_out(port, UART_TX, ch); 332562306a36Sopenharmony_ci} 332662306a36Sopenharmony_ci 332762306a36Sopenharmony_ci/* 332862306a36Sopenharmony_ci * Restore serial console when h/w power-off detected 332962306a36Sopenharmony_ci */ 333062306a36Sopenharmony_cistatic void serial8250_console_restore(struct uart_8250_port *up) 333162306a36Sopenharmony_ci{ 333262306a36Sopenharmony_ci struct uart_port *port = &up->port; 333362306a36Sopenharmony_ci struct ktermios termios; 333462306a36Sopenharmony_ci unsigned int baud, quot, frac = 0; 333562306a36Sopenharmony_ci 333662306a36Sopenharmony_ci termios.c_cflag = port->cons->cflag; 333762306a36Sopenharmony_ci termios.c_ispeed = port->cons->ispeed; 333862306a36Sopenharmony_ci termios.c_ospeed = port->cons->ospeed; 333962306a36Sopenharmony_ci if (port->state->port.tty && termios.c_cflag == 0) { 334062306a36Sopenharmony_ci termios.c_cflag = port->state->port.tty->termios.c_cflag; 334162306a36Sopenharmony_ci termios.c_ispeed = port->state->port.tty->termios.c_ispeed; 334262306a36Sopenharmony_ci termios.c_ospeed = port->state->port.tty->termios.c_ospeed; 334362306a36Sopenharmony_ci } 334462306a36Sopenharmony_ci 334562306a36Sopenharmony_ci baud = serial8250_get_baud_rate(port, &termios, NULL); 334662306a36Sopenharmony_ci quot = serial8250_get_divisor(port, baud, &frac); 334762306a36Sopenharmony_ci 334862306a36Sopenharmony_ci serial8250_set_divisor(port, baud, quot, frac); 334962306a36Sopenharmony_ci serial_port_out(port, UART_LCR, up->lcr); 335062306a36Sopenharmony_ci serial8250_out_MCR(up, up->mcr | UART_MCR_DTR | UART_MCR_RTS); 335162306a36Sopenharmony_ci} 335262306a36Sopenharmony_ci 335362306a36Sopenharmony_ci/* 335462306a36Sopenharmony_ci * Print a string to the serial port using the device FIFO 335562306a36Sopenharmony_ci * 335662306a36Sopenharmony_ci * It sends fifosize bytes and then waits for the fifo 335762306a36Sopenharmony_ci * to get empty. 335862306a36Sopenharmony_ci */ 335962306a36Sopenharmony_cistatic void serial8250_console_fifo_write(struct uart_8250_port *up, 336062306a36Sopenharmony_ci const char *s, unsigned int count) 336162306a36Sopenharmony_ci{ 336262306a36Sopenharmony_ci int i; 336362306a36Sopenharmony_ci const char *end = s + count; 336462306a36Sopenharmony_ci unsigned int fifosize = up->tx_loadsz; 336562306a36Sopenharmony_ci bool cr_sent = false; 336662306a36Sopenharmony_ci 336762306a36Sopenharmony_ci while (s != end) { 336862306a36Sopenharmony_ci wait_for_lsr(up, UART_LSR_THRE); 336962306a36Sopenharmony_ci 337062306a36Sopenharmony_ci for (i = 0; i < fifosize && s != end; ++i) { 337162306a36Sopenharmony_ci if (*s == '\n' && !cr_sent) { 337262306a36Sopenharmony_ci serial_out(up, UART_TX, '\r'); 337362306a36Sopenharmony_ci cr_sent = true; 337462306a36Sopenharmony_ci } else { 337562306a36Sopenharmony_ci serial_out(up, UART_TX, *s++); 337662306a36Sopenharmony_ci cr_sent = false; 337762306a36Sopenharmony_ci } 337862306a36Sopenharmony_ci } 337962306a36Sopenharmony_ci } 338062306a36Sopenharmony_ci} 338162306a36Sopenharmony_ci 338262306a36Sopenharmony_ci/* 338362306a36Sopenharmony_ci * Print a string to the serial port trying not to disturb 338462306a36Sopenharmony_ci * any possible real use of the port... 338562306a36Sopenharmony_ci * 338662306a36Sopenharmony_ci * The console_lock must be held when we get here. 338762306a36Sopenharmony_ci * 338862306a36Sopenharmony_ci * Doing runtime PM is really a bad idea for the kernel console. 338962306a36Sopenharmony_ci * Thus, we assume the function is called when device is powered up. 339062306a36Sopenharmony_ci */ 339162306a36Sopenharmony_civoid serial8250_console_write(struct uart_8250_port *up, const char *s, 339262306a36Sopenharmony_ci unsigned int count) 339362306a36Sopenharmony_ci{ 339462306a36Sopenharmony_ci struct uart_8250_em485 *em485 = up->em485; 339562306a36Sopenharmony_ci struct uart_port *port = &up->port; 339662306a36Sopenharmony_ci unsigned long flags; 339762306a36Sopenharmony_ci unsigned int ier, use_fifo; 339862306a36Sopenharmony_ci int locked = 1; 339962306a36Sopenharmony_ci 340062306a36Sopenharmony_ci touch_nmi_watchdog(); 340162306a36Sopenharmony_ci 340262306a36Sopenharmony_ci if (oops_in_progress) 340362306a36Sopenharmony_ci locked = spin_trylock_irqsave(&port->lock, flags); 340462306a36Sopenharmony_ci else 340562306a36Sopenharmony_ci spin_lock_irqsave(&port->lock, flags); 340662306a36Sopenharmony_ci 340762306a36Sopenharmony_ci /* 340862306a36Sopenharmony_ci * First save the IER then disable the interrupts 340962306a36Sopenharmony_ci */ 341062306a36Sopenharmony_ci ier = serial_port_in(port, UART_IER); 341162306a36Sopenharmony_ci serial8250_clear_IER(up); 341262306a36Sopenharmony_ci 341362306a36Sopenharmony_ci /* check scratch reg to see if port powered off during system sleep */ 341462306a36Sopenharmony_ci if (up->canary && (up->canary != serial_port_in(port, UART_SCR))) { 341562306a36Sopenharmony_ci serial8250_console_restore(up); 341662306a36Sopenharmony_ci up->canary = 0; 341762306a36Sopenharmony_ci } 341862306a36Sopenharmony_ci 341962306a36Sopenharmony_ci if (em485) { 342062306a36Sopenharmony_ci if (em485->tx_stopped) 342162306a36Sopenharmony_ci up->rs485_start_tx(up); 342262306a36Sopenharmony_ci mdelay(port->rs485.delay_rts_before_send); 342362306a36Sopenharmony_ci } 342462306a36Sopenharmony_ci 342562306a36Sopenharmony_ci use_fifo = (up->capabilities & UART_CAP_FIFO) && 342662306a36Sopenharmony_ci /* 342762306a36Sopenharmony_ci * BCM283x requires to check the fifo 342862306a36Sopenharmony_ci * after each byte. 342962306a36Sopenharmony_ci */ 343062306a36Sopenharmony_ci !(up->capabilities & UART_CAP_MINI) && 343162306a36Sopenharmony_ci /* 343262306a36Sopenharmony_ci * tx_loadsz contains the transmit fifo size 343362306a36Sopenharmony_ci */ 343462306a36Sopenharmony_ci up->tx_loadsz > 1 && 343562306a36Sopenharmony_ci (up->fcr & UART_FCR_ENABLE_FIFO) && 343662306a36Sopenharmony_ci port->state && 343762306a36Sopenharmony_ci test_bit(TTY_PORT_INITIALIZED, &port->state->port.iflags) && 343862306a36Sopenharmony_ci /* 343962306a36Sopenharmony_ci * After we put a data in the fifo, the controller will send 344062306a36Sopenharmony_ci * it regardless of the CTS state. Therefore, only use fifo 344162306a36Sopenharmony_ci * if we don't use control flow. 344262306a36Sopenharmony_ci */ 344362306a36Sopenharmony_ci !(up->port.flags & UPF_CONS_FLOW); 344462306a36Sopenharmony_ci 344562306a36Sopenharmony_ci if (likely(use_fifo)) 344662306a36Sopenharmony_ci serial8250_console_fifo_write(up, s, count); 344762306a36Sopenharmony_ci else 344862306a36Sopenharmony_ci uart_console_write(port, s, count, serial8250_console_putchar); 344962306a36Sopenharmony_ci 345062306a36Sopenharmony_ci /* 345162306a36Sopenharmony_ci * Finally, wait for transmitter to become empty 345262306a36Sopenharmony_ci * and restore the IER 345362306a36Sopenharmony_ci */ 345462306a36Sopenharmony_ci wait_for_xmitr(up, UART_LSR_BOTH_EMPTY); 345562306a36Sopenharmony_ci 345662306a36Sopenharmony_ci if (em485) { 345762306a36Sopenharmony_ci mdelay(port->rs485.delay_rts_after_send); 345862306a36Sopenharmony_ci if (em485->tx_stopped) 345962306a36Sopenharmony_ci up->rs485_stop_tx(up); 346062306a36Sopenharmony_ci } 346162306a36Sopenharmony_ci 346262306a36Sopenharmony_ci serial_port_out(port, UART_IER, ier); 346362306a36Sopenharmony_ci 346462306a36Sopenharmony_ci /* 346562306a36Sopenharmony_ci * The receive handling will happen properly because the 346662306a36Sopenharmony_ci * receive ready bit will still be set; it is not cleared 346762306a36Sopenharmony_ci * on read. However, modem control will not, we must 346862306a36Sopenharmony_ci * call it if we have saved something in the saved flags 346962306a36Sopenharmony_ci * while processing with interrupts off. 347062306a36Sopenharmony_ci */ 347162306a36Sopenharmony_ci if (up->msr_saved_flags) 347262306a36Sopenharmony_ci serial8250_modem_status(up); 347362306a36Sopenharmony_ci 347462306a36Sopenharmony_ci if (locked) 347562306a36Sopenharmony_ci spin_unlock_irqrestore(&port->lock, flags); 347662306a36Sopenharmony_ci} 347762306a36Sopenharmony_ci 347862306a36Sopenharmony_cistatic unsigned int probe_baud(struct uart_port *port) 347962306a36Sopenharmony_ci{ 348062306a36Sopenharmony_ci unsigned char lcr, dll, dlm; 348162306a36Sopenharmony_ci unsigned int quot; 348262306a36Sopenharmony_ci 348362306a36Sopenharmony_ci lcr = serial_port_in(port, UART_LCR); 348462306a36Sopenharmony_ci serial_port_out(port, UART_LCR, lcr | UART_LCR_DLAB); 348562306a36Sopenharmony_ci dll = serial_port_in(port, UART_DLL); 348662306a36Sopenharmony_ci dlm = serial_port_in(port, UART_DLM); 348762306a36Sopenharmony_ci serial_port_out(port, UART_LCR, lcr); 348862306a36Sopenharmony_ci 348962306a36Sopenharmony_ci quot = (dlm << 8) | dll; 349062306a36Sopenharmony_ci return (port->uartclk / 16) / quot; 349162306a36Sopenharmony_ci} 349262306a36Sopenharmony_ci 349362306a36Sopenharmony_ciint serial8250_console_setup(struct uart_port *port, char *options, bool probe) 349462306a36Sopenharmony_ci{ 349562306a36Sopenharmony_ci int baud = 9600; 349662306a36Sopenharmony_ci int bits = 8; 349762306a36Sopenharmony_ci int parity = 'n'; 349862306a36Sopenharmony_ci int flow = 'n'; 349962306a36Sopenharmony_ci int ret; 350062306a36Sopenharmony_ci 350162306a36Sopenharmony_ci if (!port->iobase && !port->membase) 350262306a36Sopenharmony_ci return -ENODEV; 350362306a36Sopenharmony_ci 350462306a36Sopenharmony_ci if (options) 350562306a36Sopenharmony_ci uart_parse_options(options, &baud, &parity, &bits, &flow); 350662306a36Sopenharmony_ci else if (probe) 350762306a36Sopenharmony_ci baud = probe_baud(port); 350862306a36Sopenharmony_ci 350962306a36Sopenharmony_ci ret = uart_set_options(port, port->cons, baud, parity, bits, flow); 351062306a36Sopenharmony_ci if (ret) 351162306a36Sopenharmony_ci return ret; 351262306a36Sopenharmony_ci 351362306a36Sopenharmony_ci if (port->dev) 351462306a36Sopenharmony_ci pm_runtime_get_sync(port->dev); 351562306a36Sopenharmony_ci 351662306a36Sopenharmony_ci return 0; 351762306a36Sopenharmony_ci} 351862306a36Sopenharmony_ci 351962306a36Sopenharmony_ciint serial8250_console_exit(struct uart_port *port) 352062306a36Sopenharmony_ci{ 352162306a36Sopenharmony_ci if (port->dev) 352262306a36Sopenharmony_ci pm_runtime_put_sync(port->dev); 352362306a36Sopenharmony_ci 352462306a36Sopenharmony_ci return 0; 352562306a36Sopenharmony_ci} 352662306a36Sopenharmony_ci 352762306a36Sopenharmony_ci#endif /* CONFIG_SERIAL_8250_CONSOLE */ 352862306a36Sopenharmony_ci 352962306a36Sopenharmony_ciMODULE_LICENSE("GPL"); 3530