summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/serial/maxim,max310x.yaml92
-rw-r--r--Documentation/devicetree/bindings/serial/snps-dw-apb-uart.yaml1
-rw-r--r--drivers/tty/amiserial.c14
-rw-r--r--drivers/tty/goldfish.c23
-rw-r--r--drivers/tty/hvc/Kconfig2
-rw-r--r--drivers/tty/serdev/core.c4
-rw-r--r--drivers/tty/serial/8250/8250.h8
-rw-r--r--drivers/tty/serial/8250/8250_core.c6
-rw-r--r--drivers/tty/serial/8250/8250_early.c19
-rw-r--r--drivers/tty/serial/8250/8250_exar.c30
-rw-r--r--drivers/tty/serial/8250/8250_hub6.c8
-rw-r--r--drivers/tty/serial/8250/8250_of.c12
-rw-r--r--drivers/tty/serial/8250/8250_platform.c1
-rw-r--r--drivers/tty/serial/8250/8250_pnp.c309
-rw-r--r--drivers/tty/serial/8250/8250_port.c43
-rw-r--r--drivers/tty/serial/8250/8250_rsa.c44
-rw-r--r--drivers/tty/serial/cpm_uart.c9
-rw-r--r--drivers/tty/serial/earlycon.c17
-rw-r--r--drivers/tty/serial/kgdboc.c2
-rw-r--r--drivers/tty/serial/ma35d1_serial.c12
-rw-r--r--drivers/tty/serial/max3100.c1
-rw-r--r--drivers/tty/serial/max310x.c100
-rw-r--r--drivers/tty/serial/men_z135_uart.c7
-rw-r--r--drivers/tty/serial/mpc52xx_uart.c8
-rw-r--r--drivers/tty/serial/pch_uart.c11
-rw-r--r--drivers/tty/serial/qcom_geni_serial.c155
-rw-r--r--drivers/tty/serial/rp2.c2
-rw-r--r--drivers/tty/serial/sc16is7xx.c9
-rw-r--r--drivers/tty/serial/serial_core.c127
-rw-r--r--drivers/tty/tty_jobctrl.c41
-rw-r--r--drivers/tty/vt/vc_screen.c6
-rw-r--r--include/linux/goldfish.h24
-rw-r--r--include/linux/serial_core.h6
-rw-r--r--include/trace/events/qcom_geni_serial.h7
-rw-r--r--include/uapi/linux/serial.h1
35 files changed, 709 insertions, 452 deletions
diff --git a/Documentation/devicetree/bindings/serial/maxim,max310x.yaml b/Documentation/devicetree/bindings/serial/maxim,max310x.yaml
index 889eeaca64a0..e598dda4d13f 100644
--- a/Documentation/devicetree/bindings/serial/maxim,max310x.yaml
+++ b/Documentation/devicetree/bindings/serial/maxim,max310x.yaml
@@ -9,6 +9,13 @@ title: Maxim MAX310X Advanced Universal Asynchronous Receiver-Transmitter (UART)
maintainers:
- Hugo Villeneuve <hvilleneuve@dimonoff.com>
+description:
+ The MAX310X is a family of SPI/I2C UARTs with one (max3107, max3108),
+ two (max3109) or four (max14830) channels. Single-channel parts are
+ described as a serial node with RS-485 properties on the chip node;
+ multi-channel parts use one "serial@N" child node per channel, each
+ carrying its own serial/RS-485 properties.
+
properties:
compatible:
enum:
@@ -49,8 +56,55 @@ required:
allOf:
- $ref: /schemas/spi/spi-peripheral-props.yaml#
- - $ref: /schemas/serial/serial.yaml#
- - $ref: /schemas/serial/rs485.yaml#
+
+ - if:
+ properties:
+ compatible:
+ contains:
+ enum:
+ - maxim,max3107
+ - maxim,max3108
+ then:
+ allOf:
+ - $ref: /schemas/serial/serial.yaml#
+ - $ref: /schemas/serial/rs485.yaml#
+
+ - if:
+ properties:
+ compatible:
+ contains:
+ enum:
+ - maxim,max3109
+ - maxim,max14830
+ then:
+ properties:
+ "#address-cells":
+ const: 1
+ "#size-cells":
+ const: 0
+ patternProperties:
+ "^serial@[0-3]$":
+ type: object
+ description: A single UART channel of the chip.
+ allOf:
+ - $ref: /schemas/serial/serial.yaml#
+ - $ref: /schemas/serial/rs485.yaml#
+ properties:
+ reg:
+ description: UART channel number on the chip.
+ maximum: 3
+ required:
+ - reg
+ unevaluatedProperties: false
+
+ - if:
+ properties:
+ compatible:
+ contains:
+ const: maxim,max3109
+ then:
+ patternProperties:
+ "^serial@[23]$": false
unevaluatedProperties: false
@@ -70,5 +124,39 @@ examples:
interrupts = <7 IRQ_TYPE_LEVEL_LOW>;
gpio-controller;
#gpio-cells = <2>;
+ rs485-rts-active-low;
+ linux,rs485-enabled-at-boot-time;
+ };
+ };
+
+ - |
+ #include <dt-bindings/interrupt-controller/irq.h>
+ spi {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ serial@0 {
+ compatible = "maxim,max14830";
+ reg = <0>;
+ spi-max-frequency = <26000000>;
+ clocks = <&xtal4m>;
+ clock-names = "xtal";
+ interrupt-parent = <&gpio3>;
+ interrupts = <7 IRQ_TYPE_LEVEL_LOW>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ serial@0 {
+ reg = <0>;
+ rs485-rts-active-low;
+ linux,rs485-enabled-at-boot-time;
+ };
+
+ serial@2 {
+ reg = <2>;
+ rs485-rts-active-low;
+ };
};
};
diff --git a/Documentation/devicetree/bindings/serial/snps-dw-apb-uart.yaml b/Documentation/devicetree/bindings/serial/snps-dw-apb-uart.yaml
index 49f51b002879..c0d0524458c1 100644
--- a/Documentation/devicetree/bindings/serial/snps-dw-apb-uart.yaml
+++ b/Documentation/devicetree/bindings/serial/snps-dw-apb-uart.yaml
@@ -72,6 +72,7 @@ properties:
- rockchip,rk3576-uart
- rockchip,rk3588-uart
- rockchip,rv1103b-uart
+ - rockchip,rv1106-uart
- rockchip,rv1108-uart
- rockchip,rv1126-uart
- sophgo,sg2044-uart
diff --git a/drivers/tty/amiserial.c b/drivers/tty/amiserial.c
index 81eaca751541..28af0fd98181 100644
--- a/drivers/tty/amiserial.c
+++ b/drivers/tty/amiserial.c
@@ -443,23 +443,23 @@ static int rs_startup(struct tty_struct *tty, struct serial_state *info)
struct tty_port *port = &info->tport;
unsigned long flags;
int retval=0;
- unsigned long page;
+ void *buffer;
- page = get_zeroed_page(GFP_KERNEL);
- if (!page)
+ buffer = kzalloc(PAGE_SIZE, GFP_KERNEL);
+ if (!buffer)
return -ENOMEM;
local_irq_save(flags);
if (tty_port_initialized(port)) {
- free_page(page);
+ kfree(buffer);
goto errout;
}
if (info->xmit.buf)
- free_page(page);
+ kfree(buffer);
else
- info->xmit.buf = (unsigned char *) page;
+ info->xmit.buf = buffer;
#ifdef SERIAL_DEBUG_OPEN
printk("starting up ttys%d ...", info->line);
@@ -537,7 +537,7 @@ static void rs_shutdown(struct tty_struct *tty, struct serial_state *info)
*/
free_irq(IRQ_AMIGA_VERTB, info);
- free_page((unsigned long)info->xmit.buf);
+ kfree(info->xmit.buf);
info->xmit.buf = NULL;
info->IER = 0;
diff --git a/drivers/tty/goldfish.c b/drivers/tty/goldfish.c
index 16edd71a0d8d..fa723a4ba7b3 100644
--- a/drivers/tty/goldfish.c
+++ b/drivers/tty/goldfish.c
@@ -17,6 +17,7 @@
#include <linux/mm.h>
#include <linux/dma-mapping.h>
#include <linux/serial_core.h>
+#include <linux/wordpart.h>
/* Goldfish tty register's offsets */
#define GOLDFISH_TTY_REG_BYTES_READY 0x04
@@ -37,7 +38,6 @@ struct goldfish_tty {
spinlock_t lock;
void __iomem *base;
u32 irq;
- int opencount;
struct console console;
u32 version;
struct device *dev;
@@ -49,15 +49,23 @@ static u32 goldfish_tty_line_count = 8;
static u32 goldfish_tty_current_line_count;
static struct goldfish_tty *goldfish_ttys;
+static inline void gf_write_addr(unsigned long addr, void __iomem *portl, void __iomem *porth)
+{
+ gf_iowrite32(lower_32_bits(addr), portl);
+#ifdef CONFIG_64BIT
+ gf_iowrite32(upper_32_bits(addr), porth);
+#endif
+}
+
static void do_rw_io(struct goldfish_tty *qtty, unsigned long address,
size_t count, bool is_write)
{
- unsigned long irq_flags;
void __iomem *base = qtty->base;
- spin_lock_irqsave(&qtty->lock, irq_flags);
- gf_write_ptr((void *)address, base + GOLDFISH_TTY_REG_DATA_PTR,
- base + GOLDFISH_TTY_REG_DATA_PTR_HIGH);
+ guard(spinlock_irqsave)(&qtty->lock);
+
+ gf_write_addr(address, base + GOLDFISH_TTY_REG_DATA_PTR,
+ base + GOLDFISH_TTY_REG_DATA_PTR_HIGH);
gf_iowrite32(count, base + GOLDFISH_TTY_REG_DATA_LEN);
if (is_write)
@@ -66,8 +74,6 @@ static void do_rw_io(struct goldfish_tty *qtty, unsigned long address,
else
gf_iowrite32(GOLDFISH_TTY_CMD_READ_BUFFER,
base + GOLDFISH_TTY_REG_CMD);
-
- spin_unlock_irqrestore(&qtty->lock, irq_flags);
}
static void goldfish_tty_rw(struct goldfish_tty *qtty, unsigned long addr,
@@ -409,7 +415,7 @@ static void goldfish_tty_remove(struct platform_device *pdev)
{
struct goldfish_tty *qtty = platform_get_drvdata(pdev);
- mutex_lock(&goldfish_tty_lock);
+ guard(mutex)(&goldfish_tty_lock);
unregister_console(&qtty->console);
tty_unregister_device(goldfish_tty_driver, qtty->console.index);
@@ -420,7 +426,6 @@ static void goldfish_tty_remove(struct platform_device *pdev)
goldfish_tty_current_line_count--;
if (goldfish_tty_current_line_count == 0)
goldfish_tty_delete_driver();
- mutex_unlock(&goldfish_tty_lock);
}
#ifdef CONFIG_GOLDFISH_TTY_EARLY_CONSOLE
diff --git a/drivers/tty/hvc/Kconfig b/drivers/tty/hvc/Kconfig
index c2a4e88b328f..5866195de26a 100644
--- a/drivers/tty/hvc/Kconfig
+++ b/drivers/tty/hvc/Kconfig
@@ -79,7 +79,7 @@ config HVC_UDBG
config HVC_DCC
bool "ARM JTAG DCC console"
- depends on ARM || ARM64
+ depends on (ARM && (CPU_V6 || CPU_V6K || CPU_V7)) || ARM64
select HVC_DRIVER
select SERIAL_CORE_CONSOLE
help
diff --git a/drivers/tty/serdev/core.c b/drivers/tty/serdev/core.c
index e9d044a331b0..7500efcdfc21 100644
--- a/drivers/tty/serdev/core.c
+++ b/drivers/tty/serdev/core.c
@@ -651,11 +651,11 @@ static int acpi_serdev_do_lookup(struct acpi_device *adev,
INIT_LIST_HEAD(&resource_list);
ret = acpi_dev_get_resources(adev, &resource_list,
acpi_serdev_parse_resource, lookup);
- acpi_dev_free_resource_list(&resource_list);
-
if (ret < 0)
return -EINVAL;
+ acpi_dev_free_resource_list(&resource_list);
+
return 0;
}
diff --git a/drivers/tty/serial/8250/8250.h b/drivers/tty/serial/8250/8250.h
index 77fe0588fd6b..b62f88eec881 100644
--- a/drivers/tty/serial/8250/8250.h
+++ b/drivers/tty/serial/8250/8250.h
@@ -8,6 +8,7 @@
*/
#include <linux/bits.h>
+#include <linux/kconfig.h>
#include <linux/serial_8250.h>
#include <linux/serial_core.h>
#include <linux/dmaengine.h>
@@ -334,6 +335,13 @@ int fintek_8250_probe(struct uart_8250_port *uart);
static inline int fintek_8250_probe(struct uart_8250_port *uart) { return 0; }
#endif
+#if IS_REACHABLE(CONFIG_SERIAL_8250_HUB6)
+bool hub6_match_port(const struct uart_port *port1, const struct uart_port *port2);
+#else
+static inline bool hub6_match_port(const struct uart_port *port1, const struct uart_port *port2)
+{ return false; }
+#endif
+
#ifdef CONFIG_ARCH_OMAP1
#include <linux/soc/ti/omap1-soc.h>
static inline int is_omap1_8250(struct uart_8250_port *pt)
diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c
index f49862d90eeb..c0e8a4efbdcc 100644
--- a/drivers/tty/serial/8250/8250_core.c
+++ b/drivers/tty/serial/8250/8250_core.c
@@ -720,8 +720,12 @@ int serial8250_register_8250_port(const struct uart_8250_port *up)
/* Preserve specified console flow control. */
cons_flow = uart_cons_flow_enabled(&uart->port);
- if (uart->port.dev)
+ if (uart->port.dev) {
+ if (uart_console(&uart->port))
+ uart->port.cons->flags &= ~CON_PRINTBUFFER;
+
uart_remove_one_port(&serial8250_reg, &uart->port);
+ }
uart->port.ctrl_id = up->port.ctrl_id;
uart->port.port_id = up->port.port_id;
diff --git a/drivers/tty/serial/8250/8250_early.c b/drivers/tty/serial/8250/8250_early.c
index dc0371857ecb..44ec209f37c4 100644
--- a/drivers/tty/serial/8250/8250_early.c
+++ b/drivers/tty/serial/8250/8250_early.c
@@ -23,6 +23,7 @@
* console=uart8250,mmio32,0xff5e0000,115200n8
*/
+#include <linux/align.h>
#include <linux/tty.h>
#include <linux/init.h>
#include <linux/console.h>
@@ -177,6 +178,23 @@ OF_EARLYCON_DECLARE(ns16550a, "ns16550a", early_serial8250_setup);
OF_EARLYCON_DECLARE(uart, "nvidia,tegra20-uart", early_serial8250_setup);
OF_EARLYCON_DECLARE(uart, "snps,dw-apb-uart", early_serial8250_setup);
+static int __init early_serial8250_xscale_setup(struct earlycon_device *device,
+ const char *options)
+{
+ /*
+ * Adjust for BE32 register accesses: drop any hardcoded
+ * address for the big endian byte target, add it explicitly
+ * if running on BE32.
+ */
+ device->port.membase = PTR_ALIGN_DOWN(device->port.membase, 4);
+ if (IS_ENABLED(CONFIG_CPU_ENDIAN_BE32))
+ device->port.membase += 3;
+ device->port.regshift = 2;
+
+ return early_serial8250_setup(device, options);
+}
+OF_EARLYCON_DECLARE(uart, "intel,xscale-uart", early_serial8250_xscale_setup);
+
static int __init early_serial8250_rs2_setup(struct earlycon_device *device,
const char *options)
{
@@ -184,7 +202,6 @@ static int __init early_serial8250_rs2_setup(struct earlycon_device *device,
return early_serial8250_setup(device, options);
}
-OF_EARLYCON_DECLARE(uart, "intel,xscale-uart", early_serial8250_rs2_setup);
OF_EARLYCON_DECLARE(uart, "mrvl,mmp-uart", early_serial8250_rs2_setup);
OF_EARLYCON_DECLARE(uart, "mrvl,pxa-uart", early_serial8250_rs2_setup);
diff --git a/drivers/tty/serial/8250/8250_exar.c b/drivers/tty/serial/8250/8250_exar.c
index c682c0d0dffa..f9a14eaa13cb 100644
--- a/drivers/tty/serial/8250/8250_exar.c
+++ b/drivers/tty/serial/8250/8250_exar.c
@@ -1642,14 +1642,14 @@ static const struct exar8250_board pbn_exar_XR17V8358 = {
.exit = pci_xr17v35x_exit,
};
-#define CTI_EXAR_DEVICE(devid, bd) { \
- PCI_DEVICE_SUB( \
- PCI_VENDOR_ID_EXAR, \
- PCI_DEVICE_ID_EXAR_##devid, \
- PCI_SUBVENDOR_ID_CONNECT_TECH, \
- PCI_ANY_ID), 0, 0, \
- (kernel_ulong_t)&bd \
- }
+#define CTI_EXAR_DEVICE(devid, bd) { \
+ PCI_DEVICE_SUB( \
+ PCI_VENDOR_ID_EXAR, \
+ PCI_DEVICE_ID_EXAR_##devid, \
+ PCI_SUBVENDOR_ID_CONNECT_TECH, \
+ PCI_ANY_ID), \
+ .driver_data = (kernel_ulong_t)&bd \
+}
#define EXAR_DEVICE(vend, devid, bd) { PCI_DEVICE_DATA(vend, devid, &bd) }
@@ -1658,18 +1658,18 @@ static const struct exar8250_board pbn_exar_XR17V8358 = {
PCI_VENDOR_ID_EXAR, \
PCI_DEVICE_ID_EXAR_##devid, \
PCI_SUBVENDOR_ID_IBM, \
- PCI_SUBDEVICE_ID_IBM_##sdevid), 0, 0, \
- (kernel_ulong_t)&bd \
- }
+ PCI_SUBDEVICE_ID_IBM_##sdevid), \
+ .driver_data = (kernel_ulong_t)&bd \
+}
#define USR_DEVICE(devid, sdevid, bd) { \
PCI_DEVICE_SUB( \
PCI_VENDOR_ID_USR, \
PCI_DEVICE_ID_EXAR_##devid, \
PCI_VENDOR_ID_EXAR, \
- PCI_SUBDEVICE_ID_USR_##sdevid), 0, 0, \
- (kernel_ulong_t)&bd \
- }
+ PCI_SUBDEVICE_ID_USR_##sdevid), \
+ .driver_data = (kernel_ulong_t)&bd \
+}
static const struct pci_device_id exar_pci_tbl[] = {
EXAR_DEVICE(ACCESSIO, COM_2S, pbn_exar_XR17C15x),
@@ -1726,7 +1726,7 @@ static const struct pci_device_id exar_pci_tbl[] = {
EXAR_DEVICE(COMMTECH, 4224PCI335, pbn_fastcom335_4),
EXAR_DEVICE(COMMTECH, 2324PCI335, pbn_fastcom335_4),
EXAR_DEVICE(COMMTECH, 2328PCI335, pbn_fastcom335_8),
- { 0, }
+ { }
};
MODULE_DEVICE_TABLE(pci, exar_pci_tbl);
diff --git a/drivers/tty/serial/8250/8250_hub6.c b/drivers/tty/serial/8250/8250_hub6.c
index 273f59b9bca5..b6767633c966 100644
--- a/drivers/tty/serial/8250/8250_hub6.c
+++ b/drivers/tty/serial/8250/8250_hub6.c
@@ -7,6 +7,8 @@
#include <linux/init.h>
#include <linux/serial_8250.h>
+#include "8250.h"
+
#define HUB6(card, port) \
{ \
.iobase = 0x302, \
@@ -41,6 +43,12 @@ static struct platform_device hub6_device = {
},
};
+bool hub6_match_port(const struct uart_port *port1, const struct uart_port *port2)
+{
+ return port1->iobase == port2->iobase && port1->hub6 == port2->hub6;
+}
+EXPORT_SYMBOL_GPL(hub6_match_port);
+
static int __init hub6_init(void)
{
return platform_device_register(&hub6_device);
diff --git a/drivers/tty/serial/8250/8250_of.c b/drivers/tty/serial/8250/8250_of.c
index 81644d40b09a..f0537fb6ef4f 100644
--- a/drivers/tty/serial/8250/8250_of.c
+++ b/drivers/tty/serial/8250/8250_of.c
@@ -5,6 +5,7 @@
* Copyright (C) 2006 Arnd Bergmann <arnd@arndb.de>, IBM Corp.
*/
+#include <linux/align.h>
#include <linux/bits.h>
#include <linux/console.h>
#include <linux/math.h>
@@ -122,6 +123,17 @@ static int of_platform_serial_setup(struct platform_device *ofdev,
if (ret)
goto err_pmruntime;
+ if (IS_ENABLED(CONFIG_CPU_XSCALE) && type == PORT_XSCALE) {
+ /*
+ * Adjust for BE32 register accesses: drop any hardcoded
+ * address for the big endian byte target, add it explicitly
+ * if running on BE32.
+ */
+ port->mapbase = PTR_ALIGN_DOWN(port->mapbase, 4);
+ if (IS_ENABLED(CONFIG_CPU_ENDIAN_BE32))
+ port->mapbase += 3;
+ }
+
/* Get clk rate through clk driver if present */
if (!port->uartclk) {
struct clk *bus_clk;
diff --git a/drivers/tty/serial/8250/8250_platform.c b/drivers/tty/serial/8250/8250_platform.c
index ad3a7bc31d6f..af946d12e764 100644
--- a/drivers/tty/serial/8250/8250_platform.c
+++ b/drivers/tty/serial/8250/8250_platform.c
@@ -284,6 +284,7 @@ static struct platform_driver serial8250_isa_driver = {
.driver = {
.name = "serial8250",
.acpi_match_table = acpi_platform_serial_table,
+ .probe_type = PROBE_FORCE_SYNCHRONOUS,
},
};
diff --git a/drivers/tty/serial/8250/8250_pnp.c b/drivers/tty/serial/8250/8250_pnp.c
index 7a837fdf9df1..6bfdeff5fe22 100644
--- a/drivers/tty/serial/8250/8250_pnp.c
+++ b/drivers/tty/serial/8250/8250_pnp.c
@@ -28,351 +28,351 @@
static const struct pnp_device_id pnp_dev_table[] = {
/* Archtek America Corp. */
/* Archtek SmartLink Modem 3334BT Plug & Play */
- { "AAC000F", 0 },
+ { .id = "AAC000F", .driver_data = 0 },
/* Anchor Datacomm BV */
/* SXPro 144 External Data Fax Modem Plug & Play */
- { "ADC0001", 0 },
+ { .id = "ADC0001", .driver_data = 0 },
/* SXPro 288 External Data Fax Modem Plug & Play */
- { "ADC0002", 0 },
+ { .id = "ADC0002", .driver_data = 0 },
/* PROLiNK 1456VH ISA PnP K56flex Fax Modem */
- { "AEI0250", 0 },
+ { .id = "AEI0250", .driver_data = 0 },
/* Actiontec ISA PNP 56K X2 Fax Modem */
- { "AEI1240", 0 },
+ { .id = "AEI1240", .driver_data = 0 },
/* Rockwell 56K ACF II Fax+Data+Voice Modem */
- { "AKY1021", 0 /*SPCI_FL_NO_SHIRQ*/ },
+ { .id ="AKY1021", .driver_data = 0 /*SPCI_FL_NO_SHIRQ*/ },
/*
* ALi Fast Infrared Controller
* Native driver (ali-ircc) is broken so at least
* it can be used with irtty-sir.
*/
- { "ALI5123", 0 },
+ { .id = "ALI5123", .driver_data = 0 },
/* AZT3005 PnP SOUND DEVICE */
- { "AZT4001", 0 },
+ { .id = "AZT4001", .driver_data = 0 },
/* Best Data Products Inc. Smart One 336F PnP Modem */
- { "BDP3336", 0 },
+ { .id = "BDP3336", .driver_data = 0 },
/* Boca Research */
/* Boca Complete Ofc Communicator 14.4 Data-FAX */
- { "BRI0A49", 0 },
+ { .id = "BRI0A49", .driver_data = 0 },
/* Boca Research 33,600 ACF Modem */
- { "BRI1400", 0 },
+ { .id = "BRI1400", .driver_data = 0 },
/* Boca 33.6 Kbps Internal FD34FSVD */
- { "BRI3400", 0 },
+ { .id = "BRI3400", .driver_data = 0 },
/* Computer Peripherals Inc */
/* EuroViVa CommCenter-33.6 SP PnP */
- { "CPI4050", 0 },
+ { .id = "CPI4050", .driver_data = 0 },
/* Creative Labs */
/* Creative Labs Phone Blaster 28.8 DSVD PnP Voice */
- { "CTL3001", 0 },
+ { .id = "CTL3001", .driver_data = 0 },
/* Creative Labs Modem Blaster 28.8 DSVD PnP Voice */
- { "CTL3011", 0 },
+ { .id = "CTL3011", .driver_data = 0 },
/* Davicom ISA 33.6K Modem */
- { "DAV0336", 0 },
+ { .id = "DAV0336", .driver_data = 0 },
/* Creative */
/* Creative Modem Blaster Flash56 DI5601-1 */
- { "DMB1032", 0 },
+ { .id = "DMB1032", .driver_data = 0 },
/* Creative Modem Blaster V.90 DI5660 */
- { "DMB2001", 0 },
+ { .id = "DMB2001", .driver_data = 0 },
/* E-Tech */
/* E-Tech CyberBULLET PC56RVP */
- { "ETT0002", 0 },
+ { .id = "ETT0002", .driver_data = 0 },
/* FUJITSU */
/* Fujitsu 33600 PnP-I2 R Plug & Play */
- { "FUJ0202", 0 },
+ { .id = "FUJ0202", .driver_data = 0 },
/* Fujitsu FMV-FX431 Plug & Play */
- { "FUJ0205", 0 },
+ { .id = "FUJ0205", .driver_data = 0 },
/* Fujitsu 33600 PnP-I4 R Plug & Play */
- { "FUJ0206", 0 },
+ { .id = "FUJ0206", .driver_data = 0 },
/* Fujitsu Fax Voice 33600 PNP-I5 R Plug & Play */
- { "FUJ0209", 0 },
+ { .id = "FUJ0209", .driver_data = 0 },
/* Archtek America Corp. */
/* Archtek SmartLink Modem 3334BT Plug & Play */
- { "GVC000F", 0 },
+ { .id = "GVC000F", .driver_data = 0 },
/* Archtek SmartLink Modem 3334BRV 33.6K Data Fax Voice */
- { "GVC0303", 0 },
+ { .id = "GVC0303", .driver_data = 0 },
/* Hayes */
/* Hayes Optima 288 V.34-V.FC + FAX + Voice Plug & Play */
- { "HAY0001", 0 },
+ { .id = "HAY0001", .driver_data = 0 },
/* Hayes Optima 336 V.34 + FAX + Voice PnP */
- { "HAY000C", 0 },
+ { .id = "HAY000C", .driver_data = 0 },
/* Hayes Optima 336B V.34 + FAX + Voice PnP */
- { "HAY000D", 0 },
+ { .id = "HAY000D", .driver_data = 0 },
/* Hayes Accura 56K Ext Fax Modem PnP */
- { "HAY5670", 0 },
+ { .id = "HAY5670", .driver_data = 0 },
/* Hayes Accura 56K Ext Fax Modem PnP */
- { "HAY5674", 0 },
+ { .id = "HAY5674", .driver_data = 0 },
/* Hayes Accura 56K Fax Modem PnP */
- { "HAY5675", 0 },
+ { .id = "HAY5675", .driver_data = 0 },
/* Hayes 288, V.34 + FAX */
- { "HAYF000", 0 },
+ { .id = "HAYF000", .driver_data = 0 },
/* Hayes Optima 288 V.34 + FAX + Voice, Plug & Play */
- { "HAYF001", 0 },
+ { .id = "HAYF001", .driver_data = 0 },
/* IBM */
/* IBM Thinkpad 701 Internal Modem Voice */
- { "IBM0033", 0 },
+ { .id = "IBM0033", .driver_data = 0 },
/* Intermec */
/* Intermec CV60 touchscreen port */
- { "PNP4972", 0 },
+ { .id = "PNP4972", .driver_data = 0 },
/* Intertex */
/* Intertex 28k8 33k6 Voice EXT PnP */
- { "IXDC801", 0 },
+ { .id = "IXDC801", .driver_data = 0 },
/* Intertex 33k6 56k Voice EXT PnP */
- { "IXDC901", 0 },
+ { .id = "IXDC901", .driver_data = 0 },
/* Intertex 28k8 33k6 Voice SP EXT PnP */
- { "IXDD801", 0 },
+ { .id = "IXDD801", .driver_data = 0 },
/* Intertex 33k6 56k Voice SP EXT PnP */
- { "IXDD901", 0 },
+ { .id = "IXDD901", .driver_data = 0 },
/* Intertex 28k8 33k6 Voice SP INT PnP */
- { "IXDF401", 0 },
+ { .id = "IXDF401", .driver_data = 0 },
/* Intertex 28k8 33k6 Voice SP EXT PnP */
- { "IXDF801", 0 },
+ { .id = "IXDF801", .driver_data = 0 },
/* Intertex 33k6 56k Voice SP EXT PnP */
- { "IXDF901", 0 },
+ { .id = "IXDF901", .driver_data = 0 },
/* Kortex International */
/* KORTEX 28800 Externe PnP */
- { "KOR4522", 0 },
+ { .id = "KOR4522", .driver_data = 0 },
/* KXPro 33.6 Vocal ASVD PnP */
- { "KORF661", 0 },
+ { .id = "KORF661", .driver_data = 0 },
/* Lasat */
/* LASAT Internet 33600 PnP */
- { "LAS4040", 0 },
+ { .id = "LAS4040", .driver_data = 0 },
/* Lasat Safire 560 PnP */
- { "LAS4540", 0 },
+ { .id = "LAS4540", .driver_data = 0 },
/* Lasat Safire 336 PnP */
- { "LAS5440", 0 },
+ { .id = "LAS5440", .driver_data = 0 },
/* Microcom, Inc. */
/* Microcom TravelPorte FAST V.34 Plug & Play */
- { "MNP0281", 0 },
+ { .id = "MNP0281", .driver_data = 0 },
/* Microcom DeskPorte V.34 FAST or FAST+ Plug & Play */
- { "MNP0336", 0 },
+ { .id = "MNP0336", .driver_data = 0 },
/* Microcom DeskPorte FAST EP 28.8 Plug & Play */
- { "MNP0339", 0 },
+ { .id = "MNP0339", .driver_data = 0 },
/* Microcom DeskPorte 28.8P Plug & Play */
- { "MNP0342", 0 },
+ { .id = "MNP0342", .driver_data = 0 },
/* Microcom DeskPorte FAST ES 28.8 Plug & Play */
- { "MNP0500", 0 },
+ { .id = "MNP0500", .driver_data = 0 },
/* Microcom DeskPorte FAST ES 28.8 Plug & Play */
- { "MNP0501", 0 },
+ { .id = "MNP0501", .driver_data = 0 },
/* Microcom DeskPorte 28.8S Internal Plug & Play */
- { "MNP0502", 0 },
+ { .id = "MNP0502", .driver_data = 0 },
/* Motorola */
/* Motorola BitSURFR Plug & Play */
- { "MOT1105", 0 },
+ { .id = "MOT1105", .driver_data = 0 },
/* Motorola TA210 Plug & Play */
- { "MOT1111", 0 },
+ { .id = "MOT1111", .driver_data = 0 },
/* Motorola HMTA 200 (ISDN) Plug & Play */
- { "MOT1114", 0 },
+ { .id = "MOT1114", .driver_data = 0 },
/* Motorola BitSURFR Plug & Play */
- { "MOT1115", 0 },
+ { .id = "MOT1115", .driver_data = 0 },
/* Motorola Lifestyle 28.8 Internal */
- { "MOT1190", 0 },
+ { .id = "MOT1190", .driver_data = 0 },
/* Motorola V.3400 Plug & Play */
- { "MOT1501", 0 },
+ { .id = "MOT1501", .driver_data = 0 },
/* Motorola Lifestyle 28.8 V.34 Plug & Play */
- { "MOT1502", 0 },
+ { .id = "MOT1502", .driver_data = 0 },
/* Motorola Power 28.8 V.34 Plug & Play */
- { "MOT1505", 0 },
+ { .id = "MOT1505", .driver_data = 0 },
/* Motorola ModemSURFR External 28.8 Plug & Play */
- { "MOT1509", 0 },
+ { .id = "MOT1509", .driver_data = 0 },
/* Motorola Premier 33.6 Desktop Plug & Play */
- { "MOT150A", 0 },
+ { .id = "MOT150A", .driver_data = 0 },
/* Motorola VoiceSURFR 56K External PnP */
- { "MOT150F", 0 },
+ { .id = "MOT150F", .driver_data = 0 },
/* Motorola ModemSURFR 56K External PnP */
- { "MOT1510", 0 },
+ { .id = "MOT1510", .driver_data = 0 },
/* Motorola ModemSURFR 56K Internal PnP */
- { "MOT1550", 0 },
+ { .id = "MOT1550", .driver_data = 0 },
/* Motorola ModemSURFR Internal 28.8 Plug & Play */
- { "MOT1560", 0 },
+ { .id = "MOT1560", .driver_data = 0 },
/* Motorola Premier 33.6 Internal Plug & Play */
- { "MOT1580", 0 },
+ { .id = "MOT1580", .driver_data = 0 },
/* Motorola OnlineSURFR 28.8 Internal Plug & Play */
- { "MOT15B0", 0 },
+ { .id = "MOT15B0", .driver_data = 0 },
/* Motorola VoiceSURFR 56K Internal PnP */
- { "MOT15F0", 0 },
+ { .id = "MOT15F0", .driver_data = 0 },
/* Com 1 */
/* Deskline K56 Phone System PnP */
- { "MVX00A1", 0 },
+ { .id = "MVX00A1", .driver_data = 0 },
/* PC Rider K56 Phone System PnP */
- { "MVX00F2", 0 },
+ { .id = "MVX00F2", .driver_data = 0 },
/* NEC 98NOTE SPEAKER PHONE FAX MODEM(33600bps) */
- { "nEC8241", 0 },
+ { .id = "nEC8241", .driver_data = 0 },
/* Pace 56 Voice Internal Plug & Play Modem */
- { "PMC2430", 0 },
+ { .id = "PMC2430", .driver_data = 0 },
/* Generic */
/* Generic standard PC COM port */
- { "PNP0500", 0 },
+ { .id = "PNP0500", .driver_data = 0 },
/* Generic 16550A-compatible COM port */
- { "PNP0501", 0 },
+ { .id = "PNP0501", .driver_data = 0 },
/* Compaq 14400 Modem */
- { "PNPC000", 0 },
+ { .id = "PNPC000", .driver_data = 0 },
/* Compaq 2400/9600 Modem */
- { "PNPC001", 0 },
+ { .id = "PNPC001", .driver_data = 0 },
/* Dial-Up Networking Serial Cable between 2 PCs */
- { "PNPC031", 0 },
+ { .id = "PNPC031", .driver_data = 0 },
/* Dial-Up Networking Parallel Cable between 2 PCs */
- { "PNPC032", 0 },
+ { .id = "PNPC032", .driver_data = 0 },
/* Standard 9600 bps Modem */
- { "PNPC100", 0 },
+ { .id = "PNPC100", .driver_data = 0 },
/* Standard 14400 bps Modem */
- { "PNPC101", 0 },
+ { .id = "PNPC101", .driver_data = 0 },
/* Standard 28800 bps Modem*/
- { "PNPC102", 0 },
+ { .id = "PNPC102", .driver_data = 0 },
/* Standard Modem*/
- { "PNPC103", 0 },
+ { .id = "PNPC103", .driver_data = 0 },
/* Standard 9600 bps Modem*/
- { "PNPC104", 0 },
+ { .id = "PNPC104", .driver_data = 0 },
/* Standard 14400 bps Modem*/
- { "PNPC105", 0 },
+ { .id = "PNPC105", .driver_data = 0 },
/* Standard 28800 bps Modem*/
- { "PNPC106", 0 },
+ { .id = "PNPC106", .driver_data = 0 },
/* Standard Modem */
- { "PNPC107", 0 },
+ { .id = "PNPC107", .driver_data = 0 },
/* Standard 9600 bps Modem */
- { "PNPC108", 0 },
+ { .id = "PNPC108", .driver_data = 0 },
/* Standard 14400 bps Modem */
- { "PNPC109", 0 },
+ { .id = "PNPC109", .driver_data = 0 },
/* Standard 28800 bps Modem */
- { "PNPC10A", 0 },
+ { .id = "PNPC10A", .driver_data = 0 },
/* Standard Modem */
- { "PNPC10B", 0 },
+ { .id = "PNPC10B", .driver_data = 0 },
/* Standard 9600 bps Modem */
- { "PNPC10C", 0 },
+ { .id = "PNPC10C", .driver_data = 0 },
/* Standard 14400 bps Modem */
- { "PNPC10D", 0 },
+ { .id = "PNPC10D", .driver_data = 0 },
/* Standard 28800 bps Modem */
- { "PNPC10E", 0 },
+ { .id = "PNPC10E", .driver_data = 0 },
/* Standard Modem */
- { "PNPC10F", 0 },
+ { .id = "PNPC10F", .driver_data = 0 },
/* Standard PCMCIA Card Modem */
- { "PNP2000", 0 },
+ { .id = "PNP2000", .driver_data = 0 },
/* Rockwell */
/* Modular Technology */
/* Rockwell 33.6 DPF Internal PnP */
/* Modular Technology 33.6 Internal PnP */
- { "ROK0030", 0 },
+ { .id = "ROK0030", .driver_data = 0 },
/* Kortex International */
/* KORTEX 14400 Externe PnP */
- { "ROK0100", 0 },
+ { .id = "ROK0100", .driver_data = 0 },
/* Rockwell 28.8 */
- { "ROK4120", 0 },
+ { .id = "ROK4120", .driver_data = 0 },
/* Viking Components, Inc */
/* Viking 28.8 INTERNAL Fax+Data+Voice PnP */
- { "ROK4920", 0 },
+ { .id = "ROK4920", .driver_data = 0 },
/* Rockwell */
/* British Telecom */
/* Modular Technology */
/* Rockwell 33.6 DPF External PnP */
/* BT Prologue 33.6 External PnP */
/* Modular Technology 33.6 External PnP */
- { "RSS00A0", 0 },
+ { .id = "RSS00A0", .driver_data = 0 },
/* Viking 56K FAX INT */
- { "RSS0262", 0 },
+ { .id = "RSS0262", .driver_data = 0 },
/* K56 par,VV,Voice,Speakphone,AudioSpan,PnP */
- { "RSS0250", 0 },
+ { .id = "RSS0250", .driver_data = 0 },
/* SupraExpress 28.8 Data/Fax PnP modem */
- { "SUP1310", 0 },
+ { .id = "SUP1310", .driver_data = 0 },
/* SupraExpress 336i PnP Voice Modem */
- { "SUP1381", 0 },
+ { .id = "SUP1381", .driver_data = 0 },
/* SupraExpress 33.6 Data/Fax PnP modem */
- { "SUP1421", 0 },
+ { .id = "SUP1421", .driver_data = 0 },
/* SupraExpress 33.6 Data/Fax PnP modem */
- { "SUP1590", 0 },
+ { .id = "SUP1590", .driver_data = 0 },
/* SupraExpress 336i Sp ASVD */
- { "SUP1620", 0 },
+ { .id = "SUP1620", .driver_data = 0 },
/* SupraExpress 33.6 Data/Fax PnP modem */
- { "SUP1760", 0 },
+ { .id = "SUP1760", .driver_data = 0 },
/* SupraExpress 56i Sp Intl */
- { "SUP2171", 0 },
+ { .id = "SUP2171", .driver_data = 0 },
/* Phoebe Micro */
/* Phoebe Micro 33.6 Data Fax 1433VQH Plug & Play */
- { "TEX0011", 0 },
+ { .id = "TEX0011", .driver_data = 0 },
/* Archtek America Corp. */
/* Archtek SmartLink Modem 3334BT Plug & Play */
- { "UAC000F", 0 },
+ { .id = "UAC000F", .driver_data = 0 },
/* 3Com Corp. */
/* Gateway Telepath IIvi 33.6 */
- { "USR0000", 0 },
+ { .id = "USR0000", .driver_data = 0 },
/* U.S. Robotics Sporster 33.6K Fax INT PnP */
- { "USR0002", 0 },
+ { .id = "USR0002", .driver_data = 0 },
/* Sportster Vi 14.4 PnP FAX Voicemail */
- { "USR0004", 0 },
+ { .id = "USR0004", .driver_data = 0 },
/* U.S. Robotics 33.6K Voice INT PnP */
- { "USR0006", 0 },
+ { .id = "USR0006", .driver_data = 0 },
/* U.S. Robotics 33.6K Voice EXT PnP */
- { "USR0007", 0 },
+ { .id = "USR0007", .driver_data = 0 },
/* U.S. Robotics Courier V.Everything INT PnP */
- { "USR0009", 0 },
+ { .id = "USR0009", .driver_data = 0 },
/* U.S. Robotics 33.6K Voice INT PnP */
- { "USR2002", 0 },
+ { .id = "USR2002", .driver_data = 0 },
/* U.S. Robotics 56K Voice INT PnP */
- { "USR2070", 0 },
+ { .id = "USR2070", .driver_data = 0 },
/* U.S. Robotics 56K Voice EXT PnP */
- { "USR2080", 0 },
+ { .id = "USR2080", .driver_data = 0 },
/* U.S. Robotics 56K FAX INT */
- { "USR3031", 0 },
+ { .id = "USR3031", .driver_data = 0 },
/* U.S. Robotics 56K FAX INT */
- { "USR3050", 0 },
+ { .id = "USR3050", .driver_data = 0 },
/* U.S. Robotics 56K Voice INT PnP */
- { "USR3070", 0 },
+ { .id = "USR3070", .driver_data = 0 },
/* U.S. Robotics 56K Voice EXT PnP */
- { "USR3080", 0 },
+ { .id = "USR3080", .driver_data = 0 },
/* U.S. Robotics 56K Voice INT PnP */
- { "USR3090", 0 },
+ { .id = "USR3090", .driver_data = 0 },
/* U.S. Robotics 56K Message */
- { "USR9100", 0 },
+ { .id = "USR9100", .driver_data = 0 },
/* U.S. Robotics 56K FAX EXT PnP*/
- { "USR9160", 0 },
+ { .id = "USR9160", .driver_data = 0 },
/* U.S. Robotics 56K FAX INT PnP*/
- { "USR9170", 0 },
+ { .id = "USR9170", .driver_data = 0 },
/* U.S. Robotics 56K Voice EXT PnP*/
- { "USR9180", 0 },
+ { .id = "USR9180", .driver_data = 0 },
/* U.S. Robotics 56K Voice INT PnP*/
- { "USR9190", 0 },
+ { .id = "USR9190", .driver_data = 0 },
/* Wacom tablets */
- { "WACFXXX", 0 },
+ { .id = "WACFXXX", .driver_data = 0 },
/* Compaq touchscreen */
- { "FPI2002", 0 },
+ { .id = "FPI2002", .driver_data = 0 },
/* Fujitsu Stylistic touchscreens */
- { "FUJ02B2", 0 },
- { "FUJ02B3", 0 },
+ { .id = "FUJ02B2", .driver_data = 0 },
+ { .id = "FUJ02B3", .driver_data = 0 },
/* Fujitsu Stylistic LT touchscreens */
- { "FUJ02B4", 0 },
+ { .id = "FUJ02B4", .driver_data = 0 },
/* Passive Fujitsu Stylistic touchscreens */
- { "FUJ02B6", 0 },
- { "FUJ02B7", 0 },
- { "FUJ02B8", 0 },
- { "FUJ02B9", 0 },
- { "FUJ02BC", 0 },
+ { .id = "FUJ02B6", .driver_data = 0 },
+ { .id = "FUJ02B7", .driver_data = 0 },
+ { .id = "FUJ02B8", .driver_data = 0 },
+ { .id = "FUJ02B9", .driver_data = 0 },
+ { .id = "FUJ02BC", .driver_data = 0 },
/* Fujitsu Wacom Tablet PC device */
- { "FUJ02E5", 0 },
+ { .id = "FUJ02E5", .driver_data = 0 },
/* Fujitsu P-series tablet PC device */
- { "FUJ02E6", 0 },
+ { .id = "FUJ02E6", .driver_data = 0 },
/* Fujitsu Wacom 2FGT Tablet PC device */
- { "FUJ02E7", 0 },
+ { .id = "FUJ02E7", .driver_data = 0 },
/* Fujitsu Wacom 1FGT Tablet PC device */
- { "FUJ02E9", 0 },
+ { .id = "FUJ02E9", .driver_data = 0 },
/*
* LG C1 EXPRESS DUAL (C1-PB11A3) touch screen (actually a FUJ02E6
* in disguise).
*/
- { "LTS0001", 0 },
+ { .id = "LTS0001", .driver_data = 0 },
/* Rockwell's (PORALiNK) 33600 INT PNP */
- { "WCI0003", 0 },
+ { .id = "WCI0003", .driver_data = 0 },
/* Unknown PnP modems */
- { "PNPCXXX", UNKNOWN_DEV },
+ { .id = "PNPCXXX", .driver_data = UNKNOWN_DEV },
/* More unknown PnP modems */
- { "PNPDXXX", UNKNOWN_DEV },
+ { .id = "PNPDXXX", .driver_data = UNKNOWN_DEV },
/*
* Winbond CIR port, should not be probed. We should keep track of
* it to prevent the legacy serial driver from probing it.
*/
- { "WEC1022", CIR_PORT },
+ { .id = "WEC1022", .driver_data = CIR_PORT },
/*
* SMSC IrCC SIR/FIR port, should not be probed by serial driver as
* well so its own driver can bind to it.
*/
- { "SMCF010", CIR_PORT },
- { "", 0 }
+ { .id = "SMCF010", .driver_data = CIR_PORT },
+ { }
};
MODULE_DEVICE_TABLE(pnp, pnp_dev_table);
@@ -521,6 +521,7 @@ static struct pnp_driver serial_pnp_driver = {
.remove = serial_pnp_remove,
.driver = {
.pm = pm_sleep_ptr(&serial_pnp_pm_ops),
+ .probe_type = PROBE_FORCE_SYNCHRONOUS,
},
.id_table = pnp_dev_table,
};
diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c
index e94a0802cbdd..8c241ec7f4f2 100644
--- a/drivers/tty/serial/8250/8250_port.c
+++ b/drivers/tty/serial/8250/8250_port.c
@@ -474,16 +474,10 @@ static void set_io_from_upio(struct uart_port *p)
static void
serial_port_out_sync(struct uart_port *p, int offset, int value)
{
- switch (p->iotype) {
- case UPIO_MEM:
- case UPIO_MEM16:
- case UPIO_MEM32:
- case UPIO_MEM32BE:
- case UPIO_AU:
+ if (uart_iotype_mmio(p->iotype)) {
p->serial_out(p, offset, value);
p->serial_in(p, UART_LCR); /* safe, no side-effects */
- break;
- default:
+ } else {
p->serial_out(p, offset, value);
}
}
@@ -2891,13 +2885,7 @@ static int serial8250_request_std_resource(struct uart_8250_port *up)
unsigned int size = serial8250_port_size(up);
struct uart_port *port = &up->port;
- switch (port->iotype) {
- case UPIO_AU:
- case UPIO_TSI:
- case UPIO_MEM32:
- case UPIO_MEM32BE:
- case UPIO_MEM16:
- case UPIO_MEM:
+ if (uart_iotype_mmio(port->iotype)) {
if (!port->mapbase)
return -EINVAL;
@@ -2911,14 +2899,9 @@ static int serial8250_request_std_resource(struct uart_8250_port *up)
return -ENOMEM;
}
}
- return 0;
- case UPIO_HUB6:
- case UPIO_PORT:
+ } else if (uart_iotype_io(port->iotype)) {
if (!request_region(port->iobase, size, "serial"))
return -EBUSY;
- return 0;
- case UPIO_UNKNOWN:
- break;
}
return 0;
@@ -2929,15 +2912,9 @@ static void serial8250_release_std_resource(struct uart_8250_port *up)
unsigned int size = serial8250_port_size(up);
struct uart_port *port = &up->port;
- switch (port->iotype) {
- case UPIO_AU:
- case UPIO_TSI:
- case UPIO_MEM32:
- case UPIO_MEM32BE:
- case UPIO_MEM16:
- case UPIO_MEM:
+ if (uart_iotype_mmio(port->iotype)) {
if (!port->mapbase)
- break;
+ return;
if (port->flags & UPF_IOREMAP) {
iounmap(port->membase);
@@ -2945,14 +2922,8 @@ static void serial8250_release_std_resource(struct uart_8250_port *up)
}
release_mem_region(port->mapbase, size);
- break;
-
- case UPIO_HUB6:
- case UPIO_PORT:
+ } else if (uart_iotype_io(port->iotype)) {
release_region(port->iobase, size);
- break;
- case UPIO_UNKNOWN:
- break;
}
}
diff --git a/drivers/tty/serial/8250/8250_rsa.c b/drivers/tty/serial/8250/8250_rsa.c
index fff9395948e3..da971437e89c 100644
--- a/drivers/tty/serial/8250/8250_rsa.c
+++ b/drivers/tty/serial/8250/8250_rsa.c
@@ -19,35 +19,33 @@ static const struct uart_ops *core_port_base_ops;
static int rsa8250_request_resource(struct uart_8250_port *up)
{
struct uart_port *port = &up->port;
- unsigned long start = UART_RSA_BASE << port->regshift;
- unsigned int size = 8 << port->regshift;
-
- switch (port->iotype) {
- case UPIO_HUB6:
- case UPIO_PORT:
- start += port->iobase;
- if (!request_region(start, size, "serial-rsa"))
- return -EBUSY;
- return 0;
- default:
+ unsigned long start;
+ unsigned int size;
+
+ if (!uart_iotype_io(port->iotype))
return -EINVAL;
- }
+
+ start = UART_RSA_BASE << port->regshift;
+ start += port->iobase;
+ size = 8 << port->regshift;
+
+ if (!request_region(start, size, "serial-rsa"))
+ return -EBUSY;
+ return 0;
}
static void rsa8250_release_resource(struct uart_8250_port *up)
{
struct uart_port *port = &up->port;
- unsigned long offset = UART_RSA_BASE << port->regshift;
- unsigned int size = 8 << port->regshift;
-
- switch (port->iotype) {
- case UPIO_HUB6:
- case UPIO_PORT:
- release_region(port->iobase + offset, size);
- break;
- default:
- break;
- }
+ unsigned long offset;
+ unsigned int size;
+
+ if (!uart_iotype_io(port->iotype))
+ return;
+
+ offset = UART_RSA_BASE << port->regshift;
+ size = 8 << port->regshift;
+ release_region(port->iobase + offset, size);
}
static void univ8250_config_port(struct uart_port *port, int flags)
diff --git a/drivers/tty/serial/cpm_uart.c b/drivers/tty/serial/cpm_uart.c
index b778a20ec9b1..39f54bb7b485 100644
--- a/drivers/tty/serial/cpm_uart.c
+++ b/drivers/tty/serial/cpm_uart.c
@@ -27,7 +27,6 @@
#include <linux/memblock.h>
#include <linux/dma-mapping.h>
#include <linux/of_address.h>
-#include <linux/of_irq.h>
#include <linux/of_platform.h>
#include <linux/gpio/consumer.h>
#include <linux/clk.h>
@@ -1530,16 +1529,14 @@ static int cpm_uart_probe(struct platform_device *ofdev)
/* initialize the device pointer for the port */
pinfo->port.dev = &ofdev->dev;
- pinfo->port.irq = irq_of_parse_and_map(ofdev->dev.of_node, 0);
- if (!pinfo->port.irq)
- return -EINVAL;
+ pinfo->port.irq = platform_get_irq(ofdev, 0);
+ if (pinfo->port.irq < 0)
+ return pinfo->port.irq;
ret = cpm_uart_init_port(ofdev->dev.of_node, pinfo);
if (!ret)
return uart_add_one_port(&cpm_reg, &pinfo->port);
- irq_dispose_mapping(pinfo->port.irq);
-
return ret;
}
diff --git a/drivers/tty/serial/earlycon.c b/drivers/tty/serial/earlycon.c
index ab9af37f6cda..ce740cdc7ceb 100644
--- a/drivers/tty/serial/earlycon.c
+++ b/drivers/tty/serial/earlycon.c
@@ -75,19 +75,12 @@ static void __init earlycon_print_info(struct earlycon_device *device)
{
struct console *earlycon = device->con;
struct uart_port *port = &device->port;
+ char ioinfos[64];
- if (port->iotype == UPIO_MEM || port->iotype == UPIO_MEM16 ||
- port->iotype == UPIO_MEM32 || port->iotype == UPIO_MEM32BE)
- pr_info("%s%d at MMIO%s %pa (options '%s')\n",
- earlycon->name, earlycon->index,
- (port->iotype == UPIO_MEM) ? "" :
- (port->iotype == UPIO_MEM16) ? "16" :
- (port->iotype == UPIO_MEM32) ? "32" : "32be",
- &port->mapbase, device->options);
- else
- pr_info("%s%d at I/O port 0x%lx (options '%s')\n",
- earlycon->name, earlycon->index,
- port->iobase, device->options);
+ uart_get_ioinfos(port, ioinfos, sizeof(ioinfos));
+
+ pr_info("%s%d%s (options '%s')\n", earlycon->name, earlycon->index,
+ ioinfos, device->options);
}
static int __init parse_options(struct earlycon_device *device, char *options)
diff --git a/drivers/tty/serial/kgdboc.c b/drivers/tty/serial/kgdboc.c
index 5a955c80a853..09648d643897 100644
--- a/drivers/tty/serial/kgdboc.c
+++ b/drivers/tty/serial/kgdboc.c
@@ -363,7 +363,7 @@ static int param_set_kgdboc_var(const char *kmessage,
mutex_lock(&config_mutex);
- strcpy(config, kmessage);
+ strscpy(config, kmessage);
/* Chop out \n char as a result of echo */
if (len && config[len - 1] == '\n')
config[len - 1] = '\0';
diff --git a/drivers/tty/serial/ma35d1_serial.c b/drivers/tty/serial/ma35d1_serial.c
index 285b0fe41a86..920fe7ff5083 100644
--- a/drivers/tty/serial/ma35d1_serial.c
+++ b/drivers/tty/serial/ma35d1_serial.c
@@ -608,8 +608,14 @@ static int __init ma35d1serial_console_setup(struct console *co, char *options)
if (!np || !p)
return -ENODEV;
- if (of_property_read_u32_array(np, "reg", val32, ARRAY_SIZE(val32)) != 0)
+ if (of_property_read_u32_array(np, "reg", val32, ARRAY_SIZE(val32)) != 0) {
+ of_node_put(np);
+ ma35d1serial_uart_nodes[co->index] = NULL;
return -EINVAL;
+ }
+
+ of_node_put(np);
+ ma35d1serial_uart_nodes[co->index] = NULL;
p->port.iobase = val32[1];
p->port.membase = ioremap(p->port.iobase, MA35_UART_REG_SIZE);
@@ -648,8 +654,10 @@ static void ma35d1serial_console_init_port(void)
of_node_get(np);
ma35d1serial_uart_nodes[i] = np;
i++;
- if (i == MA35_UART_NR)
+ if (i == MA35_UART_NR) {
+ of_node_put(np);
break;
+ }
}
}
}
diff --git a/drivers/tty/serial/max3100.c b/drivers/tty/serial/max3100.c
index 44b745fa26c6..a5a5cd68f696 100644
--- a/drivers/tty/serial/max3100.c
+++ b/drivers/tty/serial/max3100.c
@@ -724,6 +724,7 @@ static int max3100_probe(struct spi_device *spi)
max3100s[i]->port.ops = &max3100_ops;
max3100s[i]->port.flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF;
max3100s[i]->port.line = i;
+ max3100s[i]->port.iotype = UPIO_BUS;
max3100s[i]->port.type = PORT_MAX3100;
max3100s[i]->port.dev = &spi->dev;
diff --git a/drivers/tty/serial/max310x.c b/drivers/tty/serial/max310x.c
index 5fe12577ce8b..41a7bff941c1 100644
--- a/drivers/tty/serial/max310x.c
+++ b/drivers/tty/serial/max310x.c
@@ -1400,30 +1400,18 @@ static int max310x_probe(struct device *dev, const struct max310x_devtype *devty
dev_dbg(dev, "Reference clock set to %i Hz\n", uartclk);
+ /*
+ * Set up each port's state before registering the gpiochip,
+ * since the gpiochip callbacks will read s->p[i].regmap as
+ * soon as gpiolib exposes the controller.
+ */
for (i = 0; i < devtype->nr; i++) {
- unsigned int line;
-
- line = find_first_zero_bit(max310x_lines, MAX310X_UART_NRMAX);
- if (line == MAX310X_UART_NRMAX) {
- ret = -ERANGE;
- goto out_uart;
- }
-
- /* Initialize port data */
- s->p[i].port.line = line;
s->p[i].port.dev = dev;
s->p[i].port.irq = irq;
s->p[i].port.type = PORT_MAX310X;
s->p[i].port.fifosize = MAX310X_FIFO_SIZE;
s->p[i].port.flags = UPF_FIXED_TYPE | UPF_LOW_LATENCY;
- s->p[i].port.iotype = UPIO_PORT;
- s->p[i].port.iobase = i;
- /*
- * Use all ones as membase to make sure uart_configure_port() in
- * serial_core.c does not abort for SPI/I2C devices where the
- * membase address is not applicable.
- */
- s->p[i].port.membase = (void __iomem *)~0;
+ s->p[i].port.iotype = UPIO_BUS;
s->p[i].port.uartclk = uartclk;
s->p[i].port.rs485_config = max310x_rs485_config;
s->p[i].port.rs485_supported = max310x_rs485_supported;
@@ -1440,20 +1428,16 @@ static int max310x_probe(struct device *dev, const struct max310x_devtype *devty
INIT_WORK(&s->p[i].md_work, max310x_md_proc);
/* Initialize queue for changing RS485 mode */
INIT_WORK(&s->p[i].rs_work, max310x_rs_proc);
-
- /* Register port */
- ret = uart_add_one_port(&max310x_uart, &s->p[i].port);
- if (ret)
- goto out_uart;
-
- set_bit(line, max310x_lines);
-
- /* Go to suspend mode */
- max310x_power(&s->p[i].port, 0);
}
#ifdef CONFIG_GPIOLIB
- /* Setup GPIO controller */
+ /*
+ * Register the GPIO controller before adding the UART ports so
+ * that consumers referencing the chip's own GPIOs from device
+ * tree (for example rs485-term-gpios = <&max310x ...>) can
+ * resolve them at uart_add_one_port() time instead of receiving
+ * -EPROBE_DEFER from their own provider.
+ */
s->gpio.owner = THIS_MODULE;
s->gpio.parent = dev;
s->gpio.label = devtype->name;
@@ -1471,6 +1455,64 @@ static int max310x_probe(struct device *dev, const struct max310x_devtype *devty
goto out_uart;
#endif
+ for (i = 0; i < devtype->nr; i++) {
+ struct fwnode_handle *saved_fwnode = dev_fwnode(dev);
+ struct device_node *port_np = NULL;
+ struct device_node *child;
+ unsigned int line;
+
+ line = find_first_zero_bit(max310x_lines, MAX310X_UART_NRMAX);
+ if (line == MAX310X_UART_NRMAX) {
+ ret = -ERANGE;
+ goto out_uart;
+ }
+ s->p[i].port.line = line;
+
+ /* Locate the matching "serial@i" DT subnode, if any. */
+ for_each_available_child_of_node(dev->of_node, child) {
+ u32 reg;
+
+ if (!of_node_name_eq(child, "serial"))
+ continue;
+ if (of_property_read_u32(child, "reg", &reg))
+ continue;
+ if (reg == i) {
+ port_np = child;
+ break;
+ }
+ }
+
+ /*
+ * Temporarily retarget dev's fwnode to the per-port subnode
+ * so uart_get_rs485_mode() picks up the per-port properties.
+ * For single-port variants, fall back to the chip's own
+ * fwnode so legacy DTs that declare rs485 properties at the
+ * top level keep working.
+ */
+ if (port_np) {
+ device_set_node(dev, of_fwnode_handle(port_np));
+ ret = uart_get_rs485_mode(&s->p[i].port);
+ device_set_node(dev, saved_fwnode);
+ of_node_put(port_np);
+ if (ret)
+ goto out_uart;
+ } else if (devtype->nr == 1) {
+ ret = uart_get_rs485_mode(&s->p[i].port);
+ if (ret)
+ goto out_uart;
+ }
+
+ /* Register port */
+ ret = uart_add_one_port(&max310x_uart, &s->p[i].port);
+ if (ret)
+ goto out_uart;
+
+ set_bit(line, max310x_lines);
+
+ /* Go to suspend mode */
+ max310x_power(&s->p[i].port, 0);
+ }
+
/* Setup interrupt */
ret = devm_request_threaded_irq(dev, irq, NULL, max310x_ist,
IRQF_ONESHOT | IRQF_SHARED, dev_name(dev), s);
diff --git a/drivers/tty/serial/men_z135_uart.c b/drivers/tty/serial/men_z135_uart.c
index 6fad57fee912..9138fa29d301 100644
--- a/drivers/tty/serial/men_z135_uart.c
+++ b/drivers/tty/serial/men_z135_uart.c
@@ -16,6 +16,7 @@
#include <linux/tty_flip.h>
#include <linux/bitops.h>
#include <linux/mcb.h>
+#include <linux/slab.h>
#define MEN_Z135_MAX_PORTS 12
#define MEN_Z135_BASECLK 29491200
@@ -811,7 +812,7 @@ static int men_z135_probe(struct mcb_device *mdev,
if (!uart)
return -ENOMEM;
- uart->rxbuf = (unsigned char *)__get_free_page(GFP_KERNEL);
+ uart->rxbuf = kmalloc(PAGE_SIZE, GFP_KERNEL);
if (!uart->rxbuf)
return -ENOMEM;
@@ -841,7 +842,7 @@ static int men_z135_probe(struct mcb_device *mdev,
return 0;
err:
- free_page((unsigned long) uart->rxbuf);
+ kfree(uart->rxbuf);
dev_err(dev, "Failed to add UART: %d\n", err);
return err;
@@ -858,7 +859,7 @@ static void men_z135_remove(struct mcb_device *mdev)
line--;
uart_remove_one_port(&men_z135_driver, &uart->port);
- free_page((unsigned long) uart->rxbuf);
+ kfree(uart->rxbuf);
}
static const struct mcb_device_id men_z135_ids[] = {
diff --git a/drivers/tty/serial/mpc52xx_uart.c b/drivers/tty/serial/mpc52xx_uart.c
index 37eb701b0b46..b566206f42a2 100644
--- a/drivers/tty/serial/mpc52xx_uart.c
+++ b/drivers/tty/serial/mpc52xx_uart.c
@@ -645,6 +645,8 @@ static irqreturn_t mpc512x_psc_handle_irq(struct uart_port *port)
/* Check if it is an interrupt for this port */
psc_num = (port->mapbase & 0xf00) >> 8;
+ if (psc_num >= ARRAY_SIZE(psc_mclk_clk))
+ return IRQ_NONE;
if (test_bit(psc_num, &fifoc_int) ||
test_bit(psc_num + 16, &fifoc_int))
return mpc5xxx_uart_process_int(port);
@@ -663,6 +665,8 @@ static int mpc512x_psc_alloc_clock(struct uart_port *port)
int err;
psc_num = (port->mapbase & 0xf00) >> 8;
+ if (psc_num >= ARRAY_SIZE(psc_mclk_clk))
+ return -EINVAL;
clk = devm_clk_get(port->dev, "mclk");
if (IS_ERR(clk)) {
@@ -711,6 +715,8 @@ static void mpc512x_psc_relse_clock(struct uart_port *port)
struct clk *clk;
psc_num = (port->mapbase & 0xf00) >> 8;
+ if (psc_num >= ARRAY_SIZE(psc_mclk_clk))
+ return;
clk = psc_mclk_clk[psc_num];
if (clk) {
clk_disable_unprepare(clk);
@@ -733,6 +739,8 @@ static int mpc512x_psc_endis_clock(struct uart_port *port, int enable)
return 0;
psc_num = (port->mapbase & 0xf00) >> 8;
+ if (psc_num >= ARRAY_SIZE(psc_mclk_clk))
+ return -ENODEV;
psc_clk = psc_mclk_clk[psc_num];
if (!psc_clk) {
dev_err(port->dev, "Failed to get PSC clock entry!\n");
diff --git a/drivers/tty/serial/pch_uart.c b/drivers/tty/serial/pch_uart.c
index 80e31c4d9536..db5c62b0322f 100644
--- a/drivers/tty/serial/pch_uart.c
+++ b/drivers/tty/serial/pch_uart.c
@@ -678,6 +678,11 @@ static void pch_request_dma(struct uart_port *port)
/* Get DMA's dev information */
dma_dev = pci_get_slot(priv->pdev->bus,
PCI_DEVFN(PCI_SLOT(priv->pdev->devfn), 0));
+ if (!dma_dev) {
+ dev_err(priv->port.dev, "%s: failed to get DMA device\n",
+ __func__);
+ return;
+ }
/* Set Tx DMA */
param = &priv->param_tx;
@@ -1662,7 +1667,7 @@ static struct eg20t_port *pch_uart_init_port(struct pci_dev *pdev,
if (priv == NULL)
goto init_port_alloc_err;
- rxbuf = (unsigned char *)__get_free_page(GFP_KERNEL);
+ rxbuf = kmalloc(PAGE_SIZE, GFP_KERNEL);
if (!rxbuf)
goto init_port_free_txbuf;
@@ -1735,7 +1740,7 @@ init_port_hal_free:
#ifdef CONFIG_SERIAL_PCH_UART_CONSOLE
pch_uart_ports[board->line_no] = NULL;
#endif
- free_page((unsigned long)rxbuf);
+ kfree(rxbuf);
init_port_free_txbuf:
kfree(priv);
init_port_alloc_err:
@@ -1750,7 +1755,7 @@ static void pch_uart_exit_port(struct eg20t_port *priv)
snprintf(name, sizeof(name), "uart%d_regs", priv->port.line);
debugfs_lookup_and_remove(name, NULL);
uart_remove_one_port(&pch_uart_driver, &priv->port);
- free_page((unsigned long)priv->rxbuf.buf);
+ kfree(priv->rxbuf.buf);
}
static void pch_uart_pci_remove(struct pci_dev *pdev)
diff --git a/drivers/tty/serial/qcom_geni_serial.c b/drivers/tty/serial/qcom_geni_serial.c
index 7ead87b4eb65..67b14fda4ff9 100644
--- a/drivers/tty/serial/qcom_geni_serial.c
+++ b/drivers/tty/serial/qcom_geni_serial.c
@@ -7,13 +7,18 @@
/* Disable MMIO tracing to prevent excessive logging of unwanted MMIO traces */
#define __DISABLE_TRACE_MMIO__
+#define CREATE_TRACE_POINTS
+#include <trace/events/qcom_geni_serial.h>
+
#include <linux/clk.h>
#include <linux/console.h>
+#include <linux/dma-mapping.h>
#include <linux/io.h>
#include <linux/iopoll.h>
#include <linux/irq.h>
#include <linux/module.h>
#include <linux/of.h>
+#include <linux/panic_notifier.h>
#include <linux/pm_domain.h>
#include <linux/pm_opp.h>
#include <linux/platform_device.h>
@@ -143,6 +148,7 @@ struct qcom_geni_serial_port {
unsigned int tx_remaining;
unsigned int tx_queued;
+ bool tx_dma_stale;
int wakeup_irq;
bool rx_tx_swap;
bool cts_rts_swap;
@@ -151,6 +157,7 @@ struct qcom_geni_serial_port {
struct qcom_geni_private_data private_data;
const struct qcom_geni_device_data *dev_data;
struct dev_pm_domain_list *pd_list;
+ struct notifier_block panic_nb;
};
static const struct uart_ops qcom_geni_console_pops;
@@ -226,7 +233,7 @@ static void qcom_geni_serial_config_port(struct uart_port *uport, int cfg_flags)
static unsigned int qcom_geni_serial_get_mctrl(struct uart_port *uport)
{
unsigned int mctrl = TIOCM_DSR | TIOCM_CAR;
- u32 geni_ios;
+ u32 geni_ios = 0;
if (uart_console(uport)) {
mctrl |= TIOCM_CTS;
@@ -236,6 +243,8 @@ static unsigned int qcom_geni_serial_get_mctrl(struct uart_port *uport)
mctrl |= TIOCM_CTS;
}
+ trace_geni_serial_get_mctrl(uport->dev, mctrl, geni_ios);
+
return mctrl;
}
@@ -254,6 +263,8 @@ static void qcom_geni_serial_set_mctrl(struct uart_port *uport,
if (port->manual_flow && !(mctrl & TIOCM_RTS) && !uport->suspended)
uart_manual_rfr = UART_MANUAL_RFR_EN | UART_RFR_NOT_READY;
writel(uart_manual_rfr, uport->membase + SE_UART_MANUAL_RFR);
+
+ trace_geni_serial_set_mctrl(uport->dev, mctrl, uart_manual_rfr);
}
static const char *qcom_geni_serial_get_type(struct uart_port *uport)
@@ -684,6 +695,8 @@ static void qcom_geni_serial_start_tx_dma(struct uart_port *uport)
xmit_size = kfifo_out_linear_ptr(&tport->xmit_fifo, &tail,
UART_XMIT_SIZE);
+ trace_geni_serial_tx_data(uport->dev, tail, xmit_size);
+
qcom_geni_set_rs485_mode(uport, SER_RS485_RTS_ON_SEND);
qcom_geni_serial_setup_tx(uport, xmit_size);
@@ -697,6 +710,7 @@ static void qcom_geni_serial_start_tx_dma(struct uart_port *uport)
}
port->tx_remaining = xmit_size;
+ port->tx_dma_stale = false;
}
static void qcom_geni_serial_start_tx_fifo(struct uart_port *uport)
@@ -863,37 +877,31 @@ static void qcom_geni_serial_stop_rx_dma(struct uart_port *uport)
uport->membase + SE_DMA_RX_IRQ_CLR);
}
- if (port->rx_dma_addr) {
- geni_se_rx_dma_unprep(&port->se, port->rx_dma_addr,
- DMA_RX_BUF_SIZE);
- port->rx_dma_addr = 0;
- }
}
static void qcom_geni_serial_start_rx_dma(struct uart_port *uport)
{
struct qcom_geni_serial_port *port = to_dev_port(uport);
- int ret;
if (qcom_geni_serial_secondary_active(uport))
qcom_geni_serial_stop_rx_dma(uport);
geni_se_setup_s_cmd(&port->se, UART_START_READ, UART_PARAM_RFR_OPEN);
- ret = geni_se_rx_dma_prep(&port->se, port->rx_buf,
- DMA_RX_BUF_SIZE,
- &port->rx_dma_addr);
- if (ret) {
- dev_err(uport->dev, "unable to start RX SE DMA: %d\n", ret);
- qcom_geni_serial_stop_rx_dma(uport);
+ if (!port->rx_dma_addr) {
+ dev_err(uport->dev, "RX DMA buffer not mapped\n");
+ return;
}
+
+ dma_sync_single_for_device(uport->dev->parent, port->rx_dma_addr,
+ DMA_RX_BUF_SIZE, DMA_FROM_DEVICE);
+ geni_se_rx_init_dma(&port->se, port->rx_dma_addr, DMA_RX_BUF_SIZE);
}
static void qcom_geni_serial_handle_rx_dma(struct uart_port *uport, bool drop)
{
struct qcom_geni_serial_port *port = to_dev_port(uport);
u32 rx_in;
- int ret;
if (!qcom_geni_serial_secondary_active(uport))
return;
@@ -901,22 +909,20 @@ static void qcom_geni_serial_handle_rx_dma(struct uart_port *uport, bool drop)
if (!port->rx_dma_addr)
return;
- geni_se_rx_dma_unprep(&port->se, port->rx_dma_addr, DMA_RX_BUF_SIZE);
- port->rx_dma_addr = 0;
+ dma_sync_single_for_cpu(uport->dev->parent, port->rx_dma_addr,
+ DMA_RX_BUF_SIZE, DMA_FROM_DEVICE);
rx_in = readl(uport->membase + SE_DMA_RX_LEN_IN);
if (!rx_in)
dev_warn_ratelimited(uport->dev, "serial engine reports 0 RX bytes in!\n");
- else if (!drop)
+ else if (!drop) {
+ trace_geni_serial_rx_data(uport->dev, port->rx_buf, rx_in);
handle_rx_uart(uport, rx_in);
-
- ret = geni_se_rx_dma_prep(&port->se, port->rx_buf,
- DMA_RX_BUF_SIZE,
- &port->rx_dma_addr);
- if (ret) {
- dev_err(uport->dev, "unable to start RX SE DMA: %d\n", ret);
- qcom_geni_serial_stop_rx_dma(uport);
}
+
+ dma_sync_single_for_device(uport->dev->parent, port->rx_dma_addr,
+ DMA_RX_BUF_SIZE, DMA_FROM_DEVICE);
+ geni_se_rx_init_dma(&port->se, port->rx_dma_addr, DMA_RX_BUF_SIZE);
}
static void qcom_geni_serial_start_rx(struct uart_port *uport)
@@ -1029,6 +1035,7 @@ static void qcom_geni_serial_handle_tx_dma(struct uart_port *uport)
struct qcom_geni_serial_port *port = to_dev_port(uport);
struct tty_port *tport = &uport->state->port;
unsigned int fifo_len = kfifo_len(&tport->xmit_fifo);
+ bool tx_dma_stale = port->tx_dma_stale;
/*
* Only advance the kfifo if it still contains the bytes that were
@@ -1039,12 +1046,13 @@ static void qcom_geni_serial_handle_tx_dma(struct uart_port *uport)
* kfifo->in, making kfifo_len() wrap to UART_XMIT_SIZE - tx_remaining
* and triggering a spurious large DMA transfer of stale data.
*/
- if (fifo_len >= port->tx_remaining)
+ if (!tx_dma_stale && fifo_len >= port->tx_remaining)
uart_xmit_advance(uport, port->tx_remaining);
geni_se_tx_dma_unprep(&port->se, port->tx_dma_addr, port->tx_remaining);
port->tx_dma_addr = 0;
port->tx_remaining = 0;
+ port->tx_dma_stale = false;
if (!kfifo_is_empty(&tport->xmit_fifo))
qcom_geni_serial_start_tx_dma(uport);
@@ -1079,6 +1087,10 @@ static irqreturn_t qcom_geni_serial_isr(int isr, void *dev)
geni_status = readl(uport->membase + SE_GENI_STATUS);
dma = readl(uport->membase + SE_GENI_DMA_MODE_EN);
m_irq_en = readl(uport->membase + SE_GENI_M_IRQ_EN);
+
+ trace_geni_serial_irq(uport->dev, m_irq_status, s_irq_status,
+ dma_tx_status, dma_rx_status);
+
writel(m_irq_status, uport->membase + SE_GENI_M_IRQ_CLEAR);
writel(s_irq_status, uport->membase + SE_GENI_S_IRQ_CLEAR);
writel(dma_tx_status, uport->membase + SE_DMA_TX_IRQ_CLR);
@@ -1182,6 +1194,10 @@ static void qcom_geni_serial_shutdown(struct uart_port *uport)
static void qcom_geni_serial_flush_buffer(struct uart_port *uport)
{
+ struct qcom_geni_serial_port *port = to_dev_port(uport);
+
+ if (port->tx_dma_addr)
+ port->tx_dma_stale = true;
qcom_geni_serial_cancel_tx_cmd(uport);
}
@@ -1245,6 +1261,7 @@ static int qcom_geni_serial_startup(struct uart_port *uport)
{
int ret;
struct qcom_geni_serial_port *port = to_dev_port(uport);
+ struct tty_port *tport = &uport->state->port;
if (!port->setup) {
ret = qcom_geni_serial_port_setup(uport);
@@ -1252,6 +1269,13 @@ static int qcom_geni_serial_startup(struct uart_port *uport)
return ret;
}
+ /*
+ * Skip the close-time transmit drain for console ports so that
+ * shutdown can proceed without waiting for pending TX completion.
+ */
+ if (uart_console(uport))
+ tport->closing_wait = ASYNC_CLOSING_WAIT_NONE;
+
uart_port_lock_irq(uport);
qcom_geni_serial_start_rx(uport);
uart_port_unlock_irq(uport);
@@ -1291,8 +1315,8 @@ static int geni_serial_set_rate(struct uart_port *uport, unsigned int baud)
return -EINVAL;
}
- dev_dbg(port->se.dev, "desired_rate = %u, clk_rate = %lu, clk_div = %u, clk_idx = %u\n",
- baud * sampling_rate, clk_rate, clk_div, clk_idx);
+ trace_geni_serial_clk_cfg(uport->dev, baud * sampling_rate, clk_rate,
+ clk_div, clk_idx);
uport->uartclk = clk_rate;
port->clk_rate = clk_rate;
@@ -1452,6 +1476,10 @@ static void qcom_geni_serial_set_termios(struct uart_port *uport,
writel(bits_per_char, uport->membase + SE_UART_TX_WORD_LEN);
writel(bits_per_char, uport->membase + SE_UART_RX_WORD_LEN);
writel(stop_bit_len, uport->membase + SE_UART_TX_STOP_BIT_LEN);
+
+ trace_geni_serial_set_termios(uport->dev, baud, bits_per_char,
+ tx_trans_cfg, tx_parity_cfg, rx_trans_cfg,
+ rx_parity_cfg, stop_bit_len);
}
#ifdef CONFIG_SERIAL_QCOM_GENI_CONSOLE
@@ -1798,6 +1826,22 @@ static const struct uart_ops qcom_geni_uart_pops = {
.pm = qcom_geni_serial_pm,
};
+static int qcom_geni_serial_panic_notifier(struct notifier_block *nb,
+ unsigned long action, void *data)
+{
+ struct qcom_geni_serial_port *port =
+ container_of(nb, struct qcom_geni_serial_port, panic_nb);
+ struct uart_port *uport = &port->uport;
+
+ if (pm_runtime_status_suspended(uport->dev))
+ return NOTIFY_OK;
+
+ qcom_geni_serial_stop_tx(uport);
+ qcom_geni_serial_stop_rx(uport);
+
+ return NOTIFY_OK;
+}
+
static int qcom_geni_serial_probe(struct platform_device *pdev)
{
int ret = 0;
@@ -1864,6 +1908,14 @@ static int qcom_geni_serial_probe(struct platform_device *pdev)
ret = -ENOMEM;
goto error;
}
+
+ port->rx_dma_addr = dma_map_single(pdev->dev.parent, port->rx_buf,
+ DMA_RX_BUF_SIZE, DMA_FROM_DEVICE);
+ if (dma_mapping_error(pdev->dev.parent, port->rx_dma_addr)) {
+ ret = -EIO;
+ dev_err(&pdev->dev, "Failed to map RX DMA buffer: %d\n", ret);
+ goto error;
+ }
}
port->name = devm_kasprintf(uport->dev, GFP_KERNEL,
@@ -1925,9 +1977,17 @@ static int qcom_geni_serial_probe(struct platform_device *pdev)
if (ret)
goto error;
+ port->panic_nb.notifier_call = qcom_geni_serial_panic_notifier;
+ atomic_notifier_chain_register(&panic_notifier_list, &port->panic_nb);
+
return 0;
error:
+ if (port->rx_dma_addr) {
+ dma_unmap_single(pdev->dev.parent, port->rx_dma_addr,
+ DMA_RX_BUF_SIZE, DMA_FROM_DEVICE);
+ port->rx_dma_addr = 0;
+ }
dev_pm_domain_detach_list(port->pd_list);
return ret;
}
@@ -1938,10 +1998,19 @@ static void qcom_geni_serial_remove(struct platform_device *pdev)
struct uart_port *uport = &port->uport;
struct uart_driver *drv = port->private_data.drv;
+ atomic_notifier_chain_unregister(&panic_notifier_list, &port->panic_nb);
+
dev_pm_clear_wake_irq(&pdev->dev);
device_init_wakeup(&pdev->dev, false);
ida_free(&port_ida, uport->line);
uart_remove_one_port(drv, &port->uport);
+
+ if (port->rx_dma_addr) {
+ dma_unmap_single(pdev->dev.parent, port->rx_dma_addr,
+ DMA_RX_BUF_SIZE, DMA_FROM_DEVICE);
+ port->rx_dma_addr = 0;
+ }
+
dev_pm_domain_detach_list(port->pd_list);
}
@@ -1974,6 +2043,7 @@ static int qcom_geni_serial_suspend(struct device *dev)
struct qcom_geni_serial_port *port = dev_get_drvdata(dev);
struct uart_port *uport = &port->uport;
struct qcom_geni_private_data *private_data = uport->private_data;
+ int ret;
/*
* This is done so we can hit the lowest possible state in suspend
@@ -1983,7 +2053,19 @@ static int qcom_geni_serial_suspend(struct device *dev)
geni_icc_set_tag(&port->se, QCOM_ICC_TAG_ACTIVE_ONLY);
geni_icc_set_bw(&port->se);
}
- return uart_suspend_port(private_data->drv, uport);
+
+ ret = uart_suspend_port(private_data->drv, uport);
+ if (ret)
+ return ret;
+
+ /*
+ * When no_console_suspend is set the console must remain active
+ * across system sleep, so skip the force suspend path.
+ */
+ if (!console_suspend_enabled && uart_console(uport))
+ return 0;
+
+ return pm_runtime_force_suspend(dev);
}
static int qcom_geni_serial_resume(struct device *dev)
@@ -1993,6 +2075,10 @@ static int qcom_geni_serial_resume(struct device *dev)
struct uart_port *uport = &port->uport;
struct qcom_geni_private_data *private_data = uport->private_data;
+ ret = pm_runtime_force_resume(dev);
+ if (ret)
+ return ret;
+
ret = uart_resume_port(private_data->drv, uport);
if (uart_console(uport)) {
geni_icc_set_tag(&port->se, QCOM_ICC_TAG_ALWAYS);
@@ -2049,6 +2135,18 @@ static const struct dev_pm_ops qcom_geni_serial_pm_ops = {
SYSTEM_SLEEP_PM_OPS(qcom_geni_serial_suspend, qcom_geni_serial_resume)
};
+static void qcom_geni_serial_sys_shutdown(struct platform_device *pdev)
+{
+ struct qcom_geni_serial_port *port = platform_get_drvdata(pdev);
+ struct uart_port *uport = &port->uport;
+
+ if (pm_runtime_status_suspended(uport->dev))
+ return;
+
+ qcom_geni_serial_stop_tx(uport);
+ qcom_geni_serial_stop_rx(uport);
+}
+
static const struct of_device_id qcom_geni_serial_match_table[] = {
#if IS_ENABLED(CONFIG_SERIAL_QCOM_GENI_CONSOLE)
{
@@ -2075,6 +2173,7 @@ MODULE_DEVICE_TABLE(of, qcom_geni_serial_match_table);
static struct platform_driver qcom_geni_serial_platform_driver = {
.remove = qcom_geni_serial_remove,
.probe = qcom_geni_serial_probe,
+ .shutdown = qcom_geni_serial_sys_shutdown,
.driver = {
.name = "qcom_geni_serial",
.of_match_table = qcom_geni_serial_match_table,
diff --git a/drivers/tty/serial/rp2.c b/drivers/tty/serial/rp2.c
index 6d99a02dd439..51e81ec0ffdb 100644
--- a/drivers/tty/serial/rp2.c
+++ b/drivers/tty/serial/rp2.c
@@ -197,7 +197,7 @@ struct rp2_card {
};
#define RP_ID(prod) PCI_VDEVICE(RP, (prod))
-#define RP_CAP(ports, smpte) (((ports) << 8) | ((smpte) << 0))
+#define RP_CAP(ports, smpte) .driver_data = (((ports) << 8) | ((smpte) << 0))
static inline void rp2_decode_cap(const struct pci_device_id *id,
int *ports, int *smpte)
diff --git a/drivers/tty/serial/sc16is7xx.c b/drivers/tty/serial/sc16is7xx.c
index 6c97953d593b..943be318de41 100644
--- a/drivers/tty/serial/sc16is7xx.c
+++ b/drivers/tty/serial/sc16is7xx.c
@@ -1483,14 +1483,7 @@ static int sc16is7xx_setup_channel(struct sc16is7xx_one *one, int i,
port->type = PORT_SC16IS7XX;
port->fifosize = SC16IS7XX_FIFO_SIZE;
port->flags = UPF_FIXED_TYPE | UPF_LOW_LATENCY;
- port->iobase = i;
- /*
- * Use all ones as membase to make sure uart_configure_port() in
- * serial_core.c does not abort for SPI/I2C devices where the
- * membase address is not applicable.
- */
- port->membase = (void __iomem *)~0;
- port->iotype = UPIO_PORT;
+ port->iotype = UPIO_BUS;
port->rs485_config = sc16is7xx_config_rs485;
port->rs485_supported = sc16is7xx_rs485_supported;
port->ops = &sc16is7xx_ops;
diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c
index a530ad372b43..edd1e7be2a5c 100644
--- a/drivers/tty/serial/serial_core.c
+++ b/drivers/tty/serial/serial_core.c
@@ -33,6 +33,7 @@
#include <linux/uaccess.h>
#include "serial_base.h"
+#include "8250/8250.h" /* For hub6_match_port() */
/*
* This is used to lock changes in serial line configuration.
@@ -1962,6 +1963,34 @@ static const char *uart_type(struct uart_port *port)
return str;
}
+bool uart_iotype_mmio(enum uart_iotype iotype)
+{
+ switch (iotype) {
+ case UPIO_MEM:
+ case UPIO_MEM32:
+ case UPIO_AU:
+ case UPIO_TSI:
+ case UPIO_MEM32BE:
+ case UPIO_MEM16:
+ return true;
+ default:
+ return false;
+ }
+}
+EXPORT_SYMBOL_GPL(uart_iotype_mmio);
+
+bool uart_iotype_io(enum uart_iotype iotype)
+{
+ switch (iotype) {
+ case UPIO_PORT:
+ case UPIO_HUB6:
+ return true;
+ default:
+ return false;
+ }
+}
+EXPORT_SYMBOL_GPL(uart_iotype_io);
+
#ifdef CONFIG_PROC_FS
static void uart_line_info(struct seq_file *m, struct uart_state *state)
@@ -1969,9 +1998,9 @@ static void uart_line_info(struct seq_file *m, struct uart_state *state)
struct tty_port *port = &state->port;
enum uart_pm_state pm_state;
struct uart_port *uport;
+ char ioinfos[64];
char stat_buf[32];
unsigned int status;
- int mmio;
guard(mutex)(&port->mutex);
@@ -1979,13 +2008,10 @@ static void uart_line_info(struct seq_file *m, struct uart_state *state)
if (!uport)
return;
- mmio = uport->iotype >= UPIO_MEM;
- seq_printf(m, "%u: uart:%s %s%08llX irq:%u",
- uport->line, uart_type(uport),
- mmio ? "mmio:0x" : "port:",
- mmio ? (unsigned long long)uport->mapbase
- : (unsigned long long)uport->iobase,
- uport->irq);
+ seq_printf(m, "%u: uart:%s", uport->line, uart_type(uport));
+ uart_get_ioinfos(uport, ioinfos, sizeof(ioinfos));
+ seq_printf(m, "%s", ioinfos);
+ seq_printf(m, " irq:%u", uport->irq);
if (uport->type == PORT_UNKNOWN) {
seq_putc(m, '\n');
@@ -2459,38 +2485,47 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *uport)
}
EXPORT_SYMBOL(uart_resume_port);
-static inline void
-uart_report_port(struct uart_driver *drv, struct uart_port *port)
+static const char *uart_get_mmio_width(struct uart_port *port)
{
- char address[64];
-
switch (port->iotype) {
- case UPIO_PORT:
- snprintf(address, sizeof(address), "I/O 0x%lx", port->iobase);
- break;
- case UPIO_HUB6:
- snprintf(address, sizeof(address),
- "I/O 0x%lx offset 0x%x", port->iobase, port->hub6);
- break;
- case UPIO_MEM:
case UPIO_MEM16:
+ return "16";
case UPIO_MEM32:
case UPIO_MEM32BE:
+ return "32";
case UPIO_AU:
- case UPIO_TSI:
- snprintf(address, sizeof(address),
- "MMIO 0x%llx", (unsigned long long)port->mapbase);
- break;
+ case UPIO_MEM:
default:
- strscpy(address, "*unknown*", sizeof(address));
- break;
+ return "";
+ }
+}
+
+void uart_get_ioinfos(struct uart_port *port, char *buf, size_t size)
+{
+ buf[0] = '\0';
+
+ if (uart_iotype_mmio(port->iotype)) {
+ scnprintf(buf, size, " MMIO%s:%pa", uart_get_mmio_width(port), &port->mapbase);
+ } else if (uart_iotype_io(port->iotype)) {
+ if (port->iotype == UPIO_PORT)
+ scnprintf(buf, size, " I/O:0x%lx", port->iobase);
+ else if (port->iotype == UPIO_HUB6)
+ scnprintf(buf, size, " I/O:0x%lx, offset 0x%x", port->iobase, port->hub6);
}
+}
+EXPORT_SYMBOL(uart_get_ioinfos);
+
+static inline void
+uart_report_port(struct uart_driver *drv, struct uart_port *port)
+{
+ char ioinfos[64];
+
+ uart_get_ioinfos(port, ioinfos, sizeof(ioinfos));
- pr_info("%s%s%s at %s (irq = %u, base_baud = %u) is a %s\n",
- port->dev ? dev_name(port->dev) : "",
- port->dev ? ": " : "",
- port->name,
- address, port->irq, port->uartclk / 16, uart_type(port));
+ pr_info("%s%s%s%s (irq = %u, base_baud = %u) is a %s\n",
+ port->dev ? dev_name(port->dev) : "",
+ port->dev ? ": " : "",
+ port->name, ioinfos, port->irq, port->uartclk / 16, uart_type(port));
/* The magic multiplier feature is a bit obscure, so report it too. */
if (port->flags & UPF_MAGIC_MULTIPLIER)
@@ -2507,11 +2542,10 @@ uart_configure_port(struct uart_driver *drv, struct uart_state *state,
{
unsigned int flags;
- /*
- * If there isn't a port here, don't do anything further.
- */
- if (!port->iobase && !port->mapbase && !port->membase)
- return;
+ /* If there isn't a port here, don't do anything further. */
+ if (uart_iotype_mmio(port->iotype) || uart_iotype_io(port->iotype))
+ if (!port->iobase && !port->mapbase && !port->membase)
+ return;
/*
* Now do the auto configuration stuff. Note that config_port
@@ -3208,23 +3242,16 @@ bool uart_match_port(const struct uart_port *port1,
{
if (port1->iotype != port2->iotype)
return false;
-
- switch (port1->iotype) {
- case UPIO_PORT:
+ else if (port1->iotype == UPIO_PORT)
return port1->iobase == port2->iobase;
- case UPIO_HUB6:
- return port1->iobase == port2->iobase &&
- port1->hub6 == port2->hub6;
- case UPIO_MEM:
- case UPIO_MEM16:
- case UPIO_MEM32:
- case UPIO_MEM32BE:
- case UPIO_AU:
- case UPIO_TSI:
+ else if (port1->iotype == UPIO_HUB6)
+ return hub6_match_port(port1, port2);
+ else if (uart_iotype_mmio(port1->iotype))
return port1->mapbase == port2->mapbase;
- default:
+ else if (port1->iotype == UPIO_BUS)
+ return true;
+ else
return false;
- }
}
EXPORT_SYMBOL(uart_match_port);
diff --git a/drivers/tty/tty_jobctrl.c b/drivers/tty/tty_jobctrl.c
index ef8741c3e662..37929fb56174 100644
--- a/drivers/tty/tty_jobctrl.c
+++ b/drivers/tty/tty_jobctrl.c
@@ -506,29 +506,23 @@ static int tiocspgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t
if (pgrp_nr < 0)
return -EINVAL;
- spin_lock_irq(&real_tty->ctrl.lock);
+ guard(spinlock_irq)(&real_tty->ctrl.lock);
if (!current->signal->tty ||
(current->signal->tty != real_tty) ||
- (real_tty->ctrl.session != task_session(current))) {
- retval = -ENOTTY;
- goto out_unlock_ctrl;
- }
- rcu_read_lock();
+ (real_tty->ctrl.session != task_session(current)))
+ return -ENOTTY;
+
+ guard(rcu)();
pgrp = find_vpid(pgrp_nr);
- retval = -ESRCH;
if (!pgrp)
- goto out_unlock;
- retval = -EPERM;
+ return -ESRCH;
if (session_of_pgrp(pgrp) != task_session(current))
- goto out_unlock;
- retval = 0;
+ return -EPERM;
+
put_pid(real_tty->ctrl.pgrp);
real_tty->ctrl.pgrp = get_pid(pgrp);
-out_unlock:
- rcu_read_unlock();
-out_unlock_ctrl:
- spin_unlock_irq(&real_tty->ctrl.lock);
- return retval;
+
+ return 0;
}
/**
@@ -542,7 +536,6 @@ out_unlock_ctrl:
*/
static int tiocgsid(struct tty_struct *tty, struct tty_struct *real_tty, pid_t __user *p)
{
- unsigned long flags;
pid_t sid;
/*
@@ -552,17 +545,13 @@ static int tiocgsid(struct tty_struct *tty, struct tty_struct *real_tty, pid_t _
if (tty == real_tty && current->signal->tty != real_tty)
return -ENOTTY;
- spin_lock_irqsave(&real_tty->ctrl.lock, flags);
- if (!real_tty->ctrl.session)
- goto err;
- sid = pid_vnr(real_tty->ctrl.session);
- spin_unlock_irqrestore(&real_tty->ctrl.lock, flags);
+ scoped_guard(spinlock_irqsave, &real_tty->ctrl.lock) {
+ if (!real_tty->ctrl.session)
+ return -ENOTTY;
+ sid = pid_vnr(real_tty->ctrl.session);
+ }
return put_user(sid, p);
-
-err:
- spin_unlock_irqrestore(&real_tty->ctrl.lock, flags);
- return -ENOTTY;
}
/*
diff --git a/drivers/tty/vt/vc_screen.c b/drivers/tty/vt/vc_screen.c
index 7d40eacc21b3..bf1502fd5bd4 100644
--- a/drivers/tty/vt/vc_screen.c
+++ b/drivers/tty/vt/vc_screen.c
@@ -53,8 +53,6 @@
#define HEADER_SIZE 4u
#define CON_BUF_SIZE (IS_ENABLED(CONFIG_BASE_SMALL) ? 256 : PAGE_SIZE)
-DEFINE_FREE(free_page_ptr, void *, if (_T) free_page((unsigned long)_T));
-
/*
* Our minor space:
*
@@ -371,7 +369,7 @@ vcs_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
loff_t pos;
bool viewed, attr, uni_mode;
- char *con_buf __free(free_page_ptr) = (char *)__get_free_page(GFP_KERNEL);
+ char *con_buf __free(kfree) = kmalloc(PAGE_SIZE, GFP_KERNEL);
if (!con_buf)
return -ENOMEM;
@@ -596,7 +594,7 @@ vcs_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
if (use_unicode(inode))
return -EOPNOTSUPP;
- char *con_buf __free(free_page_ptr) = (char *)__get_free_page(GFP_KERNEL);
+ char *con_buf __free(kfree) = kmalloc(PAGE_SIZE, GFP_KERNEL);
if (!con_buf)
return -ENOMEM;
diff --git a/include/linux/goldfish.h b/include/linux/goldfish.h
index bcc17f95b906..98a4719c6776 100644
--- a/include/linux/goldfish.h
+++ b/include/linux/goldfish.h
@@ -2,8 +2,6 @@
#ifndef __LINUX_GOLDFISH_H
#define __LINUX_GOLDFISH_H
-#include <linux/kernel.h>
-#include <linux/types.h>
#include <linux/io.h>
/* Helpers for Goldfish virtual platform */
@@ -15,26 +13,4 @@
#define gf_iowrite32 iowrite32
#endif
-static inline void gf_write_ptr(const void *ptr, void __iomem *portl,
- void __iomem *porth)
-{
- const unsigned long addr = (unsigned long)ptr;
-
- gf_iowrite32(lower_32_bits(addr), portl);
-#ifdef CONFIG_64BIT
- gf_iowrite32(upper_32_bits(addr), porth);
-#endif
-}
-
-static inline void gf_write_dma_addr(const dma_addr_t addr,
- void __iomem *portl,
- void __iomem *porth)
-{
- gf_iowrite32(lower_32_bits(addr), portl);
-#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
- gf_iowrite32(upper_32_bits(addr), porth);
-#endif
-}
-
-
#endif /* __LINUX_GOLDFISH_H */
diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h
index bdc214386e4a..c4cc4f66af4b 100644
--- a/include/linux/serial_core.h
+++ b/include/linux/serial_core.h
@@ -437,6 +437,7 @@ enum uart_iotype {
UPIO_TSI = SERIAL_IO_TSI, /* Tsi108/109 type IO */
UPIO_MEM32BE = SERIAL_IO_MEM32BE, /* 32b big endian */
UPIO_MEM16 = SERIAL_IO_MEM16, /* 16b little endian */
+ UPIO_BUS = SERIAL_IO_BUS, /* Serial bus I/O access (ex: SPI, I2C) */
};
struct uart_port {
@@ -1338,4 +1339,9 @@ static inline int uart_handle_break(struct uart_port *port)
!((cflag) & CLOCAL))
int uart_get_rs485_mode(struct uart_port *port);
+
+void uart_get_ioinfos(struct uart_port *port, char *buf, size_t size);
+bool uart_iotype_mmio(enum uart_iotype iotype);
+bool uart_iotype_io(enum uart_iotype iotype);
+
#endif /* LINUX_SERIAL_CORE_H */
diff --git a/include/trace/events/qcom_geni_serial.h b/include/trace/events/qcom_geni_serial.h
index 417ec01f9fc8..e1aa551d525e 100644
--- a/include/trace/events/qcom_geni_serial.h
+++ b/include/trace/events/qcom_geni_serial.h
@@ -97,18 +97,17 @@ DECLARE_EVENT_CLASS(geni_serial_data,
TP_ARGS(dev, buf, len),
TP_STRUCT__entry(__string(name, dev_name(dev))
- __field(unsigned int, len)
__dynamic_array(u8, data, len)
),
TP_fast_assign(__assign_str(name);
- __entry->len = len;
memcpy(__get_dynamic_array(data), buf, len);
),
TP_printk("%s: len=%u data=%s",
- __get_str(name), __entry->len,
- __print_hex(__get_dynamic_array(data), __entry->len))
+ __get_str(name), __get_dynamic_array_len(data),
+ __print_hex(__get_dynamic_array(data),
+ __get_dynamic_array_len(data)))
);
DEFINE_EVENT(geni_serial_data, geni_serial_tx_data,
diff --git a/include/uapi/linux/serial.h b/include/uapi/linux/serial.h
index de9b4733607e..e6f61538fc28 100644
--- a/include/uapi/linux/serial.h
+++ b/include/uapi/linux/serial.h
@@ -72,6 +72,7 @@ struct serial_struct {
#define SERIAL_IO_TSI 5
#define SERIAL_IO_MEM32BE 6
#define SERIAL_IO_MEM16 7
+#define SERIAL_IO_BUS 8
#define UART_CLEAR_FIFO 0x01
#define UART_USE_FIFO 0x02