From 623ac1d4a52f279d9379bae61ae1eb37c5767f96 Mon Sep 17 00:00:00 2001 From: Pan Bian Date: Sat, 3 Dec 2016 18:40:25 +0800 Subject: tty: serial: sh-sci: set error code when kasprintf fails When the call to kasprintf() returns a NULL pointer, function sci_request_irq() frees the preallocated memory and returns 0 is returned. Because 0 means no error, the caller of sci_request_irq() will keep going, and the freed memory may be used or freed again. To avoid the above issue, this patch assigns "-ENOMEM" to the return variable ret. Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=188691 Signed-off-by: Pan Bian Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/sh-sci.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index 91e7dddbf72c..b33199af8877 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -1743,8 +1743,10 @@ static int sci_request_irq(struct sci_port *port) desc = sci_irq_desc + i; port->irqstr[j] = kasprintf(GFP_KERNEL, "%s:%s", dev_name(up->dev), desc->desc); - if (!port->irqstr[j]) + if (!port->irqstr[j]) { + ret = -ENOMEM; goto out_nomem; + } ret = request_irq(irq, desc->handler, up->irqflags, port->irqstr[j], port); -- cgit v1.2.3-59-g8ed1b From 54a44d54be3a7394ebea42bbffd67819e0f3f89a Mon Sep 17 00:00:00 2001 From: Nikita Yushchenko Date: Sun, 4 Dec 2016 18:49:28 +0300 Subject: tty: serial: fsl_lpuart: fix del_timer_sync() vs timer routine deadlock Problem found via lockdep: - lpuart_set_termios() calls del_timer_sync(&sport->lpuart_timer) while holding sport->port.lock - sport->lpuart_timer routine is lpuart_timer_func() that calls lpuart_copy_rx_to_tty() that acquires same lock. To fix, move Rx DMA stopping out of lock, as it already is in other places in the same file. While at it, also make Rx DMA start/stop code to look the same is in other places in the same file. Signed-off-by: Nikita Yushchenko Tested-by: Stefan Agner Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/fsl_lpuart.c | 35 +++++++++++++++++------------------ 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c index a1c6519837a4..f02934ffb329 100644 --- a/drivers/tty/serial/fsl_lpuart.c +++ b/drivers/tty/serial/fsl_lpuart.c @@ -1407,6 +1407,18 @@ lpuart_set_termios(struct uart_port *port, struct ktermios *termios, /* ask the core to calculate the divisor */ baud = uart_get_baud_rate(port, termios, old, 50, port->uartclk / 16); + /* + * Need to update the Ring buffer length according to the selected + * baud rate and restart Rx DMA path. + * + * Since timer function acqures sport->port.lock, need to stop before + * acquring same lock because otherwise del_timer_sync() can deadlock. + */ + if (old && sport->lpuart_dma_rx_use) { + del_timer_sync(&sport->lpuart_timer); + lpuart_dma_rx_free(&sport->port); + } + spin_lock_irqsave(&sport->port.lock, flags); sport->port.read_status_mask = 0; @@ -1456,22 +1468,11 @@ lpuart_set_termios(struct uart_port *port, struct ktermios *termios, /* restore control register */ writeb(old_cr2, sport->port.membase + UARTCR2); - /* - * If new baud rate is set, we will also need to update the Ring buffer - * length according to the selected baud rate and restart Rx DMA path. - */ - if (old) { - if (sport->lpuart_dma_rx_use) { - del_timer_sync(&sport->lpuart_timer); - lpuart_dma_rx_free(&sport->port); - } - - if (sport->dma_rx_chan && !lpuart_start_rx_dma(sport)) { - sport->lpuart_dma_rx_use = true; + if (old && sport->lpuart_dma_rx_use) { + if (!lpuart_start_rx_dma(sport)) rx_dma_timer_init(sport); - } else { + else sport->lpuart_dma_rx_use = false; - } } spin_unlock_irqrestore(&sport->port.lock, flags); @@ -2131,12 +2132,10 @@ static int lpuart_resume(struct device *dev) if (sport->lpuart_dma_rx_use) { if (sport->port.irq_wake) { - if (!lpuart_start_rx_dma(sport)) { - sport->lpuart_dma_rx_use = true; + if (!lpuart_start_rx_dma(sport)) rx_dma_timer_init(sport); - } else { + else sport->lpuart_dma_rx_use = false; - } } } -- cgit v1.2.3-59-g8ed1b From 11652fc7b7e381a8d886ae1393e00512b71fe17d Mon Sep 17 00:00:00 2001 From: Alexander Shiyan Date: Mon, 5 Dec 2016 14:05:19 +0300 Subject: serial: max310x: Add support for newer silicon revisions New IC MAX14830 has 0xB4 silicon revision ID. This patch adds support for such ICs. Signed-off-by: Alexander Shiyan Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/max310x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/serial/max310x.c b/drivers/tty/serial/max310x.c index 8a3e92638e10..9dfedbe6c071 100644 --- a/drivers/tty/serial/max310x.c +++ b/drivers/tty/serial/max310x.c @@ -236,7 +236,7 @@ /* Misc definitions */ #define MAX310X_FIFO_SIZE (128) -#define MAX310x_REV_MASK (0xfc) +#define MAX310x_REV_MASK (0xf8) /* MAX3107 specific */ #define MAX3107_REV_ID (0xa0) -- cgit v1.2.3-59-g8ed1b From f87fa71e6fb0fa7bade9c3f3bb3f49325e76a90a Mon Sep 17 00:00:00 2001 From: Wolfgang Ocker Date: Mon, 12 Dec 2016 08:21:01 +0100 Subject: serial: mxs-auart: support CMSPAR termios cflag If CMSPAR is set in the c_cflag of termios, "stick" parity is enabled. Tested on an i.MX28 system Signed-off-by: Wolfgang Ocker Acked-by: Stefan Wahren Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/mxs-auart.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/tty/serial/mxs-auart.c b/drivers/tty/serial/mxs-auart.c index 8c1c9112b3fd..6989b227d134 100644 --- a/drivers/tty/serial/mxs-auart.c +++ b/drivers/tty/serial/mxs-auart.c @@ -95,6 +95,7 @@ #define AUART_LINECTRL_BAUD_DIVFRAC_SHIFT 8 #define AUART_LINECTRL_BAUD_DIVFRAC_MASK 0x00003f00 #define AUART_LINECTRL_BAUD_DIVFRAC(v) (((v) & 0x3f) << 8) +#define AUART_LINECTRL_SPS (1 << 7) #define AUART_LINECTRL_WLEN_MASK 0x00000060 #define AUART_LINECTRL_WLEN(v) (((v) & 0x3) << 5) #define AUART_LINECTRL_FEN (1 << 4) @@ -1014,6 +1015,8 @@ static void mxs_auart_settermios(struct uart_port *u, ctrl |= AUART_LINECTRL_PEN; if ((cflag & PARODD) == 0) ctrl |= AUART_LINECTRL_EPS; + if (cflag & CMSPAR) + ctrl |= AUART_LINECTRL_SPS; } u->read_status_mask = AUART_STAT_OERR; -- cgit v1.2.3-59-g8ed1b From ba3d6f8f10c3897e0edde3069beb0bfbe81783a6 Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Fri, 16 Dec 2016 10:56:53 +0100 Subject: serial: samsung: Simplify DMA engine initialization code dma_request_slave_channel_compat() requires filter function and mask, which are not needed on device tree based platforms, so simplify the code by calling the more appropriate dma_request_chan() function. This additionally gives us proper error handling, because the new function returns error codes instead of NULL on failure. Signed-off-by: Marek Szyprowski Reviewed-by: Sylwester Nawrocki Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/samsung.c | 17 ++++++----------- drivers/tty/serial/samsung.h | 4 ---- 2 files changed, 6 insertions(+), 15 deletions(-) diff --git a/drivers/tty/serial/samsung.c b/drivers/tty/serial/samsung.c index f44615fa474d..a9b309ba24a4 100644 --- a/drivers/tty/serial/samsung.c +++ b/drivers/tty/serial/samsung.c @@ -859,7 +859,6 @@ static void s3c24xx_serial_break_ctl(struct uart_port *port, int break_state) static int s3c24xx_serial_request_dma(struct s3c24xx_uart_port *p) { struct s3c24xx_uart_dma *dma = p->dma; - dma_cap_mask_t mask; unsigned long flags; /* Default slave configuration parameters */ @@ -876,21 +875,17 @@ static int s3c24xx_serial_request_dma(struct s3c24xx_uart_port *p) else dma->tx_conf.dst_maxburst = 1; - dma_cap_zero(mask); - dma_cap_set(DMA_SLAVE, mask); + dma->rx_chan = dma_request_chan(p->port.dev, "rx"); - dma->rx_chan = dma_request_slave_channel_compat(mask, dma->fn, - dma->rx_param, p->port.dev, "rx"); - if (!dma->rx_chan) - return -ENODEV; + if (IS_ERR(dma->rx_chan)) + return PTR_ERR(dma->rx_chan); dmaengine_slave_config(dma->rx_chan, &dma->rx_conf); - dma->tx_chan = dma_request_slave_channel_compat(mask, dma->fn, - dma->tx_param, p->port.dev, "tx"); - if (!dma->tx_chan) { + dma->tx_chan = dma_request_chan(p->port.dev, "tx"); + if (IS_ERR(dma->tx_chan)) { dma_release_channel(dma->rx_chan); - return -ENODEV; + return PTR_ERR(dma->tx_chan); } dmaengine_slave_config(dma->tx_chan, &dma->tx_conf); diff --git a/drivers/tty/serial/samsung.h b/drivers/tty/serial/samsung.h index a04acef1cb20..965199b6c16f 100644 --- a/drivers/tty/serial/samsung.h +++ b/drivers/tty/serial/samsung.h @@ -44,10 +44,6 @@ struct s3c24xx_serial_drv_data { }; struct s3c24xx_uart_dma { - dma_filter_fn fn; - void *rx_param; - void *tx_param; - unsigned int rx_chan_id; unsigned int tx_chan_id; -- cgit v1.2.3-59-g8ed1b From 2aaa957361f9b84fb72ce0124ebb1e5835235ba8 Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Sun, 18 Dec 2016 07:38:11 +0100 Subject: serial: pic32_uart: Fix 'request_irq' and 'free_irq' inconsistancy 'request_irq' and 'free_irq' should have the same 'dev_id'. Here one uses 'port', and the other one uses 'sport'. Signed-off-by: Christophe JAILLET Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/pic32_uart.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/tty/serial/pic32_uart.c b/drivers/tty/serial/pic32_uart.c index 7f8e99bbcb73..00a33eb859d3 100644 --- a/drivers/tty/serial/pic32_uart.c +++ b/drivers/tty/serial/pic32_uart.c @@ -495,13 +495,13 @@ static int pic32_uart_startup(struct uart_port *port) out_t: kfree(sport->irq_tx_name); - free_irq(sport->irq_tx, sport); + free_irq(sport->irq_tx, port); out_r: kfree(sport->irq_rx_name); - free_irq(sport->irq_rx, sport); + free_irq(sport->irq_rx, port); out_f: kfree(sport->irq_fault_name); - free_irq(sport->irq_fault, sport); + free_irq(sport->irq_fault, port); out_done: return ret; } -- cgit v1.2.3-59-g8ed1b From ec84aa0a920192df56624961cb146947d7d9e11e Mon Sep 17 00:00:00 2001 From: Martin Blumenstingl Date: Sun, 11 Dec 2016 21:42:23 +0100 Subject: tty: serial: lantiq: implement earlycon support This allows enabling earlycon for devices with a Lantiq serial console by splitting lqasc_serial_port_write() from lqasc_console_write() and re-using the new function for earlycon's write callback. The kernel-parameter name matches the driver name ("lantiq"), similar to how other drivers implement this. Signed-off-by: Martin Blumenstingl Signed-off-by: Greg Kroah-Hartman --- Documentation/admin-guide/kernel-parameters.txt | 6 ++++ drivers/tty/serial/Kconfig | 1 + drivers/tty/serial/lantiq.c | 38 ++++++++++++++++++++----- 3 files changed, 38 insertions(+), 7 deletions(-) diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt index be7c0d9506b1..52f13674bc21 100644 --- a/Documentation/admin-guide/kernel-parameters.txt +++ b/Documentation/admin-guide/kernel-parameters.txt @@ -966,6 +966,12 @@ serial port must already be setup and configured. Options are not yet supported. + lantiq, + Start an early, polled-mode console on a lantiq serial + (lqasc) port at the specified address. The serial port + must already be setup and configured. Options are not + yet supported. + lpuart, lpuart32, Use early console provided by Freescale LP UART driver diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig index e9cf5b67f1b7..6117ac8da48f 100644 --- a/drivers/tty/serial/Kconfig +++ b/drivers/tty/serial/Kconfig @@ -1161,6 +1161,7 @@ config SERIAL_LANTIQ depends on LANTIQ select SERIAL_CORE select SERIAL_CORE_CONSOLE + select SERIAL_EARLYCON help Support for console and UART on Lantiq SoCs. diff --git a/drivers/tty/serial/lantiq.c b/drivers/tty/serial/lantiq.c index b88832e8ee82..7c9a3f244935 100644 --- a/drivers/tty/serial/lantiq.c +++ b/drivers/tty/serial/lantiq.c @@ -590,13 +590,20 @@ lqasc_console_putchar(struct uart_port *port, int ch) ltq_w8(ch, port->membase + LTQ_ASC_TBUF); } +static void lqasc_serial_port_write(struct uart_port *port, const char *s, + u_int count) +{ + unsigned long flags; + + spin_lock_irqsave(<q_asc_lock, flags); + uart_console_write(port, s, count, lqasc_console_putchar); + spin_unlock_irqrestore(<q_asc_lock, flags); +} static void lqasc_console_write(struct console *co, const char *s, u_int count) { struct ltq_uart_port *ltq_port; - struct uart_port *port; - unsigned long flags; if (co->index >= MAXPORTS) return; @@ -605,11 +612,7 @@ lqasc_console_write(struct console *co, const char *s, u_int count) if (!ltq_port) return; - port = <q_port->port; - - spin_lock_irqsave(<q_asc_lock, flags); - uart_console_write(port, s, count, lqasc_console_putchar); - spin_unlock_irqrestore(<q_asc_lock, flags); + lqasc_serial_port_write(<q_port->port, s, count); } static int __init @@ -659,6 +662,27 @@ lqasc_console_init(void) } console_initcall(lqasc_console_init); +static void lqasc_serial_early_console_write(struct console *co, + const char *s, + u_int count) +{ + struct earlycon_device *dev = co->data; + + lqasc_serial_port_write(&dev->port, s, count); +} + +static int __init +lqasc_serial_early_console_setup(struct earlycon_device *device, + const char *opt) +{ + if (!device->port.membase) + return -ENODEV; + + device->con->write = lqasc_serial_early_console_write; + return 0; +} +OF_EARLYCON_DECLARE(lantiq, DRVNAME, lqasc_serial_early_console_setup); + static struct uart_driver lqasc_reg = { .owner = THIS_MODULE, .driver_name = DRVNAME, -- cgit v1.2.3-59-g8ed1b From 552df698e9e88b580039ca715e1b5ad34b6e130b Mon Sep 17 00:00:00 2001 From: John Crispin Date: Tue, 20 Dec 2016 20:01:45 +0100 Subject: tty: update my email address This patch updates my email address as I no longer have access to the old one. Signed-off-by: John Crispin Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/lantiq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/serial/lantiq.c b/drivers/tty/serial/lantiq.c index 7c9a3f244935..5961bb47b8e5 100644 --- a/drivers/tty/serial/lantiq.c +++ b/drivers/tty/serial/lantiq.c @@ -16,7 +16,7 @@ * * Copyright (C) 2004 Infineon IFAP DC COM CPE * Copyright (C) 2007 Felix Fietkau - * Copyright (C) 2007 John Crispin + * Copyright (C) 2007 John Crispin * Copyright (C) 2010 Thomas Langer, */ -- cgit v1.2.3-59-g8ed1b From 732dbf3a6104a3abfcfcd066dcaf89e5054ce009 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Thu, 22 Dec 2016 08:31:34 +0100 Subject: serial: do not accept sysrq characters via serial port many embedded boards have a disconnected TTL level serial which can generate some garbage that can lead to spurious false sysrq detects. Signed-off-by: John Crispin Signed-off-by: Felix Fietkau Signed-off-by: Greg Kroah-Hartman --- include/linux/serial_core.h | 2 +- lib/Kconfig.debug | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h index 5def8e830fb0..58484fb35cc8 100644 --- a/include/linux/serial_core.h +++ b/include/linux/serial_core.h @@ -450,7 +450,7 @@ extern void uart_handle_cts_change(struct uart_port *uport, extern void uart_insert_char(struct uart_port *port, unsigned int status, unsigned int overrun, unsigned int ch, unsigned int flag); -#ifdef SUPPORT_SYSRQ +#if defined(SUPPORT_SYSRQ) && defined(CONFIG_MAGIC_SYSRQ_SERIAL) static inline int uart_handle_sysrq_char(struct uart_port *port, unsigned int ch) { diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index b06848a104e6..9fa4e6eb1fe3 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug @@ -416,6 +416,16 @@ config MAGIC_SYSRQ_DEFAULT_ENABLE This may be set to 1 or 0 to enable or disable them all, or to a bitmask as described in Documentation/sysrq.txt. +config MAGIC_SYSRQ_SERIAL + bool "Enable magic SysRq key over serial" + depends on MAGIC_SYSRQ + default y + help + Many embedded boards have a disconnected TTL level serial which can + generate some garbage that can lead to spurious false sysrq detects. + This option allows you to decide whether you want to enable the + magic SysRq key. + config DEBUG_KERNEL bool "Kernel debugging" help -- cgit v1.2.3-59-g8ed1b From 6def047c29b94cd7de8ffaec567060fb610ef2d2 Mon Sep 17 00:00:00 2001 From: "Ji-Ze Hong (Peter Hong)" Date: Fri, 23 Dec 2016 09:41:20 +0800 Subject: serial: 8250_fintek: Add resource check for Fintek F81504/508/512 Add resource type check for Fintek F81504/508/512, BAR3/4/5 must be IORESOURCE_IO. Fintek is trying to make F81504/508/512 works on MMIO interface, but it's still in progress. We found some issue when the experiment IC when the BAR3/4/5 is IORESOURCE_MEM. It'll cause wrong operation with IO resource. So we'll add the resource check for this. Signed-off-by: Ji-Ze Hong (Peter Hong) Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_pci.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c index aa0166b6d450..29198b94ef7a 100644 --- a/drivers/tty/serial/8250/8250_pci.c +++ b/drivers/tty/serial/8250/8250_pci.c @@ -1477,11 +1477,16 @@ static int pci_fintek_init(struct pci_dev *dev) { unsigned long iobase; u32 max_port, i; - u32 bar_data[3]; + resource_size_t bar_data[3]; u8 config_base; struct serial_private *priv = pci_get_drvdata(dev); struct uart_8250_port *port; + if (!(pci_resource_flags(dev, 5) & IORESOURCE_IO) || + !(pci_resource_flags(dev, 4) & IORESOURCE_IO) || + !(pci_resource_flags(dev, 3) & IORESOURCE_IO)) + return -ENODEV; + switch (dev->device) { case 0x1104: /* 4 ports */ case 0x1108: /* 8 ports */ @@ -1495,9 +1500,9 @@ static int pci_fintek_init(struct pci_dev *dev) } /* Get the io address dispatch from the BIOS */ - pci_read_config_dword(dev, 0x24, &bar_data[0]); - pci_read_config_dword(dev, 0x20, &bar_data[1]); - pci_read_config_dword(dev, 0x1c, &bar_data[2]); + bar_data[0] = pci_resource_start(dev, 5); + bar_data[1] = pci_resource_start(dev, 4); + bar_data[2] = pci_resource_start(dev, 3); for (i = 0; i < max_port; ++i) { /* UART0 configuration offset start from 0x40 */ -- cgit v1.2.3-59-g8ed1b From 9c4b60fe5313c125b1bf68ef04b0010512c27f2d Mon Sep 17 00:00:00 2001 From: "Matwey V. Kornilov" Date: Thu, 29 Dec 2016 21:48:51 +0300 Subject: serial: 8250: moxa: Store num_ports in brd When struct moxa8250_board is allocated, then num_ports should be initialized in order to use it later in moxa8250_remove. Signed-off-by: Matwey V. Kornilov Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_moxa.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/tty/serial/8250/8250_moxa.c b/drivers/tty/serial/8250/8250_moxa.c index 26eb5393a263..d5069b2d4d79 100644 --- a/drivers/tty/serial/8250/8250_moxa.c +++ b/drivers/tty/serial/8250/8250_moxa.c @@ -68,6 +68,7 @@ static int moxa8250_probe(struct pci_dev *pdev, const struct pci_device_id *id) sizeof(unsigned int) * nr_ports, GFP_KERNEL); if (!brd) return -ENOMEM; + brd->num_ports = nr_ports; memset(&uart, 0, sizeof(struct uart_8250_port)); -- cgit v1.2.3-59-g8ed1b From abe81f3b8ed2996e1712d26d38ff6b73f582c616 Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Mon, 2 Jan 2017 11:57:20 -0300 Subject: tty: serial: msm: Fix module autoload If the driver is built as a module, autoload won't work because the module alias information is not filled. So user-space can't match the registered device with the corresponding module. Export the module alias information using the MODULE_DEVICE_TABLE() macro. Before this patch: $ modinfo drivers/tty/serial/msm_serial.ko | grep alias $ After this patch: $ modinfo drivers/tty/serial/msm_serial.ko | grep alias alias: of:N*T*Cqcom,msm-uartdmC* alias: of:N*T*Cqcom,msm-uartdm alias: of:N*T*Cqcom,msm-uartC* alias: of:N*T*Cqcom,msm-uart Signed-off-by: Javier Martinez Canillas Acked-by: Bjorn Andersson Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/msm_serial.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/tty/serial/msm_serial.c b/drivers/tty/serial/msm_serial.c index 7312e7e01b7e..6788e7532dff 100644 --- a/drivers/tty/serial/msm_serial.c +++ b/drivers/tty/serial/msm_serial.c @@ -1809,6 +1809,7 @@ static const struct of_device_id msm_match_table[] = { { .compatible = "qcom,msm-uartdm" }, {} }; +MODULE_DEVICE_TABLE(of, msm_match_table); static struct platform_driver msm_platform_driver = { .remove = msm_serial_remove, -- cgit v1.2.3-59-g8ed1b From 3f08087826950de4688da0aea4e4f64f536fcdd6 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Thu, 5 Jan 2017 23:46:20 +0200 Subject: serial: 8250_lpss: avoid potential kernel crash when remove This is a follow up to the commit a9b01b5823f7 ("serial: 8250_mid fix calltrace when hotplug 8250 serial controller") in which the kernel crash was described for another 8250 based driver. It appears that we have the very same issue in 8250_lpss. Fix it by unregistering serial driver first. Cc: Liwei Song Signed-off-by: Andy Shevchenko Reviewed-by: Bryan O'Donoghue Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_lpss.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/tty/serial/8250/8250_lpss.c b/drivers/tty/serial/8250/8250_lpss.c index 58cbb30a9401..f3ea90f0e411 100644 --- a/drivers/tty/serial/8250/8250_lpss.c +++ b/drivers/tty/serial/8250/8250_lpss.c @@ -332,10 +332,10 @@ static void lpss8250_remove(struct pci_dev *pdev) { struct lpss8250 *lpss = pci_get_drvdata(pdev); + serial8250_unregister_port(lpss->line); + if (lpss->board->exit) lpss->board->exit(lpss); - - serial8250_unregister_port(lpss->line); } static const struct lpss8250_board byt_board = { -- cgit v1.2.3-59-g8ed1b From 7b7e8e8e8fc6a9f1f0372d1ffb271ecfdaf0285a Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Sat, 7 Jan 2017 19:29:13 -0200 Subject: serial: imx: Allow passing 'rst-gpios' for rs485 mode According to Documentation/devicetree/bindings/serial/serial.txt the generic 'rts-gpios' property can be used to specify the GPIO for RTS functionality. Currently it is not possible to use the imx UART port in rs485 mode when the 'rts-gpios' property is passed in the device tree. The imx uart driver only checks for the presence of the built-in RTS pin, via 'uart-has-rtscts' property and disable the rs485 flag if this property is absent. So fix this logic by also checking if RTS pin has been passed via GPIO. Tested on a imx6dl based board. Signed-off-by: Fabio Estevam Tested-by: Clemens Gruber Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/imx.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c index a70356dad1b7..33fcc84e756b 100644 --- a/drivers/tty/serial/imx.c +++ b/drivers/tty/serial/imx.c @@ -205,6 +205,7 @@ struct imx_port { struct timer_list timer; unsigned int old_status; unsigned int have_rtscts:1; + unsigned int have_rtsgpio:1; unsigned int dte_mode:1; unsigned int irda_inv_rx:1; unsigned int irda_inv_tx:1; @@ -1725,7 +1726,7 @@ static int imx_rs485_config(struct uart_port *port, rs485conf->delay_rts_after_send = 0; /* RTS is required to control the transmitter */ - if (!sport->have_rtscts) + if (!sport->have_rtscts && !sport->have_rtsgpio) rs485conf->flags &= ~SER_RS485_ENABLED; if (rs485conf->flags & SER_RS485_ENABLED) { @@ -2048,6 +2049,9 @@ static int serial_imx_probe_dt(struct imx_port *sport, if (of_get_property(np, "fsl,dte-mode", NULL)) sport->dte_mode = 1; + if (of_get_property(np, "rts-gpios", NULL)) + sport->have_rtsgpio = 1; + return 0; } #else -- cgit v1.2.3-59-g8ed1b From 1a5c2d1de7d35f5eb9793266237903348989502b Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Mon, 9 Jan 2017 01:26:37 +0100 Subject: tty: goldfish: Fix a parameter of a call to free_irq 'request_irq()' and 'free_irq()' should be called with the same dev_id. Signed-off-by: Christophe JAILLET Signed-off-by: Greg Kroah-Hartman --- drivers/tty/goldfish.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/goldfish.c b/drivers/tty/goldfish.c index 3fc912373adf..996bd473dd03 100644 --- a/drivers/tty/goldfish.c +++ b/drivers/tty/goldfish.c @@ -300,7 +300,7 @@ static int goldfish_tty_probe(struct platform_device *pdev) return 0; err_tty_register_device_failed: - free_irq(irq, pdev); + free_irq(irq, qtty); err_request_irq_failed: goldfish_tty_current_line_count--; if (goldfish_tty_current_line_count == 0) -- cgit v1.2.3-59-g8ed1b From 699a11ba7ec869b006623182881f2f1f5b4aea53 Mon Sep 17 00:00:00 2001 From: Alexey Brodkin Date: Tue, 10 Jan 2017 18:11:29 +0300 Subject: serial: 8250_port: Remove dangerous pr_debug() With CONFIG_DYNAMIC_DEBUG if dyndbg enables debug output in 8250_port.c deadlock happens inevitably on UART IRQ handling. That's the problematic execution path: ---------------------------->8------------------------ UART IRQ: serial8250_interrupt() -> serial8250_handle_irq(): lock "port->lock" -> pr_debug() -> serial8250_console_write(): bump in locked "port->lock". OR (if above pr_debug() gets removed): serial8250_tx_chars() -> pr_debug() -> serial8250_console_write(): bump in locked "port->lock". ---------------------------->8------------------------ So let's get rid of those not that much useful debug entries. Discussed problem could be easily reproduced with QEMU for x86_64. As well as this fix could be mimicked with muting of dynamic debug for the problematic lines as simple as: ---------------------------->8------------------------ dyndbg="+p; file 8250_port.c line 1756 -p; file 8250_port.c line 1822 -p" ---------------------------->8------------------------ Signed-off-by: Alexey Brodkin Cc: Jiri Slaby Cc: Peter Hurley Cc: Phillip Raffeck Cc: Anton Wuerfel Cc: "Matwey V. Kornilov" Cc: Yegor Yefremov Cc: Thor Thayer Reviewed-by: Andy Shevchenko Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_port.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c index fe4399b41df6..3cfdd745a97a 100644 --- a/drivers/tty/serial/8250/8250_port.c +++ b/drivers/tty/serial/8250/8250_port.c @@ -1753,8 +1753,6 @@ void serial8250_tx_chars(struct uart_8250_port *up) if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) uart_write_wakeup(port); - pr_debug("%s: THRE\n", __func__); - /* * With RPM enabled, we have to wait until the FIFO is empty before the * HW can go idle. So we get here once again with empty FIFO and disable @@ -1819,8 +1817,6 @@ int serial8250_handle_irq(struct uart_port *port, unsigned int iir) status = serial_port_in(port, UART_LSR); - pr_debug("%s: status = %x\n", __func__, status); - if (status & (UART_LSR_DR | UART_LSR_BI)) { if (!up->dma || handle_rx_dma(up, iir)) status = serial8250_rx_chars(up, status); -- cgit v1.2.3-59-g8ed1b From f1e8c710e20c6e5d4546396c08bb7ac28a06ed18 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Mon, 19 Dec 2016 10:58:29 +0100 Subject: serial: 8250_pci: make option visible Hiding tristate options with "if EXPERT" is usually not a good idea. You can decide that the driver should be included by default, but you don't know if the user wants it built-in or as a module. Hiding the option prevents the user from making that decision. In this specific case, driver 8250_pci ends up being built-in as soon as SERIAL_8250=y. It is very common for distribution kernels to build the subsystem core code into the kernel, because almost everybody will need it, but build all the device drivers as modules. This should be made possible. So drop the "if EXPERT" and make SERIAL_8250_PCI visible. Signed-off-by: Jean Delvare Cc: Andy Shevchenko Cc: Jiri Slaby Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/serial/8250/Kconfig b/drivers/tty/serial/8250/Kconfig index 0b8b6740ba43..a20f52590e4d 100644 --- a/drivers/tty/serial/8250/Kconfig +++ b/drivers/tty/serial/8250/Kconfig @@ -117,7 +117,7 @@ config SERIAL_8250_DMA compatible UART controllers that support DMA signaling. config SERIAL_8250_PCI - tristate "8250/16550 PCI device support" if EXPERT + tristate "8250/16550 PCI device support" depends on SERIAL_8250 && PCI default SERIAL_8250 help -- cgit v1.2.3-59-g8ed1b From dce22df190011db408cd25430f1b19f6dec4e94f Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Mon, 19 Dec 2016 10:58:53 +0100 Subject: serial: 8250_lpss: make option visible Hiding tristate options with "if EXPERT" is usually not a good idea. You can decide that the driver should be included by default, but you don't know if the user wants it built-in or as a module. Hiding the option prevents the user from making that decision. This is even more problematic when said option selects other options. You end up with several device drivers forcibly built into the kernel. In this specific case, drivers 8250_lpss, dw_dmac_core and dw_dmac_pci end up being built-in as soon as SERIAL_8250=y. It is very common for distribution kernels to build the subsystem core code into the kernel, because almost everybody will need it, but build all the device drivers as modules. This should be made possible. So drop the "if EXPERT" and make SERIAL_8250_LPSS visible. Signed-off-by: Jean Delvare Fixes: a13e19cf3dc1 ("serial: 8250_lpss: split LPSS driver to separate module") Cc: Andy Shevchenko Cc: Jiri Slaby Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/serial/8250/Kconfig b/drivers/tty/serial/8250/Kconfig index a20f52590e4d..cd8fafe23849 100644 --- a/drivers/tty/serial/8250/Kconfig +++ b/drivers/tty/serial/8250/Kconfig @@ -402,7 +402,7 @@ config SERIAL_8250_INGENIC its UARTs, say Y to this option. If unsure, say N. config SERIAL_8250_LPSS - tristate "Support for serial ports on Intel LPSS platforms" if EXPERT + tristate "Support for serial ports on Intel LPSS platforms" default SERIAL_8250 depends on SERIAL_8250 && PCI depends on X86 || COMPILE_TEST -- cgit v1.2.3-59-g8ed1b From 194588930c5d603e574b7ecae1b55a6a774bdbe5 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Mon, 19 Dec 2016 10:59:42 +0100 Subject: serial: 8250_mid: make option visible Hiding tristate options with "if EXPERT" is usually not a good idea. You can decide that the driver should be included by default, but you don't know if the user wants it built-in or as a module. Hiding the option prevents the user from making that decision. This is even more problematic when said option selects other options. You end up with several device drivers forcibly built into the kernel. In this specific case, drivers 8250_mid, virt-dma, hsu_dma and hsu_dma_pci end up being built-in as soon as SERIAL_8250=y. It is very common for distribution kernels to build the subsystem core code into the kernel, because almost everybody will need it, but build all the device drivers as modules. This should be made possible. So drop the "if EXPERT" and make SERIAL_8250_MID visible. Signed-off-by: Jean Delvare Fixes: 1fc969c75986 ("serial: 8250_mid: make module available only on X86") Cc: Andy Shevchenko Cc: Jiri Slaby Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/serial/8250/Kconfig b/drivers/tty/serial/8250/Kconfig index cd8fafe23849..c0bf996a826e 100644 --- a/drivers/tty/serial/8250/Kconfig +++ b/drivers/tty/serial/8250/Kconfig @@ -417,7 +417,7 @@ config SERIAL_8250_LPSS - Intel Quark X1000 SoC config SERIAL_8250_MID - tristate "Support for serial ports on Intel MID platforms" if EXPERT + tristate "Support for serial ports on Intel MID platforms" default SERIAL_8250 depends on SERIAL_8250 && PCI depends on X86 || COMPILE_TEST -- cgit v1.2.3-59-g8ed1b From b2ae93e0580c8d08c6a84e9188068c0e74930112 Mon Sep 17 00:00:00 2001 From: David Lechner Date: Thu, 5 Jan 2017 12:54:17 -0600 Subject: doc: DT: Add ti,da830-uart to serial/8250 bindings This adds the ti,da830-uart compatible string to serial 8250 UART bindings. Signed-off-by: David Lechner Acked-by: Rob Herring Signed-off-by: Greg Kroah-Hartman --- Documentation/devicetree/bindings/serial/8250.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/serial/8250.txt b/Documentation/devicetree/bindings/serial/8250.txt index f86bb06c39e9..10276a46ecef 100644 --- a/Documentation/devicetree/bindings/serial/8250.txt +++ b/Documentation/devicetree/bindings/serial/8250.txt @@ -19,6 +19,7 @@ Required properties: - "altr,16550-FIFO128" - "fsl,16550-FIFO64" - "fsl,ns16550" + - "ti,da830-uart" - "serial" if the port type is unknown. - reg : offset and length of the register set for the device. - interrupts : should contain uart interrupt. -- cgit v1.2.3-59-g8ed1b From a2d6a987bfe4a2e344fae9d255200072eb082427 Mon Sep 17 00:00:00 2001 From: David Lechner Date: Thu, 5 Jan 2017 12:54:18 -0600 Subject: serial: 8250: Add new port type for TI DA8xx/66AK2x This adds a new UART port type for TI DA8xx/OMAPL13x/AM17xx/AM18xx/66AK2x. These SoCs have standard 8250 registers plus some extra non-standard registers. The UART will not function unless the non-standard Power and Emulation Management Register (PWREMU_MGMT) is configured correctly. This is currently handled in arch/arm/mach-davinci/serial.c for non-device-tree boards. Making this part of the UART driver will allow UART to work on device-tree boards as well and the mach code can eventually be removed. Signed-off-by: David Lechner Acked-by: Sekhar Nori Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_of.c | 1 + drivers/tty/serial/8250/8250_port.c | 22 ++++++++++++++++++++++ include/uapi/linux/serial_core.h | 3 ++- include/uapi/linux/serial_reg.h | 8 ++++++++ 4 files changed, 33 insertions(+), 1 deletion(-) diff --git a/drivers/tty/serial/8250/8250_of.c b/drivers/tty/serial/8250/8250_of.c index d25ab1cd4295..52812524abfb 100644 --- a/drivers/tty/serial/8250/8250_of.c +++ b/drivers/tty/serial/8250/8250_of.c @@ -332,6 +332,7 @@ static const struct of_device_id of_platform_serial_table[] = { .data = (void *)PORT_ALTR_16550_F128, }, { .compatible = "mrvl,mmp-uart", .data = (void *)PORT_XSCALE, }, + { .compatible = "ti,da830-uart", .data = (void *)PORT_DA830, }, { /* end of list */ }, }; MODULE_DEVICE_TABLE(of, of_platform_serial_table); diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c index 3cfdd745a97a..f88028a62f23 100644 --- a/drivers/tty/serial/8250/8250_port.c +++ b/drivers/tty/serial/8250/8250_port.c @@ -273,6 +273,15 @@ static const struct serial8250_config uart_config[] = { .rxtrig_bytes = {1, 4, 8, 14}, .flags = UART_CAP_FIFO, }, + [PORT_DA830] = { + .name = "TI DA8xx/66AK2x", + .fifo_size = 16, + .tx_loadsz = 16, + .fcr = UART_FCR_DMA_SELECT | UART_FCR_ENABLE_FIFO | + UART_FCR_R_TRIG_10, + .rxtrig_bytes = {1, 4, 8, 14}, + .flags = UART_CAP_FIFO | UART_CAP_AFE, + }, }; /* Uart divisor latch read */ @@ -2114,6 +2123,19 @@ int serial8250_do_startup(struct uart_port *port) serial_port_out(port, UART_LCR, 0); } + if (port->type == PORT_DA830) { + /* Reset the port */ + serial_port_out(port, UART_IER, 0); + serial_port_out(port, UART_DA830_PWREMU_MGMT, 0); + mdelay(10); + + /* Enable Tx, Rx and free run mode */ + serial_port_out(port, UART_DA830_PWREMU_MGMT, + UART_DA830_PWREMU_MGMT_UTRST | + UART_DA830_PWREMU_MGMT_URRST | + UART_DA830_PWREMU_MGMT_FREE); + } + #ifdef CONFIG_SERIAL_8250_RSA /* * If this is an RSA port, see if we can kick it up to the diff --git a/include/uapi/linux/serial_core.h b/include/uapi/linux/serial_core.h index 99dbed8a8874..9ec741b133fe 100644 --- a/include/uapi/linux/serial_core.h +++ b/include/uapi/linux/serial_core.h @@ -56,7 +56,8 @@ #define PORT_ALTR_16550_F128 28 /* Altera 16550 UART with 128 FIFOs */ #define PORT_RT2880 29 /* Ralink RT2880 internal UART */ #define PORT_16550A_FSL64 30 /* Freescale 16550 UART with 64 FIFOs */ -#define PORT_MAX_8250 30 /* max port ID */ +#define PORT_DA830 31 /* TI DA8xx/66AK2x */ +#define PORT_MAX_8250 31 /* max port ID */ /* * ARM specific type numbers. These are not currently guaranteed diff --git a/include/uapi/linux/serial_reg.h b/include/uapi/linux/serial_reg.h index b4c04842a8c0..274d8fc206e3 100644 --- a/include/uapi/linux/serial_reg.h +++ b/include/uapi/linux/serial_reg.h @@ -327,6 +327,14 @@ #define SERIAL_RSA_BAUD_BASE (921600) #define SERIAL_RSA_BAUD_BASE_LO (SERIAL_RSA_BAUD_BASE / 8) +/* Extra registers for TI DA8xx/66AK2x */ +#define UART_DA830_PWREMU_MGMT 12 + +/* PWREMU_MGMT register bits */ +#define UART_DA830_PWREMU_MGMT_FREE (1 << 0) /* Free-running mode */ +#define UART_DA830_PWREMU_MGMT_URRST (1 << 13) /* Receiver reset/enable */ +#define UART_DA830_PWREMU_MGMT_UTRST (1 << 14) /* Transmitter reset/enable */ + /* * Extra serial register definitions for the internal UARTs * in TI OMAP processors. -- cgit v1.2.3-59-g8ed1b From 9f8325b3c19cf2e5df6b9624480748421104d00c Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Wed, 11 Jan 2017 16:43:23 +0200 Subject: serial: sh-sci: Set the SCSCR TE and RE bits in the driver The Transmit Enable and Receive Enable bits are set in the scscr field of all instances of the sh-sci platform data. Set them in the driver directly to prepare for their removal from platform data. Signed-off-by: Laurent Pinchart Reviewed-by: Geert Uytterhoeven Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/sh-sci.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index b33199af8877..28e96213bad8 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -2343,7 +2343,8 @@ done: serial_port_out(port, SCFCR, ctrl); } - scr_val |= s->cfg->scscr & ~(SCSCR_CKE1 | SCSCR_CKE0); + scr_val |= SCSCR_RE | SCSCR_TE | + (s->cfg->scscr & ~(SCSCR_CKE1 | SCSCR_CKE0)); dev_dbg(port->dev, "SCSCR 0x%x\n", scr_val); serial_port_out(port, SCSCR, scr_val); if ((srr + 1 == 5) && @@ -2793,7 +2794,8 @@ static void serial_console_write(struct console *co, const char *s, /* first save SCSCR then disable interrupts, keep clock source */ ctrl = serial_port_in(port, SCSCR); - ctrl_temp = (sci_port->cfg->scscr & ~(SCSCR_CKE1 | SCSCR_CKE0)) | + ctrl_temp = SCSCR_RE | SCSCR_TE | + (sci_port->cfg->scscr & ~(SCSCR_CKE1 | SCSCR_CKE0)) | (ctrl & (SCSCR_CKE1 | SCSCR_CKE0)); serial_port_out(port, SCSCR, ctrl_temp); @@ -2996,7 +2998,6 @@ sci_parse_dt(struct platform_device *pdev, unsigned int *dev_id) p->flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF; p->type = SCI_OF_TYPE(match->data); p->regtype = SCI_OF_REGTYPE(match->data); - p->scscr = SCSCR_RE | SCSCR_TE; if (of_find_property(np, "uart-has-rtscts", NULL)) p->capabilities |= SCIx_HAVE_RTSCTS; @@ -3164,9 +3165,9 @@ static int __init early_console_setup(struct earlycon_device *device, sci_ports[0].cfg = &port_cfg; sci_ports[0].cfg->type = type; sci_probe_regmap(sci_ports[0].cfg); - port_cfg.scscr = sci_serial_in(&sci_ports[0].port, SCSCR) | - SCSCR_RE | SCSCR_TE; - sci_serial_out(&sci_ports[0].port, SCSCR, port_cfg.scscr); + port_cfg.scscr = sci_serial_in(&sci_ports[0].port, SCSCR); + sci_serial_out(&sci_ports[0].port, SCSCR, + SCSCR_RE | SCSCR_TE | port_cfg.scscr); device->con->write = serial_console_write; return 0; -- cgit v1.2.3-59-g8ed1b From 3d73f32bfa312155a0990efd95803a3e7061140c Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Wed, 11 Jan 2017 16:43:24 +0200 Subject: serial: sh-sci: Don't rely on platform data flags when not needed The UPF_BOOT_AUTOCONF platform data flag is set by all platforms, hardcode it. The UPF_IOREMAP flag is set by a single SH platform and thus needs to be kept. However, for ARM platforms, we can base the decision on whether an OF node is present and bypass the platform data flags completely. Signed-off-by: Laurent Pinchart Reviewed-by: Geert Uytterhoeven Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/sh-sci.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index 28e96213bad8..d0102bcca4ef 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -2455,7 +2455,7 @@ static int sci_remap_port(struct uart_port *port) if (port->membase) return 0; - if (port->flags & UPF_IOREMAP) { + if (port->dev->of_node || (port->flags & UPF_IOREMAP)) { port->membase = ioremap_nocache(port->mapbase, sport->reg_size); if (unlikely(!port->membase)) { dev_err(port->dev, "can't remap port#%d\n", port->line); @@ -2477,7 +2477,7 @@ static void sci_release_port(struct uart_port *port) { struct sci_port *sport = to_sci_port(port); - if (port->flags & UPF_IOREMAP) { + if (port->dev->of_node || (port->flags & UPF_IOREMAP)) { iounmap(port->membase); port->membase = NULL; } @@ -2733,7 +2733,7 @@ static int sci_init_single(struct platform_device *dev, } port->type = p->type; - port->flags = UPF_FIXED_PORT | p->flags; + port->flags = UPF_FIXED_PORT | UPF_BOOT_AUTOCONF | p->flags; port->regshift = p->regshift; /* @@ -2995,7 +2995,6 @@ sci_parse_dt(struct platform_device *pdev, unsigned int *dev_id) *dev_id = id; - p->flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF; p->type = SCI_OF_TYPE(match->data); p->regtype = SCI_OF_REGTYPE(match->data); -- cgit v1.2.3-59-g8ed1b From c3fa400b276325b57a20e1e54e6fcc18a98e962c Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Wed, 11 Jan 2017 16:43:25 +0200 Subject: sh: Don't set sh-sci pdata scscr TE and RE bits The bits are set by the driver internally, don't set them in platform data. Signed-off-by: Laurent Pinchart Reviewed-by: Geert Uytterhoeven Signed-off-by: Greg Kroah-Hartman --- arch/sh/kernel/cpu/sh2/setup-sh7619.c | 6 +++--- arch/sh/kernel/cpu/sh2a/setup-mxg.c | 2 +- arch/sh/kernel/cpu/sh2a/setup-sh7201.c | 16 ++++++++-------- arch/sh/kernel/cpu/sh2a/setup-sh7203.c | 12 ++++-------- arch/sh/kernel/cpu/sh2a/setup-sh7206.c | 8 ++++---- arch/sh/kernel/cpu/sh2a/setup-sh7264.c | 24 ++++++++---------------- arch/sh/kernel/cpu/sh2a/setup-sh7269.c | 24 ++++++++---------------- arch/sh/kernel/cpu/sh3/setup-sh7705.c | 5 ++--- arch/sh/kernel/cpu/sh3/setup-sh770x.c | 3 --- arch/sh/kernel/cpu/sh3/setup-sh7710.c | 6 ++---- arch/sh/kernel/cpu/sh3/setup-sh7720.c | 2 -- arch/sh/kernel/cpu/sh4/setup-sh4-202.c | 2 +- arch/sh/kernel/cpu/sh4/setup-sh7750.c | 3 +-- arch/sh/kernel/cpu/sh4/setup-sh7760.c | 8 ++++---- arch/sh/kernel/cpu/sh4a/setup-sh7343.c | 8 ++++---- arch/sh/kernel/cpu/sh4a/setup-sh7366.c | 2 +- arch/sh/kernel/cpu/sh4a/setup-sh7722.c | 6 +++--- arch/sh/kernel/cpu/sh4a/setup-sh7723.c | 12 ++++++------ arch/sh/kernel/cpu/sh4a/setup-sh7724.c | 9 +++------ arch/sh/kernel/cpu/sh4a/setup-sh7734.c | 12 ++++++------ arch/sh/kernel/cpu/sh4a/setup-sh7757.c | 6 +++--- arch/sh/kernel/cpu/sh4a/setup-sh7763.c | 6 +++--- arch/sh/kernel/cpu/sh4a/setup-sh7770.c | 20 ++++++++++---------- arch/sh/kernel/cpu/sh4a/setup-sh7780.c | 4 ++-- arch/sh/kernel/cpu/sh4a/setup-sh7785.c | 12 ++++++------ arch/sh/kernel/cpu/sh4a/setup-sh7786.c | 12 ++++++------ arch/sh/kernel/cpu/sh4a/setup-shx3.c | 6 +++--- arch/sh/kernel/cpu/sh5/setup-sh5.c | 2 +- 28 files changed, 103 insertions(+), 135 deletions(-) diff --git a/arch/sh/kernel/cpu/sh2/setup-sh7619.c b/arch/sh/kernel/cpu/sh2/setup-sh7619.c index 58c19adae900..f8a77bdad0a6 100644 --- a/arch/sh/kernel/cpu/sh2/setup-sh7619.c +++ b/arch/sh/kernel/cpu/sh2/setup-sh7619.c @@ -62,7 +62,7 @@ static DECLARE_INTC_DESC(intc_desc, "sh7619", vectors, NULL, static struct plat_sci_port scif0_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, + .scscr = SCSCR_REIE, .type = PORT_SCIF, }; @@ -83,7 +83,7 @@ static struct platform_device scif0_device = { static struct plat_sci_port scif1_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, + .scscr = SCSCR_REIE, .type = PORT_SCIF, }; @@ -104,7 +104,7 @@ static struct platform_device scif1_device = { static struct plat_sci_port scif2_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, + .scscr = SCSCR_REIE, .type = PORT_SCIF, }; diff --git a/arch/sh/kernel/cpu/sh2a/setup-mxg.c b/arch/sh/kernel/cpu/sh2a/setup-mxg.c index 26fcdbd4127a..fc6f0677888d 100644 --- a/arch/sh/kernel/cpu/sh2a/setup-mxg.c +++ b/arch/sh/kernel/cpu/sh2a/setup-mxg.c @@ -130,7 +130,7 @@ static struct platform_device mtu2_device = { static struct plat_sci_port scif0_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, + .scscr = SCSCR_REIE, .type = PORT_SCIF, }; diff --git a/arch/sh/kernel/cpu/sh2a/setup-sh7201.c b/arch/sh/kernel/cpu/sh2a/setup-sh7201.c index abc0ce9fb800..5b5a67082207 100644 --- a/arch/sh/kernel/cpu/sh2a/setup-sh7201.c +++ b/arch/sh/kernel/cpu/sh2a/setup-sh7201.c @@ -179,7 +179,7 @@ static DECLARE_INTC_DESC(intc_desc, "sh7201", vectors, groups, static struct plat_sci_port scif0_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, + .scscr = SCSCR_REIE, .type = PORT_SCIF, }; @@ -200,7 +200,7 @@ static struct platform_device scif0_device = { static struct plat_sci_port scif1_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, + .scscr = SCSCR_REIE, .type = PORT_SCIF, }; @@ -221,7 +221,7 @@ static struct platform_device scif1_device = { static struct plat_sci_port scif2_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, + .scscr = SCSCR_REIE, .type = PORT_SCIF, }; @@ -242,7 +242,7 @@ static struct platform_device scif2_device = { static struct plat_sci_port scif3_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, + .scscr = SCSCR_REIE, .type = PORT_SCIF, }; @@ -263,7 +263,7 @@ static struct platform_device scif3_device = { static struct plat_sci_port scif4_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, + .scscr = SCSCR_REIE, .type = PORT_SCIF, }; @@ -284,7 +284,7 @@ static struct platform_device scif4_device = { static struct plat_sci_port scif5_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, + .scscr = SCSCR_REIE, .type = PORT_SCIF, }; @@ -305,7 +305,7 @@ static struct platform_device scif5_device = { static struct plat_sci_port scif6_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, + .scscr = SCSCR_REIE, .type = PORT_SCIF, }; @@ -326,7 +326,7 @@ static struct platform_device scif6_device = { static struct plat_sci_port scif7_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, + .scscr = SCSCR_REIE, .type = PORT_SCIF, }; diff --git a/arch/sh/kernel/cpu/sh2a/setup-sh7203.c b/arch/sh/kernel/cpu/sh2a/setup-sh7203.c index 3b4894cba92f..d0d1a36d1264 100644 --- a/arch/sh/kernel/cpu/sh2a/setup-sh7203.c +++ b/arch/sh/kernel/cpu/sh2a/setup-sh7203.c @@ -175,8 +175,7 @@ static DECLARE_INTC_DESC(intc_desc, "sh7203", vectors, groups, static struct plat_sci_port scif0_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RIE | SCSCR_TIE | SCSCR_RE | SCSCR_TE | - SCSCR_REIE, + .scscr = SCSCR_RIE | SCSCR_TIE | SCSCR_REIE, .type = PORT_SCIF, .regtype = SCIx_SH2_SCIF_FIFODATA_REGTYPE, }; @@ -198,8 +197,7 @@ static struct platform_device scif0_device = { static struct plat_sci_port scif1_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RIE | SCSCR_TIE | SCSCR_RE | SCSCR_TE | - SCSCR_REIE, + .scscr = SCSCR_RIE | SCSCR_TIE | SCSCR_REIE, .type = PORT_SCIF, .regtype = SCIx_SH2_SCIF_FIFODATA_REGTYPE, }; @@ -221,8 +219,7 @@ static struct platform_device scif1_device = { static struct plat_sci_port scif2_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RIE | SCSCR_TIE | SCSCR_RE | SCSCR_TE | - SCSCR_REIE, + .scscr = SCSCR_RIE | SCSCR_TIE | SCSCR_REIE, .type = PORT_SCIF, .regtype = SCIx_SH2_SCIF_FIFODATA_REGTYPE, }; @@ -244,8 +241,7 @@ static struct platform_device scif2_device = { static struct plat_sci_port scif3_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RIE | SCSCR_TIE | SCSCR_RE | SCSCR_TE | - SCSCR_REIE, + .scscr = SCSCR_RIE | SCSCR_TIE | SCSCR_REIE, .type = PORT_SCIF, .regtype = SCIx_SH2_SCIF_FIFODATA_REGTYPE, }; diff --git a/arch/sh/kernel/cpu/sh2a/setup-sh7206.c b/arch/sh/kernel/cpu/sh2a/setup-sh7206.c index 49bc5a34bec1..c540fb8c9e09 100644 --- a/arch/sh/kernel/cpu/sh2a/setup-sh7206.c +++ b/arch/sh/kernel/cpu/sh2a/setup-sh7206.c @@ -135,7 +135,7 @@ static DECLARE_INTC_DESC(intc_desc, "sh7206", vectors, groups, static struct plat_sci_port scif0_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, + .scscr = SCSCR_REIE, .type = PORT_SCIF, }; @@ -156,7 +156,7 @@ static struct platform_device scif0_device = { static struct plat_sci_port scif1_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, + .scscr = SCSCR_REIE, .type = PORT_SCIF, }; @@ -177,7 +177,7 @@ static struct platform_device scif1_device = { static struct plat_sci_port scif2_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, + .scscr = SCSCR_REIE, .type = PORT_SCIF, }; @@ -198,7 +198,7 @@ static struct platform_device scif2_device = { static struct plat_sci_port scif3_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, + .scscr = SCSCR_REIE, .type = PORT_SCIF, }; diff --git a/arch/sh/kernel/cpu/sh2a/setup-sh7264.c b/arch/sh/kernel/cpu/sh2a/setup-sh7264.c index 608146455562..0d66fd664836 100644 --- a/arch/sh/kernel/cpu/sh2a/setup-sh7264.c +++ b/arch/sh/kernel/cpu/sh2a/setup-sh7264.c @@ -227,8 +227,7 @@ static DECLARE_INTC_DESC(intc_desc, "sh7264", vectors, groups, static struct plat_sci_port scif0_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RIE | SCSCR_TIE | SCSCR_RE | SCSCR_TE | - SCSCR_REIE | SCSCR_TOIE, + .scscr = SCSCR_RIE | SCSCR_TIE | SCSCR_REIE | SCSCR_TOIE, .type = PORT_SCIF, .regtype = SCIx_SH2_SCIF_FIFODATA_REGTYPE, }; @@ -253,8 +252,7 @@ static struct platform_device scif0_device = { static struct plat_sci_port scif1_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RIE | SCSCR_TIE | SCSCR_RE | SCSCR_TE | - SCSCR_REIE | SCSCR_TOIE, + .scscr = SCSCR_RIE | SCSCR_TIE | SCSCR_REIE | SCSCR_TOIE, .type = PORT_SCIF, .regtype = SCIx_SH2_SCIF_FIFODATA_REGTYPE, }; @@ -279,8 +277,7 @@ static struct platform_device scif1_device = { static struct plat_sci_port scif2_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RIE | SCSCR_TIE | SCSCR_RE | SCSCR_TE | - SCSCR_REIE | SCSCR_TOIE, + .scscr = SCSCR_RIE | SCSCR_TIE | SCSCR_REIE | SCSCR_TOIE, .type = PORT_SCIF, .regtype = SCIx_SH2_SCIF_FIFODATA_REGTYPE, }; @@ -305,8 +302,7 @@ static struct platform_device scif2_device = { static struct plat_sci_port scif3_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RIE | SCSCR_TIE | SCSCR_RE | SCSCR_TE | - SCSCR_REIE | SCSCR_TOIE, + .scscr = SCSCR_RIE | SCSCR_TIE | SCSCR_REIE | SCSCR_TOIE, .type = PORT_SCIF, .regtype = SCIx_SH2_SCIF_FIFODATA_REGTYPE, }; @@ -331,8 +327,7 @@ static struct platform_device scif3_device = { static struct plat_sci_port scif4_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RIE | SCSCR_TIE | SCSCR_RE | SCSCR_TE | - SCSCR_REIE | SCSCR_TOIE, + .scscr = SCSCR_RIE | SCSCR_TIE | SCSCR_REIE | SCSCR_TOIE, .type = PORT_SCIF, .regtype = SCIx_SH2_SCIF_FIFODATA_REGTYPE, }; @@ -357,8 +352,7 @@ static struct platform_device scif4_device = { static struct plat_sci_port scif5_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RIE | SCSCR_TIE | SCSCR_RE | SCSCR_TE | - SCSCR_REIE | SCSCR_TOIE, + .scscr = SCSCR_RIE | SCSCR_TIE | SCSCR_REIE | SCSCR_TOIE, .type = PORT_SCIF, .regtype = SCIx_SH2_SCIF_FIFODATA_REGTYPE, }; @@ -383,8 +377,7 @@ static struct platform_device scif5_device = { static struct plat_sci_port scif6_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RIE | SCSCR_TIE | SCSCR_RE | SCSCR_TE | - SCSCR_REIE | SCSCR_TOIE, + .scscr = SCSCR_RIE | SCSCR_TIE | SCSCR_REIE | SCSCR_TOIE, .type = PORT_SCIF, .regtype = SCIx_SH2_SCIF_FIFODATA_REGTYPE, }; @@ -409,8 +402,7 @@ static struct platform_device scif6_device = { static struct plat_sci_port scif7_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RIE | SCSCR_TIE | SCSCR_RE | SCSCR_TE | - SCSCR_REIE | SCSCR_TOIE, + .scscr = SCSCR_RIE | SCSCR_TIE | SCSCR_REIE | SCSCR_TOIE, .type = PORT_SCIF, .regtype = SCIx_SH2_SCIF_FIFODATA_REGTYPE, }; diff --git a/arch/sh/kernel/cpu/sh2a/setup-sh7269.c b/arch/sh/kernel/cpu/sh2a/setup-sh7269.c index 16ce5aa77bdd..26abbfbeb99a 100644 --- a/arch/sh/kernel/cpu/sh2a/setup-sh7269.c +++ b/arch/sh/kernel/cpu/sh2a/setup-sh7269.c @@ -249,8 +249,7 @@ static DECLARE_INTC_DESC(intc_desc, "sh7269", vectors, groups, static struct plat_sci_port scif0_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RIE | SCSCR_TIE | SCSCR_RE | SCSCR_TE | - SCSCR_REIE | SCSCR_TOIE, + .scscr = SCSCR_RIE | SCSCR_TIE | SCSCR_REIE | SCSCR_TOIE, .type = PORT_SCIF, .regtype = SCIx_SH2_SCIF_FIFODATA_REGTYPE, }; @@ -275,8 +274,7 @@ static struct platform_device scif0_device = { static struct plat_sci_port scif1_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RIE | SCSCR_TIE | SCSCR_RE | SCSCR_TE | - SCSCR_REIE | SCSCR_TOIE, + .scscr = SCSCR_RIE | SCSCR_TIE | SCSCR_REIE | SCSCR_TOIE, .type = PORT_SCIF, .regtype = SCIx_SH2_SCIF_FIFODATA_REGTYPE, }; @@ -301,8 +299,7 @@ static struct platform_device scif1_device = { static struct plat_sci_port scif2_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RIE | SCSCR_TIE | SCSCR_RE | SCSCR_TE | - SCSCR_REIE | SCSCR_TOIE, + .scscr = SCSCR_RIE | SCSCR_TIE | SCSCR_REIE | SCSCR_TOIE, .type = PORT_SCIF, .regtype = SCIx_SH2_SCIF_FIFODATA_REGTYPE, }; @@ -327,8 +324,7 @@ static struct platform_device scif2_device = { static struct plat_sci_port scif3_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RIE | SCSCR_TIE | SCSCR_RE | SCSCR_TE | - SCSCR_REIE | SCSCR_TOIE, + .scscr = SCSCR_RIE | SCSCR_TIE | SCSCR_REIE | SCSCR_TOIE, .type = PORT_SCIF, .regtype = SCIx_SH2_SCIF_FIFODATA_REGTYPE, }; @@ -353,8 +349,7 @@ static struct platform_device scif3_device = { static struct plat_sci_port scif4_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RIE | SCSCR_TIE | SCSCR_RE | SCSCR_TE | - SCSCR_REIE | SCSCR_TOIE, + .scscr = SCSCR_RIE | SCSCR_TIE | SCSCR_REIE | SCSCR_TOIE, .type = PORT_SCIF, .regtype = SCIx_SH2_SCIF_FIFODATA_REGTYPE, }; @@ -379,8 +374,7 @@ static struct platform_device scif4_device = { static struct plat_sci_port scif5_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RIE | SCSCR_TIE | SCSCR_RE | SCSCR_TE | - SCSCR_REIE | SCSCR_TOIE, + .scscr = SCSCR_RIE | SCSCR_TIE | SCSCR_REIE | SCSCR_TOIE, .type = PORT_SCIF, .regtype = SCIx_SH2_SCIF_FIFODATA_REGTYPE, }; @@ -405,8 +399,7 @@ static struct platform_device scif5_device = { static struct plat_sci_port scif6_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RIE | SCSCR_TIE | SCSCR_RE | SCSCR_TE | - SCSCR_REIE | SCSCR_TOIE, + .scscr = SCSCR_RIE | SCSCR_TIE | SCSCR_REIE | SCSCR_TOIE, .type = PORT_SCIF, .regtype = SCIx_SH2_SCIF_FIFODATA_REGTYPE, }; @@ -431,8 +424,7 @@ static struct platform_device scif6_device = { static struct plat_sci_port scif7_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RIE | SCSCR_TIE | SCSCR_RE | SCSCR_TE | - SCSCR_REIE | SCSCR_TOIE, + .scscr = SCSCR_RIE | SCSCR_TIE | SCSCR_REIE | SCSCR_TOIE, .type = PORT_SCIF, .regtype = SCIx_SH2_SCIF_FIFODATA_REGTYPE, }; diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7705.c b/arch/sh/kernel/cpu/sh3/setup-sh7705.c index 6a72fd14de21..62b1559dbe99 100644 --- a/arch/sh/kernel/cpu/sh3/setup-sh7705.c +++ b/arch/sh/kernel/cpu/sh3/setup-sh7705.c @@ -71,8 +71,7 @@ static DECLARE_INTC_DESC(intc_desc, "sh7705", vectors, NULL, static struct plat_sci_port scif0_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_TIE | SCSCR_RIE | SCSCR_TE | - SCSCR_RE | SCSCR_CKE1 | SCSCR_CKE0, + .scscr = SCSCR_TIE | SCSCR_RIE | SCSCR_CKE1 | SCSCR_CKE0, .type = PORT_SCIF, .ops = &sh770x_sci_port_ops, .regtype = SCIx_SH7705_SCIF_REGTYPE, @@ -95,7 +94,7 @@ static struct platform_device scif0_device = { static struct plat_sci_port scif1_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_TIE | SCSCR_RIE | SCSCR_TE | SCSCR_RE, + .scscr = SCSCR_TIE | SCSCR_RIE, .type = PORT_SCIF, .ops = &sh770x_sci_port_ops, .regtype = SCIx_SH7705_SCIF_REGTYPE, diff --git a/arch/sh/kernel/cpu/sh3/setup-sh770x.c b/arch/sh/kernel/cpu/sh3/setup-sh770x.c index 538c10db3537..06682ae414e2 100644 --- a/arch/sh/kernel/cpu/sh3/setup-sh770x.c +++ b/arch/sh/kernel/cpu/sh3/setup-sh770x.c @@ -111,7 +111,6 @@ static struct platform_device rtc_device = { static struct plat_sci_port scif0_platform_data = { .port_reg = 0xa4000136, .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_TE | SCSCR_RE, .type = PORT_SCI, .ops = &sh770x_sci_port_ops, .regshift = 1, @@ -136,7 +135,6 @@ static struct platform_device scif0_device = { defined(CONFIG_CPU_SUBTYPE_SH7709) static struct plat_sci_port scif1_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_TE | SCSCR_RE, .type = PORT_SCIF, .ops = &sh770x_sci_port_ops, .regtype = SCIx_SH3_SCIF_REGTYPE, @@ -162,7 +160,6 @@ static struct platform_device scif1_device = { static struct plat_sci_port scif2_platform_data = { .port_reg = SCIx_NOT_SUPPORTED, .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_TE | SCSCR_RE, .type = PORT_IRDA, .ops = &sh770x_sci_port_ops, .regshift = 1, diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7710.c b/arch/sh/kernel/cpu/sh3/setup-sh7710.c index e9ed300dba5c..6347f9625ed1 100644 --- a/arch/sh/kernel/cpu/sh3/setup-sh7710.c +++ b/arch/sh/kernel/cpu/sh3/setup-sh7710.c @@ -99,8 +99,7 @@ static struct platform_device rtc_device = { static struct plat_sci_port scif0_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_TE | SCSCR_RE | SCSCR_REIE | - SCSCR_CKE1 | SCSCR_CKE0, + .scscr = SCSCR_REIE | SCSCR_CKE1 | SCSCR_CKE0, .type = PORT_SCIF, }; @@ -121,8 +120,7 @@ static struct platform_device scif0_device = { static struct plat_sci_port scif1_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_TE | SCSCR_RE | SCSCR_REIE | - SCSCR_CKE1 | SCSCR_CKE0, + .scscr = SCSCR_REIE | SCSCR_CKE1 | SCSCR_CKE0, .type = PORT_SCIF, }; diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7720.c b/arch/sh/kernel/cpu/sh3/setup-sh7720.c index 84df85a5b800..d35400c76db7 100644 --- a/arch/sh/kernel/cpu/sh3/setup-sh7720.c +++ b/arch/sh/kernel/cpu/sh3/setup-sh7720.c @@ -53,7 +53,6 @@ static struct platform_device rtc_device = { static struct plat_sci_port scif0_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RE | SCSCR_TE, .type = PORT_SCIF, .ops = &sh7720_sci_port_ops, .regtype = SCIx_SH7705_SCIF_REGTYPE, @@ -76,7 +75,6 @@ static struct platform_device scif0_device = { static struct plat_sci_port scif1_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RE | SCSCR_TE, .type = PORT_SCIF, .ops = &sh7720_sci_port_ops, .regtype = SCIx_SH7705_SCIF_REGTYPE, diff --git a/arch/sh/kernel/cpu/sh4/setup-sh4-202.c b/arch/sh/kernel/cpu/sh4/setup-sh4-202.c index e7a7b3cdf68d..fa5f8e7b8150 100644 --- a/arch/sh/kernel/cpu/sh4/setup-sh4-202.c +++ b/arch/sh/kernel/cpu/sh4/setup-sh4-202.c @@ -18,7 +18,7 @@ static struct plat_sci_port scif0_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, + .scscr = SCSCR_REIE, .type = PORT_SCIF, }; diff --git a/arch/sh/kernel/cpu/sh4/setup-sh7750.c b/arch/sh/kernel/cpu/sh4/setup-sh7750.c index 5f08c59b9f3e..9baabdaa214e 100644 --- a/arch/sh/kernel/cpu/sh4/setup-sh7750.c +++ b/arch/sh/kernel/cpu/sh4/setup-sh7750.c @@ -40,7 +40,6 @@ static struct platform_device rtc_device = { static struct plat_sci_port sci_platform_data = { .port_reg = 0xffe0001C, .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_TE | SCSCR_RE, .type = PORT_SCI, .regshift = 2, }; @@ -62,7 +61,7 @@ static struct platform_device sci_device = { static struct plat_sci_port scif_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_TE | SCSCR_RE | SCSCR_REIE, + .scscr = SCSCR_REIE, .type = PORT_SCIF, }; diff --git a/arch/sh/kernel/cpu/sh4/setup-sh7760.c b/arch/sh/kernel/cpu/sh4/setup-sh7760.c index 973b736b3b98..c94a8f746013 100644 --- a/arch/sh/kernel/cpu/sh4/setup-sh7760.c +++ b/arch/sh/kernel/cpu/sh4/setup-sh7760.c @@ -129,7 +129,7 @@ static DECLARE_INTC_DESC(intc_desc_irq, "sh7760-irq", vectors_irq, groups, static struct plat_sci_port scif0_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, + .scscr = SCSCR_REIE, .type = PORT_SCIF, .regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE, }; @@ -155,7 +155,7 @@ static struct platform_device scif0_device = { static struct plat_sci_port scif1_platform_data = { .flags = UPF_BOOT_AUTOCONF, .type = PORT_SCIF, - .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, + .scscr = SCSCR_REIE, .regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE, }; @@ -179,7 +179,7 @@ static struct platform_device scif1_device = { static struct plat_sci_port scif2_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, + .scscr = SCSCR_REIE, .type = PORT_SCIF, .regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE, }; @@ -204,7 +204,7 @@ static struct platform_device scif2_device = { static struct plat_sci_port scif3_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, + .scscr = SCSCR_REIE, .type = PORT_SCI, .regshift = 2, }; diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7343.c b/arch/sh/kernel/cpu/sh4a/setup-sh7343.c index ceb3dedad983..9de7dc2f3c24 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7343.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7343.c @@ -19,7 +19,7 @@ /* Serial */ static struct plat_sci_port scif0_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1, + .scscr = SCSCR_CKE1, .type = PORT_SCIF, }; @@ -40,7 +40,7 @@ static struct platform_device scif0_device = { static struct plat_sci_port scif1_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1, + .scscr = SCSCR_CKE1, .type = PORT_SCIF, }; @@ -61,7 +61,7 @@ static struct platform_device scif1_device = { static struct plat_sci_port scif2_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1, + .scscr = SCSCR_CKE1, .type = PORT_SCIF, }; @@ -82,7 +82,7 @@ static struct platform_device scif2_device = { static struct plat_sci_port scif3_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1, + .scscr = SCSCR_CKE1, .type = PORT_SCIF, }; diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7366.c b/arch/sh/kernel/cpu/sh4a/setup-sh7366.c index f75f67343139..d9a8f242e148 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7366.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7366.c @@ -22,7 +22,7 @@ static struct plat_sci_port scif0_platform_data = { .port_reg = 0xa405013e, .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, + .scscr = SCSCR_REIE, .type = PORT_SCIF, }; diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c index 7aa733307afc..7d41261c5f67 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c @@ -180,7 +180,7 @@ struct platform_device dma_device = { /* Serial */ static struct plat_sci_port scif0_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, + .scscr = SCSCR_REIE, .type = PORT_SCIF, .ops = &sh7722_sci_port_ops, .regtype = SCIx_SH4_SCIF_NO_SCSPTR_REGTYPE, @@ -203,7 +203,7 @@ static struct platform_device scif0_device = { static struct plat_sci_port scif1_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, + .scscr = SCSCR_REIE, .type = PORT_SCIF, .ops = &sh7722_sci_port_ops, .regtype = SCIx_SH4_SCIF_NO_SCSPTR_REGTYPE, @@ -226,7 +226,7 @@ static struct platform_device scif1_device = { static struct plat_sci_port scif2_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, + .scscr = SCSCR_REIE, .type = PORT_SCIF, .ops = &sh7722_sci_port_ops, .regtype = SCIx_SH4_SCIF_NO_SCSPTR_REGTYPE, diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7723.c b/arch/sh/kernel/cpu/sh4a/setup-sh7723.c index 3533b56dd465..610571f174ee 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7723.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7723.c @@ -25,7 +25,7 @@ static struct plat_sci_port scif0_platform_data = { .port_reg = 0xa4050160, .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, + .scscr = SCSCR_REIE, .type = PORT_SCIF, .regtype = SCIx_SH4_SCIF_NO_SCSPTR_REGTYPE, }; @@ -48,7 +48,7 @@ static struct platform_device scif0_device = { static struct plat_sci_port scif1_platform_data = { .port_reg = SCIx_NOT_SUPPORTED, .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, + .scscr = SCSCR_REIE, .type = PORT_SCIF, .regtype = SCIx_SH4_SCIF_NO_SCSPTR_REGTYPE, }; @@ -71,7 +71,7 @@ static struct platform_device scif1_device = { static struct plat_sci_port scif2_platform_data = { .port_reg = SCIx_NOT_SUPPORTED, .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, + .scscr = SCSCR_REIE, .type = PORT_SCIF, .regtype = SCIx_SH4_SCIF_NO_SCSPTR_REGTYPE, }; @@ -94,7 +94,7 @@ static struct platform_device scif2_device = { static struct plat_sci_port scif3_platform_data = { .flags = UPF_BOOT_AUTOCONF, .port_reg = SCIx_NOT_SUPPORTED, - .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, + .scscr = SCSCR_REIE, .sampling_rate = 8, .type = PORT_SCIFA, }; @@ -117,7 +117,7 @@ static struct platform_device scif3_device = { static struct plat_sci_port scif4_platform_data = { .port_reg = SCIx_NOT_SUPPORTED, .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, + .scscr = SCSCR_REIE, .sampling_rate = 8, .type = PORT_SCIFA, }; @@ -140,7 +140,7 @@ static struct platform_device scif4_device = { static struct plat_sci_port scif5_platform_data = { .port_reg = SCIx_NOT_SUPPORTED, .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, + .scscr = SCSCR_REIE, .sampling_rate = 8, .type = PORT_SCIFA, }; diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7724.c b/arch/sh/kernel/cpu/sh4a/setup-sh7724.c index ea5780b3c7f6..478a61f73b47 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7724.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7724.c @@ -292,7 +292,7 @@ static struct platform_device dma1_device = { static struct plat_sci_port scif0_platform_data = { .port_reg = SCIx_NOT_SUPPORTED, .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, + .scscr = SCSCR_REIE, .type = PORT_SCIF, .regtype = SCIx_SH4_SCIF_NO_SCSPTR_REGTYPE, }; @@ -315,7 +315,7 @@ static struct platform_device scif0_device = { static struct plat_sci_port scif1_platform_data = { .port_reg = SCIx_NOT_SUPPORTED, .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, + .scscr = SCSCR_REIE, .type = PORT_SCIF, .regtype = SCIx_SH4_SCIF_NO_SCSPTR_REGTYPE, }; @@ -338,7 +338,7 @@ static struct platform_device scif1_device = { static struct plat_sci_port scif2_platform_data = { .port_reg = SCIx_NOT_SUPPORTED, .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, + .scscr = SCSCR_REIE, .type = PORT_SCIF, .regtype = SCIx_SH4_SCIF_NO_SCSPTR_REGTYPE, }; @@ -361,7 +361,6 @@ static struct platform_device scif2_device = { static struct plat_sci_port scif3_platform_data = { .port_reg = SCIx_NOT_SUPPORTED, .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RE | SCSCR_TE, .sampling_rate = 8, .type = PORT_SCIFA, }; @@ -384,7 +383,6 @@ static struct platform_device scif3_device = { static struct plat_sci_port scif4_platform_data = { .port_reg = SCIx_NOT_SUPPORTED, .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RE | SCSCR_TE, .sampling_rate = 8, .type = PORT_SCIFA, }; @@ -407,7 +405,6 @@ static struct platform_device scif4_device = { static struct plat_sci_port scif5_platform_data = { .port_reg = SCIx_NOT_SUPPORTED, .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RE | SCSCR_TE, .sampling_rate = 8, .type = PORT_SCIFA, }; diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7734.c b/arch/sh/kernel/cpu/sh4a/setup-sh7734.c index 69b8a50310d9..51910a8d8df4 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7734.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7734.c @@ -26,7 +26,7 @@ /* SCIF */ static struct plat_sci_port scif0_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, + .scscr = SCSCR_REIE, .type = PORT_SCIF, .regtype = SCIx_SH4_SCIF_BRG_REGTYPE, }; @@ -48,7 +48,7 @@ static struct platform_device scif0_device = { static struct plat_sci_port scif1_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, + .scscr = SCSCR_REIE, .type = PORT_SCIF, .regtype = SCIx_SH4_SCIF_BRG_REGTYPE, }; @@ -70,7 +70,7 @@ static struct platform_device scif1_device = { static struct plat_sci_port scif2_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, + .scscr = SCSCR_REIE, .type = PORT_SCIF, .regtype = SCIx_SH4_SCIF_BRG_REGTYPE, }; @@ -92,7 +92,7 @@ static struct platform_device scif2_device = { static struct plat_sci_port scif3_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_TOIE, + .scscr = SCSCR_REIE | SCSCR_TOIE, .type = PORT_SCIF, .regtype = SCIx_SH4_SCIF_BRG_REGTYPE, }; @@ -114,7 +114,7 @@ static struct platform_device scif3_device = { static struct plat_sci_port scif4_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, + .scscr = SCSCR_REIE, .type = PORT_SCIF, .regtype = SCIx_SH4_SCIF_BRG_REGTYPE, }; @@ -136,7 +136,7 @@ static struct platform_device scif4_device = { static struct plat_sci_port scif5_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, + .scscr = SCSCR_REIE, .type = PORT_SCIF, .regtype = SCIx_SH4_SCIF_BRG_REGTYPE, }; diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7757.c b/arch/sh/kernel/cpu/sh4a/setup-sh7757.c index 18bcd70cd813..b44061cb8540 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7757.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7757.c @@ -25,7 +25,7 @@ static struct plat_sci_port scif2_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, + .scscr = SCSCR_REIE, .type = PORT_SCIF, }; @@ -46,7 +46,7 @@ static struct platform_device scif2_device = { static struct plat_sci_port scif3_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, + .scscr = SCSCR_REIE, .type = PORT_SCIF, }; @@ -67,7 +67,7 @@ static struct platform_device scif3_device = { static struct plat_sci_port scif4_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, + .scscr = SCSCR_REIE, .type = PORT_SCIF, }; diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7763.c b/arch/sh/kernel/cpu/sh4a/setup-sh7763.c index 5a47d670ddec..428c16526dcb 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7763.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7763.c @@ -20,7 +20,7 @@ static struct plat_sci_port scif0_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, + .scscr = SCSCR_REIE, .type = PORT_SCIF, .regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE, }; @@ -42,7 +42,7 @@ static struct platform_device scif0_device = { static struct plat_sci_port scif1_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, + .scscr = SCSCR_REIE, .type = PORT_SCIF, .regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE, }; @@ -64,7 +64,7 @@ static struct platform_device scif1_device = { static struct plat_sci_port scif2_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, + .scscr = SCSCR_REIE, .type = PORT_SCIF, .regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE, }; diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7770.c b/arch/sh/kernel/cpu/sh4a/setup-sh7770.c index e9b532a76c37..b2d3206e2704 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7770.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7770.c @@ -17,7 +17,7 @@ static struct plat_sci_port scif0_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_TOIE, + .scscr = SCSCR_REIE | SCSCR_TOIE, .type = PORT_SCIF, }; @@ -38,7 +38,7 @@ static struct platform_device scif0_device = { static struct plat_sci_port scif1_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_TOIE, + .scscr = SCSCR_REIE | SCSCR_TOIE, .type = PORT_SCIF, }; @@ -59,7 +59,7 @@ static struct platform_device scif1_device = { static struct plat_sci_port scif2_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_TOIE, + .scscr = SCSCR_REIE | SCSCR_TOIE, .type = PORT_SCIF, }; @@ -80,7 +80,7 @@ static struct platform_device scif2_device = { static struct plat_sci_port scif3_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_TOIE, + .scscr = SCSCR_REIE | SCSCR_TOIE, .type = PORT_SCIF, }; @@ -101,7 +101,7 @@ static struct platform_device scif3_device = { static struct plat_sci_port scif4_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_TOIE, + .scscr = SCSCR_REIE | SCSCR_TOIE, .type = PORT_SCIF, }; @@ -122,7 +122,7 @@ static struct platform_device scif4_device = { static struct plat_sci_port scif5_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_TOIE, + .scscr = SCSCR_REIE | SCSCR_TOIE, .type = PORT_SCIF, }; @@ -143,7 +143,7 @@ static struct platform_device scif5_device = { static struct plat_sci_port scif6_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_TOIE, + .scscr = SCSCR_REIE | SCSCR_TOIE, .type = PORT_SCIF, }; @@ -164,7 +164,7 @@ static struct platform_device scif6_device = { static struct plat_sci_port scif7_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_TOIE, + .scscr = SCSCR_REIE | SCSCR_TOIE, .type = PORT_SCIF, }; @@ -185,7 +185,7 @@ static struct platform_device scif7_device = { static struct plat_sci_port scif8_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_TOIE, + .scscr = SCSCR_REIE | SCSCR_TOIE, .type = PORT_SCIF, }; @@ -206,7 +206,7 @@ static struct platform_device scif8_device = { static struct plat_sci_port scif9_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_TOIE, + .scscr = SCSCR_REIE | SCSCR_TOIE, .type = PORT_SCIF, }; diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7780.c b/arch/sh/kernel/cpu/sh4a/setup-sh7780.c index 3ee7dd9b3a65..59282f760ca9 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7780.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7780.c @@ -19,7 +19,7 @@ static struct plat_sci_port scif0_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_CKE1, + .scscr = SCSCR_REIE | SCSCR_CKE1, .type = PORT_SCIF, .regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE, }; @@ -41,7 +41,7 @@ static struct platform_device scif0_device = { static struct plat_sci_port scif1_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_CKE1, + .scscr = SCSCR_REIE | SCSCR_CKE1, .type = PORT_SCIF, .regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE, }; diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7785.c b/arch/sh/kernel/cpu/sh4a/setup-sh7785.c index c72d5a5d0995..22893c0f1662 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7785.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7785.c @@ -21,7 +21,7 @@ static struct plat_sci_port scif0_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_CKE1, + .scscr = SCSCR_REIE | SCSCR_CKE1, .type = PORT_SCIF, .regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE, }; @@ -43,7 +43,7 @@ static struct platform_device scif0_device = { static struct plat_sci_port scif1_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_CKE1, + .scscr = SCSCR_REIE | SCSCR_CKE1, .type = PORT_SCIF, .regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE, }; @@ -65,7 +65,7 @@ static struct platform_device scif1_device = { static struct plat_sci_port scif2_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_CKE1, + .scscr = SCSCR_REIE | SCSCR_CKE1, .type = PORT_SCIF, .regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE, }; @@ -87,7 +87,7 @@ static struct platform_device scif2_device = { static struct plat_sci_port scif3_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_CKE1, + .scscr = SCSCR_REIE | SCSCR_CKE1, .type = PORT_SCIF, .regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE, }; @@ -109,7 +109,7 @@ static struct platform_device scif3_device = { static struct plat_sci_port scif4_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_CKE1, + .scscr = SCSCR_REIE | SCSCR_CKE1, .type = PORT_SCIF, .regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE, }; @@ -131,7 +131,7 @@ static struct platform_device scif4_device = { static struct plat_sci_port scif5_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_CKE1, + .scscr = SCSCR_REIE | SCSCR_CKE1, .type = PORT_SCIF, .regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE, }; diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7786.c b/arch/sh/kernel/cpu/sh4a/setup-sh7786.c index 479e79bdd3d0..32525e13aa26 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7786.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7786.c @@ -29,7 +29,7 @@ static struct plat_sci_port scif0_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_CKE1, + .scscr = SCSCR_REIE | SCSCR_CKE1, .type = PORT_SCIF, .regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE, }; @@ -57,7 +57,7 @@ static struct platform_device scif0_device = { */ static struct plat_sci_port scif1_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_CKE1, + .scscr = SCSCR_REIE | SCSCR_CKE1, .type = PORT_SCIF, .regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE, }; @@ -88,7 +88,7 @@ static struct platform_device scif1_device = { static struct plat_sci_port scif2_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_CKE1, + .scscr = SCSCR_REIE | SCSCR_CKE1, .type = PORT_SCIF, .regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE, }; @@ -110,7 +110,7 @@ static struct platform_device scif2_device = { static struct plat_sci_port scif3_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_CKE1, + .scscr = SCSCR_REIE | SCSCR_CKE1, .type = PORT_SCIF, .regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE, }; @@ -132,7 +132,7 @@ static struct platform_device scif3_device = { static struct plat_sci_port scif4_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_CKE1, + .scscr = SCSCR_REIE | SCSCR_CKE1, .type = PORT_SCIF, .regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE, }; @@ -154,7 +154,7 @@ static struct platform_device scif4_device = { static struct plat_sci_port scif5_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_CKE1, + .scscr = SCSCR_REIE | SCSCR_CKE1, .type = PORT_SCIF, .regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE, }; diff --git a/arch/sh/kernel/cpu/sh4a/setup-shx3.c b/arch/sh/kernel/cpu/sh4a/setup-shx3.c index a78c5feb4e3b..5495d6693086 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-shx3.c +++ b/arch/sh/kernel/cpu/sh4a/setup-shx3.c @@ -29,7 +29,7 @@ */ static struct plat_sci_port scif0_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, + .scscr = SCSCR_REIE, .type = PORT_SCIF, }; @@ -53,7 +53,7 @@ static struct platform_device scif0_device = { static struct plat_sci_port scif1_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, + .scscr = SCSCR_REIE, .type = PORT_SCIF, }; @@ -77,7 +77,7 @@ static struct platform_device scif1_device = { static struct plat_sci_port scif2_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, + .scscr = SCSCR_REIE, .type = PORT_SCIF, }; diff --git a/arch/sh/kernel/cpu/sh5/setup-sh5.c b/arch/sh/kernel/cpu/sh5/setup-sh5.c index 1bf0b2cf6652..5ce34bfd0b4e 100644 --- a/arch/sh/kernel/cpu/sh5/setup-sh5.c +++ b/arch/sh/kernel/cpu/sh5/setup-sh5.c @@ -18,7 +18,7 @@ static struct plat_sci_port scif0_platform_data = { .flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP, - .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, + .scscr = SCSCR_REIE, .type = PORT_SCIF, }; -- cgit v1.2.3-59-g8ed1b From 203a1aeb5da58c2d228df057f0264efced85a57b Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Wed, 11 Jan 2017 16:43:26 +0200 Subject: sh: Don't set sh-sci pdata scscr TIE and RIE bits The scscr platform data field is used by the driver in three locations. One of them masks out all bits except SCSCR_REIE. The two other are the set_termios handler and the console write handler. The set_termios handler calls sci_start_rx() to enable the receiver, which sets the RIE bit unconditionally. It then calls sci_port_disable() that effectively disables both the transmitter and the receiver. The TIE bit will thus get set later when the serial cores reenables the serial port. The console write handler runs with interrupts disabled, and saves and restores the SCSCR register value. The RIE and TIE bits are thus not needed there. The bits are thus not necessary in platform data, remove them. Signed-off-by: Laurent Pinchart Reviewed-by: Geert Uytterhoeven Signed-off-by: Greg Kroah-Hartman --- arch/sh/kernel/cpu/sh2a/setup-sh7203.c | 8 ++++---- arch/sh/kernel/cpu/sh2a/setup-sh7264.c | 16 ++++++++-------- arch/sh/kernel/cpu/sh2a/setup-sh7269.c | 16 ++++++++-------- arch/sh/kernel/cpu/sh3/setup-sh7705.c | 3 +-- 4 files changed, 21 insertions(+), 22 deletions(-) diff --git a/arch/sh/kernel/cpu/sh2a/setup-sh7203.c b/arch/sh/kernel/cpu/sh2a/setup-sh7203.c index d0d1a36d1264..146a7d9a20fd 100644 --- a/arch/sh/kernel/cpu/sh2a/setup-sh7203.c +++ b/arch/sh/kernel/cpu/sh2a/setup-sh7203.c @@ -175,7 +175,7 @@ static DECLARE_INTC_DESC(intc_desc, "sh7203", vectors, groups, static struct plat_sci_port scif0_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RIE | SCSCR_TIE | SCSCR_REIE, + .scscr = SCSCR_REIE, .type = PORT_SCIF, .regtype = SCIx_SH2_SCIF_FIFODATA_REGTYPE, }; @@ -197,7 +197,7 @@ static struct platform_device scif0_device = { static struct plat_sci_port scif1_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RIE | SCSCR_TIE | SCSCR_REIE, + .scscr = SCSCR_REIE, .type = PORT_SCIF, .regtype = SCIx_SH2_SCIF_FIFODATA_REGTYPE, }; @@ -219,7 +219,7 @@ static struct platform_device scif1_device = { static struct plat_sci_port scif2_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RIE | SCSCR_TIE | SCSCR_REIE, + .scscr = SCSCR_REIE, .type = PORT_SCIF, .regtype = SCIx_SH2_SCIF_FIFODATA_REGTYPE, }; @@ -241,7 +241,7 @@ static struct platform_device scif2_device = { static struct plat_sci_port scif3_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RIE | SCSCR_TIE | SCSCR_REIE, + .scscr = SCSCR_REIE, .type = PORT_SCIF, .regtype = SCIx_SH2_SCIF_FIFODATA_REGTYPE, }; diff --git a/arch/sh/kernel/cpu/sh2a/setup-sh7264.c b/arch/sh/kernel/cpu/sh2a/setup-sh7264.c index 0d66fd664836..f111c20177ea 100644 --- a/arch/sh/kernel/cpu/sh2a/setup-sh7264.c +++ b/arch/sh/kernel/cpu/sh2a/setup-sh7264.c @@ -227,7 +227,7 @@ static DECLARE_INTC_DESC(intc_desc, "sh7264", vectors, groups, static struct plat_sci_port scif0_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RIE | SCSCR_TIE | SCSCR_REIE | SCSCR_TOIE, + .scscr = SCSCR_REIE | SCSCR_TOIE, .type = PORT_SCIF, .regtype = SCIx_SH2_SCIF_FIFODATA_REGTYPE, }; @@ -252,7 +252,7 @@ static struct platform_device scif0_device = { static struct plat_sci_port scif1_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RIE | SCSCR_TIE | SCSCR_REIE | SCSCR_TOIE, + .scscr = SCSCR_REIE | SCSCR_TOIE, .type = PORT_SCIF, .regtype = SCIx_SH2_SCIF_FIFODATA_REGTYPE, }; @@ -277,7 +277,7 @@ static struct platform_device scif1_device = { static struct plat_sci_port scif2_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RIE | SCSCR_TIE | SCSCR_REIE | SCSCR_TOIE, + .scscr = SCSCR_REIE | SCSCR_TOIE, .type = PORT_SCIF, .regtype = SCIx_SH2_SCIF_FIFODATA_REGTYPE, }; @@ -302,7 +302,7 @@ static struct platform_device scif2_device = { static struct plat_sci_port scif3_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RIE | SCSCR_TIE | SCSCR_REIE | SCSCR_TOIE, + .scscr = SCSCR_REIE | SCSCR_TOIE, .type = PORT_SCIF, .regtype = SCIx_SH2_SCIF_FIFODATA_REGTYPE, }; @@ -327,7 +327,7 @@ static struct platform_device scif3_device = { static struct plat_sci_port scif4_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RIE | SCSCR_TIE | SCSCR_REIE | SCSCR_TOIE, + .scscr = SCSCR_REIE | SCSCR_TOIE, .type = PORT_SCIF, .regtype = SCIx_SH2_SCIF_FIFODATA_REGTYPE, }; @@ -352,7 +352,7 @@ static struct platform_device scif4_device = { static struct plat_sci_port scif5_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RIE | SCSCR_TIE | SCSCR_REIE | SCSCR_TOIE, + .scscr = SCSCR_REIE | SCSCR_TOIE, .type = PORT_SCIF, .regtype = SCIx_SH2_SCIF_FIFODATA_REGTYPE, }; @@ -377,7 +377,7 @@ static struct platform_device scif5_device = { static struct plat_sci_port scif6_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RIE | SCSCR_TIE | SCSCR_REIE | SCSCR_TOIE, + .scscr = SCSCR_REIE | SCSCR_TOIE, .type = PORT_SCIF, .regtype = SCIx_SH2_SCIF_FIFODATA_REGTYPE, }; @@ -402,7 +402,7 @@ static struct platform_device scif6_device = { static struct plat_sci_port scif7_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RIE | SCSCR_TIE | SCSCR_REIE | SCSCR_TOIE, + .scscr = SCSCR_REIE | SCSCR_TOIE, .type = PORT_SCIF, .regtype = SCIx_SH2_SCIF_FIFODATA_REGTYPE, }; diff --git a/arch/sh/kernel/cpu/sh2a/setup-sh7269.c b/arch/sh/kernel/cpu/sh2a/setup-sh7269.c index 26abbfbeb99a..b3445e59841a 100644 --- a/arch/sh/kernel/cpu/sh2a/setup-sh7269.c +++ b/arch/sh/kernel/cpu/sh2a/setup-sh7269.c @@ -249,7 +249,7 @@ static DECLARE_INTC_DESC(intc_desc, "sh7269", vectors, groups, static struct plat_sci_port scif0_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RIE | SCSCR_TIE | SCSCR_REIE | SCSCR_TOIE, + .scscr = SCSCR_REIE | SCSCR_TOIE, .type = PORT_SCIF, .regtype = SCIx_SH2_SCIF_FIFODATA_REGTYPE, }; @@ -274,7 +274,7 @@ static struct platform_device scif0_device = { static struct plat_sci_port scif1_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RIE | SCSCR_TIE | SCSCR_REIE | SCSCR_TOIE, + .scscr = SCSCR_REIE | SCSCR_TOIE, .type = PORT_SCIF, .regtype = SCIx_SH2_SCIF_FIFODATA_REGTYPE, }; @@ -299,7 +299,7 @@ static struct platform_device scif1_device = { static struct plat_sci_port scif2_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RIE | SCSCR_TIE | SCSCR_REIE | SCSCR_TOIE, + .scscr = SCSCR_REIE | SCSCR_TOIE, .type = PORT_SCIF, .regtype = SCIx_SH2_SCIF_FIFODATA_REGTYPE, }; @@ -324,7 +324,7 @@ static struct platform_device scif2_device = { static struct plat_sci_port scif3_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RIE | SCSCR_TIE | SCSCR_REIE | SCSCR_TOIE, + .scscr = SCSCR_REIE | SCSCR_TOIE, .type = PORT_SCIF, .regtype = SCIx_SH2_SCIF_FIFODATA_REGTYPE, }; @@ -349,7 +349,7 @@ static struct platform_device scif3_device = { static struct plat_sci_port scif4_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RIE | SCSCR_TIE | SCSCR_REIE | SCSCR_TOIE, + .scscr = SCSCR_REIE | SCSCR_TOIE, .type = PORT_SCIF, .regtype = SCIx_SH2_SCIF_FIFODATA_REGTYPE, }; @@ -374,7 +374,7 @@ static struct platform_device scif4_device = { static struct plat_sci_port scif5_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RIE | SCSCR_TIE | SCSCR_REIE | SCSCR_TOIE, + .scscr = SCSCR_REIE | SCSCR_TOIE, .type = PORT_SCIF, .regtype = SCIx_SH2_SCIF_FIFODATA_REGTYPE, }; @@ -399,7 +399,7 @@ static struct platform_device scif5_device = { static struct plat_sci_port scif6_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RIE | SCSCR_TIE | SCSCR_REIE | SCSCR_TOIE, + .scscr = SCSCR_REIE | SCSCR_TOIE, .type = PORT_SCIF, .regtype = SCIx_SH2_SCIF_FIFODATA_REGTYPE, }; @@ -424,7 +424,7 @@ static struct platform_device scif6_device = { static struct plat_sci_port scif7_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RIE | SCSCR_TIE | SCSCR_REIE | SCSCR_TOIE, + .scscr = SCSCR_REIE | SCSCR_TOIE, .type = PORT_SCIF, .regtype = SCIx_SH2_SCIF_FIFODATA_REGTYPE, }; diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7705.c b/arch/sh/kernel/cpu/sh3/setup-sh7705.c index 62b1559dbe99..4f7b4f9b7d02 100644 --- a/arch/sh/kernel/cpu/sh3/setup-sh7705.c +++ b/arch/sh/kernel/cpu/sh3/setup-sh7705.c @@ -71,7 +71,7 @@ static DECLARE_INTC_DESC(intc_desc, "sh7705", vectors, NULL, static struct plat_sci_port scif0_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_TIE | SCSCR_RIE | SCSCR_CKE1 | SCSCR_CKE0, + .scscr = SCSCR_CKE1 | SCSCR_CKE0, .type = PORT_SCIF, .ops = &sh770x_sci_port_ops, .regtype = SCIx_SH7705_SCIF_REGTYPE, @@ -94,7 +94,6 @@ static struct platform_device scif0_device = { static struct plat_sci_port scif1_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_TIE | SCSCR_RIE, .type = PORT_SCIF, .ops = &sh770x_sci_port_ops, .regtype = SCIx_SH7705_SCIF_REGTYPE, -- cgit v1.2.3-59-g8ed1b From 1b10b8853157e5768014161cc83407c321e6dfa9 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Wed, 11 Jan 2017 16:43:27 +0200 Subject: sh: sh726[49]: Don't set sh-sci pdata scscr TOIE bit The SCIF ports on sh7264 and sh7269 don't support the TOIE bit according to the datasheets. Signed-off-by: Laurent Pinchart Reviewed-by: Geert Uytterhoeven Signed-off-by: Greg Kroah-Hartman --- arch/sh/kernel/cpu/sh2a/setup-sh7264.c | 16 ++++++++-------- arch/sh/kernel/cpu/sh2a/setup-sh7269.c | 16 ++++++++-------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/arch/sh/kernel/cpu/sh2a/setup-sh7264.c b/arch/sh/kernel/cpu/sh2a/setup-sh7264.c index f111c20177ea..aebaa7a4da46 100644 --- a/arch/sh/kernel/cpu/sh2a/setup-sh7264.c +++ b/arch/sh/kernel/cpu/sh2a/setup-sh7264.c @@ -227,7 +227,7 @@ static DECLARE_INTC_DESC(intc_desc, "sh7264", vectors, groups, static struct plat_sci_port scif0_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_REIE | SCSCR_TOIE, + .scscr = SCSCR_REIE, .type = PORT_SCIF, .regtype = SCIx_SH2_SCIF_FIFODATA_REGTYPE, }; @@ -252,7 +252,7 @@ static struct platform_device scif0_device = { static struct plat_sci_port scif1_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_REIE | SCSCR_TOIE, + .scscr = SCSCR_REIE, .type = PORT_SCIF, .regtype = SCIx_SH2_SCIF_FIFODATA_REGTYPE, }; @@ -277,7 +277,7 @@ static struct platform_device scif1_device = { static struct plat_sci_port scif2_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_REIE | SCSCR_TOIE, + .scscr = SCSCR_REIE, .type = PORT_SCIF, .regtype = SCIx_SH2_SCIF_FIFODATA_REGTYPE, }; @@ -302,7 +302,7 @@ static struct platform_device scif2_device = { static struct plat_sci_port scif3_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_REIE | SCSCR_TOIE, + .scscr = SCSCR_REIE, .type = PORT_SCIF, .regtype = SCIx_SH2_SCIF_FIFODATA_REGTYPE, }; @@ -327,7 +327,7 @@ static struct platform_device scif3_device = { static struct plat_sci_port scif4_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_REIE | SCSCR_TOIE, + .scscr = SCSCR_REIE, .type = PORT_SCIF, .regtype = SCIx_SH2_SCIF_FIFODATA_REGTYPE, }; @@ -352,7 +352,7 @@ static struct platform_device scif4_device = { static struct plat_sci_port scif5_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_REIE | SCSCR_TOIE, + .scscr = SCSCR_REIE, .type = PORT_SCIF, .regtype = SCIx_SH2_SCIF_FIFODATA_REGTYPE, }; @@ -377,7 +377,7 @@ static struct platform_device scif5_device = { static struct plat_sci_port scif6_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_REIE | SCSCR_TOIE, + .scscr = SCSCR_REIE, .type = PORT_SCIF, .regtype = SCIx_SH2_SCIF_FIFODATA_REGTYPE, }; @@ -402,7 +402,7 @@ static struct platform_device scif6_device = { static struct plat_sci_port scif7_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_REIE | SCSCR_TOIE, + .scscr = SCSCR_REIE, .type = PORT_SCIF, .regtype = SCIx_SH2_SCIF_FIFODATA_REGTYPE, }; diff --git a/arch/sh/kernel/cpu/sh2a/setup-sh7269.c b/arch/sh/kernel/cpu/sh2a/setup-sh7269.c index b3445e59841a..6d7ac07b4e54 100644 --- a/arch/sh/kernel/cpu/sh2a/setup-sh7269.c +++ b/arch/sh/kernel/cpu/sh2a/setup-sh7269.c @@ -249,7 +249,7 @@ static DECLARE_INTC_DESC(intc_desc, "sh7269", vectors, groups, static struct plat_sci_port scif0_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_REIE | SCSCR_TOIE, + .scscr = SCSCR_REIE, .type = PORT_SCIF, .regtype = SCIx_SH2_SCIF_FIFODATA_REGTYPE, }; @@ -274,7 +274,7 @@ static struct platform_device scif0_device = { static struct plat_sci_port scif1_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_REIE | SCSCR_TOIE, + .scscr = SCSCR_REIE, .type = PORT_SCIF, .regtype = SCIx_SH2_SCIF_FIFODATA_REGTYPE, }; @@ -299,7 +299,7 @@ static struct platform_device scif1_device = { static struct plat_sci_port scif2_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_REIE | SCSCR_TOIE, + .scscr = SCSCR_REIE, .type = PORT_SCIF, .regtype = SCIx_SH2_SCIF_FIFODATA_REGTYPE, }; @@ -324,7 +324,7 @@ static struct platform_device scif2_device = { static struct plat_sci_port scif3_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_REIE | SCSCR_TOIE, + .scscr = SCSCR_REIE, .type = PORT_SCIF, .regtype = SCIx_SH2_SCIF_FIFODATA_REGTYPE, }; @@ -349,7 +349,7 @@ static struct platform_device scif3_device = { static struct plat_sci_port scif4_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_REIE | SCSCR_TOIE, + .scscr = SCSCR_REIE, .type = PORT_SCIF, .regtype = SCIx_SH2_SCIF_FIFODATA_REGTYPE, }; @@ -374,7 +374,7 @@ static struct platform_device scif4_device = { static struct plat_sci_port scif5_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_REIE | SCSCR_TOIE, + .scscr = SCSCR_REIE, .type = PORT_SCIF, .regtype = SCIx_SH2_SCIF_FIFODATA_REGTYPE, }; @@ -399,7 +399,7 @@ static struct platform_device scif5_device = { static struct plat_sci_port scif6_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_REIE | SCSCR_TOIE, + .scscr = SCSCR_REIE, .type = PORT_SCIF, .regtype = SCIx_SH2_SCIF_FIFODATA_REGTYPE, }; @@ -424,7 +424,7 @@ static struct platform_device scif6_device = { static struct plat_sci_port scif7_platform_data = { .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_REIE | SCSCR_TOIE, + .scscr = SCSCR_REIE, .type = PORT_SCIF, .regtype = SCIx_SH2_SCIF_FIFODATA_REGTYPE, }; -- cgit v1.2.3-59-g8ed1b From 9c21ac508c6a75ba2670efe25f6de902ce32e98e Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Wed, 11 Jan 2017 16:43:28 +0200 Subject: sh: Don't set the sh-sci pdata UPF_BOOT_AUTOCONF flags The flag is set by the driver internally, don't set it in platform data. Signed-off-by: Laurent Pinchart Reviewed-by: Geert Uytterhoeven Signed-off-by: Greg Kroah-Hartman --- arch/sh/kernel/cpu/sh2/setup-sh7619.c | 3 --- arch/sh/kernel/cpu/sh2a/setup-mxg.c | 1 - arch/sh/kernel/cpu/sh2a/setup-sh7201.c | 8 -------- arch/sh/kernel/cpu/sh2a/setup-sh7203.c | 4 ---- arch/sh/kernel/cpu/sh2a/setup-sh7206.c | 4 ---- arch/sh/kernel/cpu/sh2a/setup-sh7264.c | 8 -------- arch/sh/kernel/cpu/sh2a/setup-sh7269.c | 8 -------- arch/sh/kernel/cpu/sh3/setup-sh7705.c | 2 -- arch/sh/kernel/cpu/sh3/setup-sh770x.c | 3 --- arch/sh/kernel/cpu/sh3/setup-sh7710.c | 2 -- arch/sh/kernel/cpu/sh3/setup-sh7720.c | 2 -- arch/sh/kernel/cpu/sh4/setup-sh4-202.c | 1 - arch/sh/kernel/cpu/sh4/setup-sh7750.c | 2 -- arch/sh/kernel/cpu/sh4/setup-sh7760.c | 4 ---- arch/sh/kernel/cpu/sh4a/setup-sh7343.c | 4 ---- arch/sh/kernel/cpu/sh4a/setup-sh7366.c | 1 - arch/sh/kernel/cpu/sh4a/setup-sh7722.c | 3 --- arch/sh/kernel/cpu/sh4a/setup-sh7723.c | 6 ------ arch/sh/kernel/cpu/sh4a/setup-sh7724.c | 6 ------ arch/sh/kernel/cpu/sh4a/setup-sh7734.c | 6 ------ arch/sh/kernel/cpu/sh4a/setup-sh7757.c | 3 --- arch/sh/kernel/cpu/sh4a/setup-sh7763.c | 3 --- arch/sh/kernel/cpu/sh4a/setup-sh7770.c | 10 ---------- arch/sh/kernel/cpu/sh4a/setup-sh7780.c | 2 -- arch/sh/kernel/cpu/sh4a/setup-sh7785.c | 6 ------ arch/sh/kernel/cpu/sh4a/setup-sh7786.c | 6 ------ arch/sh/kernel/cpu/sh4a/setup-shx3.c | 3 --- arch/sh/kernel/cpu/sh5/setup-sh5.c | 2 +- 28 files changed, 1 insertion(+), 112 deletions(-) diff --git a/arch/sh/kernel/cpu/sh2/setup-sh7619.c b/arch/sh/kernel/cpu/sh2/setup-sh7619.c index f8a77bdad0a6..95796ad00fbe 100644 --- a/arch/sh/kernel/cpu/sh2/setup-sh7619.c +++ b/arch/sh/kernel/cpu/sh2/setup-sh7619.c @@ -61,7 +61,6 @@ static DECLARE_INTC_DESC(intc_desc, "sh7619", vectors, NULL, NULL, prio_registers, NULL); static struct plat_sci_port scif0_platform_data = { - .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_REIE, .type = PORT_SCIF, }; @@ -82,7 +81,6 @@ static struct platform_device scif0_device = { }; static struct plat_sci_port scif1_platform_data = { - .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_REIE, .type = PORT_SCIF, }; @@ -103,7 +101,6 @@ static struct platform_device scif1_device = { }; static struct plat_sci_port scif2_platform_data = { - .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_REIE, .type = PORT_SCIF, }; diff --git a/arch/sh/kernel/cpu/sh2a/setup-mxg.c b/arch/sh/kernel/cpu/sh2a/setup-mxg.c index fc6f0677888d..060fdd369f09 100644 --- a/arch/sh/kernel/cpu/sh2a/setup-mxg.c +++ b/arch/sh/kernel/cpu/sh2a/setup-mxg.c @@ -129,7 +129,6 @@ static struct platform_device mtu2_device = { }; static struct plat_sci_port scif0_platform_data = { - .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_REIE, .type = PORT_SCIF, }; diff --git a/arch/sh/kernel/cpu/sh2a/setup-sh7201.c b/arch/sh/kernel/cpu/sh2a/setup-sh7201.c index 5b5a67082207..c1301f68d3cd 100644 --- a/arch/sh/kernel/cpu/sh2a/setup-sh7201.c +++ b/arch/sh/kernel/cpu/sh2a/setup-sh7201.c @@ -178,7 +178,6 @@ static DECLARE_INTC_DESC(intc_desc, "sh7201", vectors, groups, mask_registers, prio_registers, NULL); static struct plat_sci_port scif0_platform_data = { - .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_REIE, .type = PORT_SCIF, }; @@ -199,7 +198,6 @@ static struct platform_device scif0_device = { }; static struct plat_sci_port scif1_platform_data = { - .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_REIE, .type = PORT_SCIF, }; @@ -220,7 +218,6 @@ static struct platform_device scif1_device = { }; static struct plat_sci_port scif2_platform_data = { - .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_REIE, .type = PORT_SCIF, }; @@ -241,7 +238,6 @@ static struct platform_device scif2_device = { }; static struct plat_sci_port scif3_platform_data = { - .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_REIE, .type = PORT_SCIF, }; @@ -262,7 +258,6 @@ static struct platform_device scif3_device = { }; static struct plat_sci_port scif4_platform_data = { - .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_REIE, .type = PORT_SCIF, }; @@ -283,7 +278,6 @@ static struct platform_device scif4_device = { }; static struct plat_sci_port scif5_platform_data = { - .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_REIE, .type = PORT_SCIF, }; @@ -304,7 +298,6 @@ static struct platform_device scif5_device = { }; static struct plat_sci_port scif6_platform_data = { - .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_REIE, .type = PORT_SCIF, }; @@ -325,7 +318,6 @@ static struct platform_device scif6_device = { }; static struct plat_sci_port scif7_platform_data = { - .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_REIE, .type = PORT_SCIF, }; diff --git a/arch/sh/kernel/cpu/sh2a/setup-sh7203.c b/arch/sh/kernel/cpu/sh2a/setup-sh7203.c index 146a7d9a20fd..32ec732e28e5 100644 --- a/arch/sh/kernel/cpu/sh2a/setup-sh7203.c +++ b/arch/sh/kernel/cpu/sh2a/setup-sh7203.c @@ -174,7 +174,6 @@ static DECLARE_INTC_DESC(intc_desc, "sh7203", vectors, groups, mask_registers, prio_registers, NULL); static struct plat_sci_port scif0_platform_data = { - .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_REIE, .type = PORT_SCIF, .regtype = SCIx_SH2_SCIF_FIFODATA_REGTYPE, @@ -196,7 +195,6 @@ static struct platform_device scif0_device = { }; static struct plat_sci_port scif1_platform_data = { - .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_REIE, .type = PORT_SCIF, .regtype = SCIx_SH2_SCIF_FIFODATA_REGTYPE, @@ -218,7 +216,6 @@ static struct platform_device scif1_device = { }; static struct plat_sci_port scif2_platform_data = { - .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_REIE, .type = PORT_SCIF, .regtype = SCIx_SH2_SCIF_FIFODATA_REGTYPE, @@ -240,7 +237,6 @@ static struct platform_device scif2_device = { }; static struct plat_sci_port scif3_platform_data = { - .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_REIE, .type = PORT_SCIF, .regtype = SCIx_SH2_SCIF_FIFODATA_REGTYPE, diff --git a/arch/sh/kernel/cpu/sh2a/setup-sh7206.c b/arch/sh/kernel/cpu/sh2a/setup-sh7206.c index c540fb8c9e09..8d8d354851ce 100644 --- a/arch/sh/kernel/cpu/sh2a/setup-sh7206.c +++ b/arch/sh/kernel/cpu/sh2a/setup-sh7206.c @@ -134,7 +134,6 @@ static DECLARE_INTC_DESC(intc_desc, "sh7206", vectors, groups, mask_registers, prio_registers, NULL); static struct plat_sci_port scif0_platform_data = { - .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_REIE, .type = PORT_SCIF, }; @@ -155,7 +154,6 @@ static struct platform_device scif0_device = { }; static struct plat_sci_port scif1_platform_data = { - .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_REIE, .type = PORT_SCIF, }; @@ -176,7 +174,6 @@ static struct platform_device scif1_device = { }; static struct plat_sci_port scif2_platform_data = { - .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_REIE, .type = PORT_SCIF, }; @@ -197,7 +194,6 @@ static struct platform_device scif2_device = { }; static struct plat_sci_port scif3_platform_data = { - .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_REIE, .type = PORT_SCIF, }; diff --git a/arch/sh/kernel/cpu/sh2a/setup-sh7264.c b/arch/sh/kernel/cpu/sh2a/setup-sh7264.c index aebaa7a4da46..ab71eab690fd 100644 --- a/arch/sh/kernel/cpu/sh2a/setup-sh7264.c +++ b/arch/sh/kernel/cpu/sh2a/setup-sh7264.c @@ -226,7 +226,6 @@ static DECLARE_INTC_DESC(intc_desc, "sh7264", vectors, groups, mask_registers, prio_registers, NULL); static struct plat_sci_port scif0_platform_data = { - .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_REIE, .type = PORT_SCIF, .regtype = SCIx_SH2_SCIF_FIFODATA_REGTYPE, @@ -251,7 +250,6 @@ static struct platform_device scif0_device = { }; static struct plat_sci_port scif1_platform_data = { - .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_REIE, .type = PORT_SCIF, .regtype = SCIx_SH2_SCIF_FIFODATA_REGTYPE, @@ -276,7 +274,6 @@ static struct platform_device scif1_device = { }; static struct plat_sci_port scif2_platform_data = { - .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_REIE, .type = PORT_SCIF, .regtype = SCIx_SH2_SCIF_FIFODATA_REGTYPE, @@ -301,7 +298,6 @@ static struct platform_device scif2_device = { }; static struct plat_sci_port scif3_platform_data = { - .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_REIE, .type = PORT_SCIF, .regtype = SCIx_SH2_SCIF_FIFODATA_REGTYPE, @@ -326,7 +322,6 @@ static struct platform_device scif3_device = { }; static struct plat_sci_port scif4_platform_data = { - .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_REIE, .type = PORT_SCIF, .regtype = SCIx_SH2_SCIF_FIFODATA_REGTYPE, @@ -351,7 +346,6 @@ static struct platform_device scif4_device = { }; static struct plat_sci_port scif5_platform_data = { - .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_REIE, .type = PORT_SCIF, .regtype = SCIx_SH2_SCIF_FIFODATA_REGTYPE, @@ -376,7 +370,6 @@ static struct platform_device scif5_device = { }; static struct plat_sci_port scif6_platform_data = { - .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_REIE, .type = PORT_SCIF, .regtype = SCIx_SH2_SCIF_FIFODATA_REGTYPE, @@ -401,7 +394,6 @@ static struct platform_device scif6_device = { }; static struct plat_sci_port scif7_platform_data = { - .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_REIE, .type = PORT_SCIF, .regtype = SCIx_SH2_SCIF_FIFODATA_REGTYPE, diff --git a/arch/sh/kernel/cpu/sh2a/setup-sh7269.c b/arch/sh/kernel/cpu/sh2a/setup-sh7269.c index 6d7ac07b4e54..c7e81b20967c 100644 --- a/arch/sh/kernel/cpu/sh2a/setup-sh7269.c +++ b/arch/sh/kernel/cpu/sh2a/setup-sh7269.c @@ -248,7 +248,6 @@ static DECLARE_INTC_DESC(intc_desc, "sh7269", vectors, groups, mask_registers, prio_registers, NULL); static struct plat_sci_port scif0_platform_data = { - .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_REIE, .type = PORT_SCIF, .regtype = SCIx_SH2_SCIF_FIFODATA_REGTYPE, @@ -273,7 +272,6 @@ static struct platform_device scif0_device = { }; static struct plat_sci_port scif1_platform_data = { - .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_REIE, .type = PORT_SCIF, .regtype = SCIx_SH2_SCIF_FIFODATA_REGTYPE, @@ -298,7 +296,6 @@ static struct platform_device scif1_device = { }; static struct plat_sci_port scif2_platform_data = { - .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_REIE, .type = PORT_SCIF, .regtype = SCIx_SH2_SCIF_FIFODATA_REGTYPE, @@ -323,7 +320,6 @@ static struct platform_device scif2_device = { }; static struct plat_sci_port scif3_platform_data = { - .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_REIE, .type = PORT_SCIF, .regtype = SCIx_SH2_SCIF_FIFODATA_REGTYPE, @@ -348,7 +344,6 @@ static struct platform_device scif3_device = { }; static struct plat_sci_port scif4_platform_data = { - .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_REIE, .type = PORT_SCIF, .regtype = SCIx_SH2_SCIF_FIFODATA_REGTYPE, @@ -373,7 +368,6 @@ static struct platform_device scif4_device = { }; static struct plat_sci_port scif5_platform_data = { - .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_REIE, .type = PORT_SCIF, .regtype = SCIx_SH2_SCIF_FIFODATA_REGTYPE, @@ -398,7 +392,6 @@ static struct platform_device scif5_device = { }; static struct plat_sci_port scif6_platform_data = { - .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_REIE, .type = PORT_SCIF, .regtype = SCIx_SH2_SCIF_FIFODATA_REGTYPE, @@ -423,7 +416,6 @@ static struct platform_device scif6_device = { }; static struct plat_sci_port scif7_platform_data = { - .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_REIE, .type = PORT_SCIF, .regtype = SCIx_SH2_SCIF_FIFODATA_REGTYPE, diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7705.c b/arch/sh/kernel/cpu/sh3/setup-sh7705.c index 4f7b4f9b7d02..a60edd8f3db7 100644 --- a/arch/sh/kernel/cpu/sh3/setup-sh7705.c +++ b/arch/sh/kernel/cpu/sh3/setup-sh7705.c @@ -70,7 +70,6 @@ static DECLARE_INTC_DESC(intc_desc, "sh7705", vectors, NULL, NULL, prio_registers, NULL); static struct plat_sci_port scif0_platform_data = { - .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_CKE1 | SCSCR_CKE0, .type = PORT_SCIF, .ops = &sh770x_sci_port_ops, @@ -93,7 +92,6 @@ static struct platform_device scif0_device = { }; static struct plat_sci_port scif1_platform_data = { - .flags = UPF_BOOT_AUTOCONF, .type = PORT_SCIF, .ops = &sh770x_sci_port_ops, .regtype = SCIx_SH7705_SCIF_REGTYPE, diff --git a/arch/sh/kernel/cpu/sh3/setup-sh770x.c b/arch/sh/kernel/cpu/sh3/setup-sh770x.c index 06682ae414e2..e64fe24d860c 100644 --- a/arch/sh/kernel/cpu/sh3/setup-sh770x.c +++ b/arch/sh/kernel/cpu/sh3/setup-sh770x.c @@ -110,7 +110,6 @@ static struct platform_device rtc_device = { static struct plat_sci_port scif0_platform_data = { .port_reg = 0xa4000136, - .flags = UPF_BOOT_AUTOCONF, .type = PORT_SCI, .ops = &sh770x_sci_port_ops, .regshift = 1, @@ -134,7 +133,6 @@ static struct platform_device scif0_device = { defined(CONFIG_CPU_SUBTYPE_SH7707) || \ defined(CONFIG_CPU_SUBTYPE_SH7709) static struct plat_sci_port scif1_platform_data = { - .flags = UPF_BOOT_AUTOCONF, .type = PORT_SCIF, .ops = &sh770x_sci_port_ops, .regtype = SCIx_SH3_SCIF_REGTYPE, @@ -159,7 +157,6 @@ static struct platform_device scif1_device = { defined(CONFIG_CPU_SUBTYPE_SH7709) static struct plat_sci_port scif2_platform_data = { .port_reg = SCIx_NOT_SUPPORTED, - .flags = UPF_BOOT_AUTOCONF, .type = PORT_IRDA, .ops = &sh770x_sci_port_ops, .regshift = 1, diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7710.c b/arch/sh/kernel/cpu/sh3/setup-sh7710.c index 6347f9625ed1..ac2a0aabcec5 100644 --- a/arch/sh/kernel/cpu/sh3/setup-sh7710.c +++ b/arch/sh/kernel/cpu/sh3/setup-sh7710.c @@ -98,7 +98,6 @@ static struct platform_device rtc_device = { }; static struct plat_sci_port scif0_platform_data = { - .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_REIE | SCSCR_CKE1 | SCSCR_CKE0, .type = PORT_SCIF, }; @@ -119,7 +118,6 @@ static struct platform_device scif0_device = { }; static struct plat_sci_port scif1_platform_data = { - .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_REIE | SCSCR_CKE1 | SCSCR_CKE0, .type = PORT_SCIF, }; diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7720.c b/arch/sh/kernel/cpu/sh3/setup-sh7720.c index d35400c76db7..bf34b4e2e9ef 100644 --- a/arch/sh/kernel/cpu/sh3/setup-sh7720.c +++ b/arch/sh/kernel/cpu/sh3/setup-sh7720.c @@ -52,7 +52,6 @@ static struct platform_device rtc_device = { }; static struct plat_sci_port scif0_platform_data = { - .flags = UPF_BOOT_AUTOCONF, .type = PORT_SCIF, .ops = &sh7720_sci_port_ops, .regtype = SCIx_SH7705_SCIF_REGTYPE, @@ -74,7 +73,6 @@ static struct platform_device scif0_device = { }; static struct plat_sci_port scif1_platform_data = { - .flags = UPF_BOOT_AUTOCONF, .type = PORT_SCIF, .ops = &sh7720_sci_port_ops, .regtype = SCIx_SH7705_SCIF_REGTYPE, diff --git a/arch/sh/kernel/cpu/sh4/setup-sh4-202.c b/arch/sh/kernel/cpu/sh4/setup-sh4-202.c index fa5f8e7b8150..2623f820d510 100644 --- a/arch/sh/kernel/cpu/sh4/setup-sh4-202.c +++ b/arch/sh/kernel/cpu/sh4/setup-sh4-202.c @@ -17,7 +17,6 @@ #include static struct plat_sci_port scif0_platform_data = { - .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_REIE, .type = PORT_SCIF, }; diff --git a/arch/sh/kernel/cpu/sh4/setup-sh7750.c b/arch/sh/kernel/cpu/sh4/setup-sh7750.c index 9baabdaa214e..f693f122a286 100644 --- a/arch/sh/kernel/cpu/sh4/setup-sh7750.c +++ b/arch/sh/kernel/cpu/sh4/setup-sh7750.c @@ -39,7 +39,6 @@ static struct platform_device rtc_device = { static struct plat_sci_port sci_platform_data = { .port_reg = 0xffe0001C, - .flags = UPF_BOOT_AUTOCONF, .type = PORT_SCI, .regshift = 2, }; @@ -60,7 +59,6 @@ static struct platform_device sci_device = { }; static struct plat_sci_port scif_platform_data = { - .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_REIE, .type = PORT_SCIF, }; diff --git a/arch/sh/kernel/cpu/sh4/setup-sh7760.c b/arch/sh/kernel/cpu/sh4/setup-sh7760.c index c94a8f746013..641b85865a63 100644 --- a/arch/sh/kernel/cpu/sh4/setup-sh7760.c +++ b/arch/sh/kernel/cpu/sh4/setup-sh7760.c @@ -128,7 +128,6 @@ static DECLARE_INTC_DESC(intc_desc_irq, "sh7760-irq", vectors_irq, groups, mask_registers, prio_registers, NULL); static struct plat_sci_port scif0_platform_data = { - .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_REIE, .type = PORT_SCIF, .regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE, @@ -153,7 +152,6 @@ static struct platform_device scif0_device = { }; static struct plat_sci_port scif1_platform_data = { - .flags = UPF_BOOT_AUTOCONF, .type = PORT_SCIF, .scscr = SCSCR_REIE, .regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE, @@ -178,7 +176,6 @@ static struct platform_device scif1_device = { }; static struct plat_sci_port scif2_platform_data = { - .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_REIE, .type = PORT_SCIF, .regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE, @@ -203,7 +200,6 @@ static struct platform_device scif2_device = { }; static struct plat_sci_port scif3_platform_data = { - .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_REIE, .type = PORT_SCI, .regshift = 2, diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7343.c b/arch/sh/kernel/cpu/sh4a/setup-sh7343.c index 9de7dc2f3c24..5788073a7c30 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7343.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7343.c @@ -18,7 +18,6 @@ /* Serial */ static struct plat_sci_port scif0_platform_data = { - .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_CKE1, .type = PORT_SCIF, }; @@ -39,7 +38,6 @@ static struct platform_device scif0_device = { }; static struct plat_sci_port scif1_platform_data = { - .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_CKE1, .type = PORT_SCIF, }; @@ -60,7 +58,6 @@ static struct platform_device scif1_device = { }; static struct plat_sci_port scif2_platform_data = { - .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_CKE1, .type = PORT_SCIF, }; @@ -81,7 +78,6 @@ static struct platform_device scif2_device = { }; static struct plat_sci_port scif3_platform_data = { - .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_CKE1, .type = PORT_SCIF, }; diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7366.c b/arch/sh/kernel/cpu/sh4a/setup-sh7366.c index d9a8f242e148..3fc1a3ab634e 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7366.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7366.c @@ -21,7 +21,6 @@ static struct plat_sci_port scif0_platform_data = { .port_reg = 0xa405013e, - .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_REIE, .type = PORT_SCIF, }; diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c index 7d41261c5f67..6b3a26e61abb 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c @@ -179,7 +179,6 @@ struct platform_device dma_device = { /* Serial */ static struct plat_sci_port scif0_platform_data = { - .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_REIE, .type = PORT_SCIF, .ops = &sh7722_sci_port_ops, @@ -202,7 +201,6 @@ static struct platform_device scif0_device = { }; static struct plat_sci_port scif1_platform_data = { - .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_REIE, .type = PORT_SCIF, .ops = &sh7722_sci_port_ops, @@ -225,7 +223,6 @@ static struct platform_device scif1_device = { }; static struct plat_sci_port scif2_platform_data = { - .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_REIE, .type = PORT_SCIF, .ops = &sh7722_sci_port_ops, diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7723.c b/arch/sh/kernel/cpu/sh4a/setup-sh7723.c index 610571f174ee..9f47ec950af8 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7723.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7723.c @@ -24,7 +24,6 @@ /* Serial */ static struct plat_sci_port scif0_platform_data = { .port_reg = 0xa4050160, - .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_REIE, .type = PORT_SCIF, .regtype = SCIx_SH4_SCIF_NO_SCSPTR_REGTYPE, @@ -47,7 +46,6 @@ static struct platform_device scif0_device = { static struct plat_sci_port scif1_platform_data = { .port_reg = SCIx_NOT_SUPPORTED, - .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_REIE, .type = PORT_SCIF, .regtype = SCIx_SH4_SCIF_NO_SCSPTR_REGTYPE, @@ -70,7 +68,6 @@ static struct platform_device scif1_device = { static struct plat_sci_port scif2_platform_data = { .port_reg = SCIx_NOT_SUPPORTED, - .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_REIE, .type = PORT_SCIF, .regtype = SCIx_SH4_SCIF_NO_SCSPTR_REGTYPE, @@ -92,7 +89,6 @@ static struct platform_device scif2_device = { }; static struct plat_sci_port scif3_platform_data = { - .flags = UPF_BOOT_AUTOCONF, .port_reg = SCIx_NOT_SUPPORTED, .scscr = SCSCR_REIE, .sampling_rate = 8, @@ -116,7 +112,6 @@ static struct platform_device scif3_device = { static struct plat_sci_port scif4_platform_data = { .port_reg = SCIx_NOT_SUPPORTED, - .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_REIE, .sampling_rate = 8, .type = PORT_SCIFA, @@ -139,7 +134,6 @@ static struct platform_device scif4_device = { static struct plat_sci_port scif5_platform_data = { .port_reg = SCIx_NOT_SUPPORTED, - .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_REIE, .sampling_rate = 8, .type = PORT_SCIFA, diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7724.c b/arch/sh/kernel/cpu/sh4a/setup-sh7724.c index 478a61f73b47..3ce55884c787 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7724.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7724.c @@ -291,7 +291,6 @@ static struct platform_device dma1_device = { /* Serial */ static struct plat_sci_port scif0_platform_data = { .port_reg = SCIx_NOT_SUPPORTED, - .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_REIE, .type = PORT_SCIF, .regtype = SCIx_SH4_SCIF_NO_SCSPTR_REGTYPE, @@ -314,7 +313,6 @@ static struct platform_device scif0_device = { static struct plat_sci_port scif1_platform_data = { .port_reg = SCIx_NOT_SUPPORTED, - .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_REIE, .type = PORT_SCIF, .regtype = SCIx_SH4_SCIF_NO_SCSPTR_REGTYPE, @@ -337,7 +335,6 @@ static struct platform_device scif1_device = { static struct plat_sci_port scif2_platform_data = { .port_reg = SCIx_NOT_SUPPORTED, - .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_REIE, .type = PORT_SCIF, .regtype = SCIx_SH4_SCIF_NO_SCSPTR_REGTYPE, @@ -360,7 +357,6 @@ static struct platform_device scif2_device = { static struct plat_sci_port scif3_platform_data = { .port_reg = SCIx_NOT_SUPPORTED, - .flags = UPF_BOOT_AUTOCONF, .sampling_rate = 8, .type = PORT_SCIFA, }; @@ -382,7 +378,6 @@ static struct platform_device scif3_device = { static struct plat_sci_port scif4_platform_data = { .port_reg = SCIx_NOT_SUPPORTED, - .flags = UPF_BOOT_AUTOCONF, .sampling_rate = 8, .type = PORT_SCIFA, }; @@ -404,7 +399,6 @@ static struct platform_device scif4_device = { static struct plat_sci_port scif5_platform_data = { .port_reg = SCIx_NOT_SUPPORTED, - .flags = UPF_BOOT_AUTOCONF, .sampling_rate = 8, .type = PORT_SCIFA, }; diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7734.c b/arch/sh/kernel/cpu/sh4a/setup-sh7734.c index 51910a8d8df4..8c0c9da6b5b3 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7734.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7734.c @@ -25,7 +25,6 @@ /* SCIF */ static struct plat_sci_port scif0_platform_data = { - .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_REIE, .type = PORT_SCIF, .regtype = SCIx_SH4_SCIF_BRG_REGTYPE, @@ -47,7 +46,6 @@ static struct platform_device scif0_device = { }; static struct plat_sci_port scif1_platform_data = { - .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_REIE, .type = PORT_SCIF, .regtype = SCIx_SH4_SCIF_BRG_REGTYPE, @@ -69,7 +67,6 @@ static struct platform_device scif1_device = { }; static struct plat_sci_port scif2_platform_data = { - .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_REIE, .type = PORT_SCIF, .regtype = SCIx_SH4_SCIF_BRG_REGTYPE, @@ -91,7 +88,6 @@ static struct platform_device scif2_device = { }; static struct plat_sci_port scif3_platform_data = { - .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_REIE | SCSCR_TOIE, .type = PORT_SCIF, .regtype = SCIx_SH4_SCIF_BRG_REGTYPE, @@ -113,7 +109,6 @@ static struct platform_device scif3_device = { }; static struct plat_sci_port scif4_platform_data = { - .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_REIE, .type = PORT_SCIF, .regtype = SCIx_SH4_SCIF_BRG_REGTYPE, @@ -135,7 +130,6 @@ static struct platform_device scif4_device = { }; static struct plat_sci_port scif5_platform_data = { - .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_REIE, .type = PORT_SCIF, .regtype = SCIx_SH4_SCIF_BRG_REGTYPE, diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7757.c b/arch/sh/kernel/cpu/sh4a/setup-sh7757.c index b44061cb8540..a46a19b49e08 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7757.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7757.c @@ -24,7 +24,6 @@ #include static struct plat_sci_port scif2_platform_data = { - .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_REIE, .type = PORT_SCIF, }; @@ -45,7 +44,6 @@ static struct platform_device scif2_device = { }; static struct plat_sci_port scif3_platform_data = { - .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_REIE, .type = PORT_SCIF, }; @@ -66,7 +64,6 @@ static struct platform_device scif3_device = { }; static struct plat_sci_port scif4_platform_data = { - .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_REIE, .type = PORT_SCIF, }; diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7763.c b/arch/sh/kernel/cpu/sh4a/setup-sh7763.c index 428c16526dcb..40e6cda914d3 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7763.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7763.c @@ -19,7 +19,6 @@ #include static struct plat_sci_port scif0_platform_data = { - .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_REIE, .type = PORT_SCIF, .regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE, @@ -41,7 +40,6 @@ static struct platform_device scif0_device = { }; static struct plat_sci_port scif1_platform_data = { - .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_REIE, .type = PORT_SCIF, .regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE, @@ -63,7 +61,6 @@ static struct platform_device scif1_device = { }; static struct plat_sci_port scif2_platform_data = { - .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_REIE, .type = PORT_SCIF, .regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE, diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7770.c b/arch/sh/kernel/cpu/sh4a/setup-sh7770.c index b2d3206e2704..82e3bdf2e1b6 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7770.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7770.c @@ -16,7 +16,6 @@ #include static struct plat_sci_port scif0_platform_data = { - .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_REIE | SCSCR_TOIE, .type = PORT_SCIF, }; @@ -37,7 +36,6 @@ static struct platform_device scif0_device = { }; static struct plat_sci_port scif1_platform_data = { - .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_REIE | SCSCR_TOIE, .type = PORT_SCIF, }; @@ -58,7 +56,6 @@ static struct platform_device scif1_device = { }; static struct plat_sci_port scif2_platform_data = { - .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_REIE | SCSCR_TOIE, .type = PORT_SCIF, }; @@ -79,7 +76,6 @@ static struct platform_device scif2_device = { }; static struct plat_sci_port scif3_platform_data = { - .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_REIE | SCSCR_TOIE, .type = PORT_SCIF, }; @@ -100,7 +96,6 @@ static struct platform_device scif3_device = { }; static struct plat_sci_port scif4_platform_data = { - .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_REIE | SCSCR_TOIE, .type = PORT_SCIF, }; @@ -121,7 +116,6 @@ static struct platform_device scif4_device = { }; static struct plat_sci_port scif5_platform_data = { - .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_REIE | SCSCR_TOIE, .type = PORT_SCIF, }; @@ -142,7 +136,6 @@ static struct platform_device scif5_device = { }; static struct plat_sci_port scif6_platform_data = { - .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_REIE | SCSCR_TOIE, .type = PORT_SCIF, }; @@ -163,7 +156,6 @@ static struct platform_device scif6_device = { }; static struct plat_sci_port scif7_platform_data = { - .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_REIE | SCSCR_TOIE, .type = PORT_SCIF, }; @@ -184,7 +176,6 @@ static struct platform_device scif7_device = { }; static struct plat_sci_port scif8_platform_data = { - .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_REIE | SCSCR_TOIE, .type = PORT_SCIF, }; @@ -205,7 +196,6 @@ static struct platform_device scif8_device = { }; static struct plat_sci_port scif9_platform_data = { - .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_REIE | SCSCR_TOIE, .type = PORT_SCIF, }; diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7780.c b/arch/sh/kernel/cpu/sh4a/setup-sh7780.c index 59282f760ca9..d90ff67a4633 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7780.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7780.c @@ -18,7 +18,6 @@ #include static struct plat_sci_port scif0_platform_data = { - .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_REIE | SCSCR_CKE1, .type = PORT_SCIF, .regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE, @@ -40,7 +39,6 @@ static struct platform_device scif0_device = { }; static struct plat_sci_port scif1_platform_data = { - .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_REIE | SCSCR_CKE1, .type = PORT_SCIF, .regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE, diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7785.c b/arch/sh/kernel/cpu/sh4a/setup-sh7785.c index 22893c0f1662..b0d6f82f2d71 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7785.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7785.c @@ -20,7 +20,6 @@ #include static struct plat_sci_port scif0_platform_data = { - .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_REIE | SCSCR_CKE1, .type = PORT_SCIF, .regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE, @@ -42,7 +41,6 @@ static struct platform_device scif0_device = { }; static struct plat_sci_port scif1_platform_data = { - .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_REIE | SCSCR_CKE1, .type = PORT_SCIF, .regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE, @@ -64,7 +62,6 @@ static struct platform_device scif1_device = { }; static struct plat_sci_port scif2_platform_data = { - .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_REIE | SCSCR_CKE1, .type = PORT_SCIF, .regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE, @@ -86,7 +83,6 @@ static struct platform_device scif2_device = { }; static struct plat_sci_port scif3_platform_data = { - .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_REIE | SCSCR_CKE1, .type = PORT_SCIF, .regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE, @@ -108,7 +104,6 @@ static struct platform_device scif3_device = { }; static struct plat_sci_port scif4_platform_data = { - .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_REIE | SCSCR_CKE1, .type = PORT_SCIF, .regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE, @@ -130,7 +125,6 @@ static struct platform_device scif4_device = { }; static struct plat_sci_port scif5_platform_data = { - .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_REIE | SCSCR_CKE1, .type = PORT_SCIF, .regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE, diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7786.c b/arch/sh/kernel/cpu/sh4a/setup-sh7786.c index 32525e13aa26..17aac38a6e90 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7786.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7786.c @@ -28,7 +28,6 @@ #include static struct plat_sci_port scif0_platform_data = { - .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_REIE | SCSCR_CKE1, .type = PORT_SCIF, .regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE, @@ -56,7 +55,6 @@ static struct platform_device scif0_device = { * The rest of these all have multiplexed IRQs */ static struct plat_sci_port scif1_platform_data = { - .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_REIE | SCSCR_CKE1, .type = PORT_SCIF, .regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE, @@ -87,7 +85,6 @@ static struct platform_device scif1_device = { }; static struct plat_sci_port scif2_platform_data = { - .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_REIE | SCSCR_CKE1, .type = PORT_SCIF, .regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE, @@ -109,7 +106,6 @@ static struct platform_device scif2_device = { }; static struct plat_sci_port scif3_platform_data = { - .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_REIE | SCSCR_CKE1, .type = PORT_SCIF, .regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE, @@ -131,7 +127,6 @@ static struct platform_device scif3_device = { }; static struct plat_sci_port scif4_platform_data = { - .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_REIE | SCSCR_CKE1, .type = PORT_SCIF, .regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE, @@ -153,7 +148,6 @@ static struct platform_device scif4_device = { }; static struct plat_sci_port scif5_platform_data = { - .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_REIE | SCSCR_CKE1, .type = PORT_SCIF, .regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE, diff --git a/arch/sh/kernel/cpu/sh4a/setup-shx3.c b/arch/sh/kernel/cpu/sh4a/setup-shx3.c index 5495d6693086..ee14d92d840f 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-shx3.c +++ b/arch/sh/kernel/cpu/sh4a/setup-shx3.c @@ -28,7 +28,6 @@ * all rather than adding infrastructure to hack around it. */ static struct plat_sci_port scif0_platform_data = { - .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_REIE, .type = PORT_SCIF, }; @@ -52,7 +51,6 @@ static struct platform_device scif0_device = { }; static struct plat_sci_port scif1_platform_data = { - .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_REIE, .type = PORT_SCIF, }; @@ -76,7 +74,6 @@ static struct platform_device scif1_device = { }; static struct plat_sci_port scif2_platform_data = { - .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_REIE, .type = PORT_SCIF, }; diff --git a/arch/sh/kernel/cpu/sh5/setup-sh5.c b/arch/sh/kernel/cpu/sh5/setup-sh5.c index 5ce34bfd0b4e..084a9cc99175 100644 --- a/arch/sh/kernel/cpu/sh5/setup-sh5.c +++ b/arch/sh/kernel/cpu/sh5/setup-sh5.c @@ -17,7 +17,7 @@ #include static struct plat_sci_port scif0_platform_data = { - .flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP, + .flags = UPF_IOREMAP, .scscr = SCSCR_REIE, .type = PORT_SCIF, }; -- cgit v1.2.3-59-g8ed1b From bcce9daa87cd0ad44bf9bdd433eae0474f51e1e2 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Wed, 11 Jan 2017 16:43:29 +0200 Subject: sh: Don't set sh-sci port_reg The driver considers all negative or zero values of the port_reg field as invalid. The four platforms that set the field to a register address all use an address higher than 0x7fffffff, which is thus considered by the driver as invalid. The feature is thus never used, remove it. The feature could be implemented properly in the future using the pinctrl and GPIO APIs if desired. While at it, don't set the field to SCIx_NOT_SUPPORTED (-1) either, leaving it unset leads to the same result. This will allow removing the SCIx_NOT_SUPPORTED macro. Signed-off-by: Laurent Pinchart Reviewed-by: Geert Uytterhoeven Signed-off-by: Greg Kroah-Hartman --- arch/sh/kernel/cpu/sh3/setup-sh770x.c | 2 -- arch/sh/kernel/cpu/sh4/setup-sh7750.c | 1 - arch/sh/kernel/cpu/sh4a/setup-sh7366.c | 1 - arch/sh/kernel/cpu/sh4a/setup-sh7723.c | 6 ------ arch/sh/kernel/cpu/sh4a/setup-sh7724.c | 6 ------ 5 files changed, 16 deletions(-) diff --git a/arch/sh/kernel/cpu/sh3/setup-sh770x.c b/arch/sh/kernel/cpu/sh3/setup-sh770x.c index e64fe24d860c..e1e54258b822 100644 --- a/arch/sh/kernel/cpu/sh3/setup-sh770x.c +++ b/arch/sh/kernel/cpu/sh3/setup-sh770x.c @@ -109,7 +109,6 @@ static struct platform_device rtc_device = { }; static struct plat_sci_port scif0_platform_data = { - .port_reg = 0xa4000136, .type = PORT_SCI, .ops = &sh770x_sci_port_ops, .regshift = 1, @@ -156,7 +155,6 @@ static struct platform_device scif1_device = { #if defined(CONFIG_CPU_SUBTYPE_SH7707) || \ defined(CONFIG_CPU_SUBTYPE_SH7709) static struct plat_sci_port scif2_platform_data = { - .port_reg = SCIx_NOT_SUPPORTED, .type = PORT_IRDA, .ops = &sh770x_sci_port_ops, .regshift = 1, diff --git a/arch/sh/kernel/cpu/sh4/setup-sh7750.c b/arch/sh/kernel/cpu/sh4/setup-sh7750.c index f693f122a286..d98a55416306 100644 --- a/arch/sh/kernel/cpu/sh4/setup-sh7750.c +++ b/arch/sh/kernel/cpu/sh4/setup-sh7750.c @@ -38,7 +38,6 @@ static struct platform_device rtc_device = { }; static struct plat_sci_port sci_platform_data = { - .port_reg = 0xffe0001C, .type = PORT_SCI, .regshift = 2, }; diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7366.c b/arch/sh/kernel/cpu/sh4a/setup-sh7366.c index 3fc1a3ab634e..646918713d9a 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7366.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7366.c @@ -20,7 +20,6 @@ #include static struct plat_sci_port scif0_platform_data = { - .port_reg = 0xa405013e, .scscr = SCSCR_REIE, .type = PORT_SCIF, }; diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7723.c b/arch/sh/kernel/cpu/sh4a/setup-sh7723.c index 9f47ec950af8..6c5cb234aa33 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7723.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7723.c @@ -23,7 +23,6 @@ /* Serial */ static struct plat_sci_port scif0_platform_data = { - .port_reg = 0xa4050160, .scscr = SCSCR_REIE, .type = PORT_SCIF, .regtype = SCIx_SH4_SCIF_NO_SCSPTR_REGTYPE, @@ -45,7 +44,6 @@ static struct platform_device scif0_device = { }; static struct plat_sci_port scif1_platform_data = { - .port_reg = SCIx_NOT_SUPPORTED, .scscr = SCSCR_REIE, .type = PORT_SCIF, .regtype = SCIx_SH4_SCIF_NO_SCSPTR_REGTYPE, @@ -67,7 +65,6 @@ static struct platform_device scif1_device = { }; static struct plat_sci_port scif2_platform_data = { - .port_reg = SCIx_NOT_SUPPORTED, .scscr = SCSCR_REIE, .type = PORT_SCIF, .regtype = SCIx_SH4_SCIF_NO_SCSPTR_REGTYPE, @@ -89,7 +86,6 @@ static struct platform_device scif2_device = { }; static struct plat_sci_port scif3_platform_data = { - .port_reg = SCIx_NOT_SUPPORTED, .scscr = SCSCR_REIE, .sampling_rate = 8, .type = PORT_SCIFA, @@ -111,7 +107,6 @@ static struct platform_device scif3_device = { }; static struct plat_sci_port scif4_platform_data = { - .port_reg = SCIx_NOT_SUPPORTED, .scscr = SCSCR_REIE, .sampling_rate = 8, .type = PORT_SCIFA, @@ -133,7 +128,6 @@ static struct platform_device scif4_device = { }; static struct plat_sci_port scif5_platform_data = { - .port_reg = SCIx_NOT_SUPPORTED, .scscr = SCSCR_REIE, .sampling_rate = 8, .type = PORT_SCIFA, diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7724.c b/arch/sh/kernel/cpu/sh4a/setup-sh7724.c index 3ce55884c787..c20258b18775 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7724.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7724.c @@ -290,7 +290,6 @@ static struct platform_device dma1_device = { /* Serial */ static struct plat_sci_port scif0_platform_data = { - .port_reg = SCIx_NOT_SUPPORTED, .scscr = SCSCR_REIE, .type = PORT_SCIF, .regtype = SCIx_SH4_SCIF_NO_SCSPTR_REGTYPE, @@ -312,7 +311,6 @@ static struct platform_device scif0_device = { }; static struct plat_sci_port scif1_platform_data = { - .port_reg = SCIx_NOT_SUPPORTED, .scscr = SCSCR_REIE, .type = PORT_SCIF, .regtype = SCIx_SH4_SCIF_NO_SCSPTR_REGTYPE, @@ -334,7 +332,6 @@ static struct platform_device scif1_device = { }; static struct plat_sci_port scif2_platform_data = { - .port_reg = SCIx_NOT_SUPPORTED, .scscr = SCSCR_REIE, .type = PORT_SCIF, .regtype = SCIx_SH4_SCIF_NO_SCSPTR_REGTYPE, @@ -356,7 +353,6 @@ static struct platform_device scif2_device = { }; static struct plat_sci_port scif3_platform_data = { - .port_reg = SCIx_NOT_SUPPORTED, .sampling_rate = 8, .type = PORT_SCIFA, }; @@ -377,7 +373,6 @@ static struct platform_device scif3_device = { }; static struct plat_sci_port scif4_platform_data = { - .port_reg = SCIx_NOT_SUPPORTED, .sampling_rate = 8, .type = PORT_SCIFA, }; @@ -398,7 +393,6 @@ static struct platform_device scif4_device = { }; static struct plat_sci_port scif5_platform_data = { - .port_reg = SCIx_NOT_SUPPORTED, .sampling_rate = 8, .type = PORT_SCIFA, }; -- cgit v1.2.3-59-g8ed1b From a05ea9e26456c1c249d1e50f033898390e92679e Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Wed, 11 Jan 2017 16:43:30 +0200 Subject: sh: Don't set the sh-sci platform data scscr CKE0 bit The bit is only set by platforms that also set the CKE1 but, in which case its value is ignored by the device. Don't set it, this simplifies platform data and only leaves the CKE1 bit to be handled. Signed-off-by: Laurent Pinchart Reviewed-by: Geert Uytterhoeven Signed-off-by: Greg Kroah-Hartman --- arch/sh/kernel/cpu/sh3/setup-sh7705.c | 2 +- arch/sh/kernel/cpu/sh3/setup-sh7710.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7705.c b/arch/sh/kernel/cpu/sh3/setup-sh7705.c index a60edd8f3db7..f6e392e0d27e 100644 --- a/arch/sh/kernel/cpu/sh3/setup-sh7705.c +++ b/arch/sh/kernel/cpu/sh3/setup-sh7705.c @@ -70,7 +70,7 @@ static DECLARE_INTC_DESC(intc_desc, "sh7705", vectors, NULL, NULL, prio_registers, NULL); static struct plat_sci_port scif0_platform_data = { - .scscr = SCSCR_CKE1 | SCSCR_CKE0, + .scscr = SCSCR_CKE1, .type = PORT_SCIF, .ops = &sh770x_sci_port_ops, .regtype = SCIx_SH7705_SCIF_REGTYPE, diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7710.c b/arch/sh/kernel/cpu/sh3/setup-sh7710.c index ac2a0aabcec5..ea52410b430d 100644 --- a/arch/sh/kernel/cpu/sh3/setup-sh7710.c +++ b/arch/sh/kernel/cpu/sh3/setup-sh7710.c @@ -98,7 +98,7 @@ static struct platform_device rtc_device = { }; static struct plat_sci_port scif0_platform_data = { - .scscr = SCSCR_REIE | SCSCR_CKE1 | SCSCR_CKE0, + .scscr = SCSCR_REIE | SCSCR_CKE1, .type = PORT_SCIF, }; @@ -118,7 +118,7 @@ static struct platform_device scif0_device = { }; static struct plat_sci_port scif1_platform_data = { - .scscr = SCSCR_REIE | SCSCR_CKE1 | SCSCR_CKE0, + .scscr = SCSCR_REIE | SCSCR_CKE1, .type = PORT_SCIF, }; -- cgit v1.2.3-59-g8ed1b From f48debc42f9aee5fcdde44f4ef2120dd25394a65 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Wed, 11 Jan 2017 16:43:31 +0200 Subject: sh: Don't set the sh-sci platform data REIE bit when not implemented According to the datasheets, the sh7760 SIM and sh7723 SCIFA instances don't implement the REIE bit. Don't set it in platform data. Signed-off-by: Laurent Pinchart Reviewed-by: Geert Uytterhoeven Signed-off-by: Greg Kroah-Hartman --- arch/sh/kernel/cpu/sh4/setup-sh7760.c | 1 - arch/sh/kernel/cpu/sh4a/setup-sh7723.c | 3 --- 2 files changed, 4 deletions(-) diff --git a/arch/sh/kernel/cpu/sh4/setup-sh7760.c b/arch/sh/kernel/cpu/sh4/setup-sh7760.c index 641b85865a63..0c0cdfc69dcc 100644 --- a/arch/sh/kernel/cpu/sh4/setup-sh7760.c +++ b/arch/sh/kernel/cpu/sh4/setup-sh7760.c @@ -200,7 +200,6 @@ static struct platform_device scif2_device = { }; static struct plat_sci_port scif3_platform_data = { - .scscr = SCSCR_REIE, .type = PORT_SCI, .regshift = 2, }; diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7723.c b/arch/sh/kernel/cpu/sh4a/setup-sh7723.c index 6c5cb234aa33..1c1b3c469831 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7723.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7723.c @@ -86,7 +86,6 @@ static struct platform_device scif2_device = { }; static struct plat_sci_port scif3_platform_data = { - .scscr = SCSCR_REIE, .sampling_rate = 8, .type = PORT_SCIFA, }; @@ -107,7 +106,6 @@ static struct platform_device scif3_device = { }; static struct plat_sci_port scif4_platform_data = { - .scscr = SCSCR_REIE, .sampling_rate = 8, .type = PORT_SCIFA, }; @@ -128,7 +126,6 @@ static struct platform_device scif4_device = { }; static struct plat_sci_port scif5_platform_data = { - .scscr = SCSCR_REIE, .sampling_rate = 8, .type = PORT_SCIFA, }; -- cgit v1.2.3-59-g8ed1b From a752ba18af8285e3eeda572f40dddaebff0c3621 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Wed, 11 Jan 2017 16:43:32 +0200 Subject: serial: sh-sci: Fix register offsets for the IRDA serial port Even though most of its registers are 8-bit wide, the IRDA has two 16-bit registers that make it a 16-bit peripheral and not a 8-bit peripheral with addresses shifted by one. Fix the registers offset in the driver and the platform data regshift value. Signed-off-by: Laurent Pinchart Reviewed-by: Geert Uytterhoeven Signed-off-by: Greg Kroah-Hartman --- arch/sh/kernel/cpu/sh3/setup-sh770x.c | 1 - drivers/tty/serial/sh-sci.c | 17 ++++++++--------- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/arch/sh/kernel/cpu/sh3/setup-sh770x.c b/arch/sh/kernel/cpu/sh3/setup-sh770x.c index e1e54258b822..592cd9ab30c4 100644 --- a/arch/sh/kernel/cpu/sh3/setup-sh770x.c +++ b/arch/sh/kernel/cpu/sh3/setup-sh770x.c @@ -157,7 +157,6 @@ static struct platform_device scif1_device = { static struct plat_sci_port scif2_platform_data = { .type = PORT_IRDA, .ops = &sh770x_sci_port_ops, - .regshift = 1, }; static struct resource scif2_resources[] = { diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index d0102bcca4ef..baa041c1f28f 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -193,18 +193,17 @@ static const struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { }, /* - * Common definitions for legacy IrDA ports, dependent on - * regshift value. + * Common definitions for legacy IrDA ports. */ [SCIx_IRDA_REGTYPE] = { [SCSMR] = { 0x00, 8 }, - [SCBRR] = { 0x01, 8 }, - [SCSCR] = { 0x02, 8 }, - [SCxTDR] = { 0x03, 8 }, - [SCxSR] = { 0x04, 8 }, - [SCxRDR] = { 0x05, 8 }, - [SCFCR] = { 0x06, 8 }, - [SCFDR] = { 0x07, 16 }, + [SCBRR] = { 0x02, 8 }, + [SCSCR] = { 0x04, 8 }, + [SCxTDR] = { 0x06, 8 }, + [SCxSR] = { 0x08, 16 }, + [SCxRDR] = { 0x0a, 8 }, + [SCFCR] = { 0x0c, 8 }, + [SCFDR] = { 0x0e, 16 }, [SCTFDR] = sci_reg_invalid, [SCRFDR] = sci_reg_invalid, [SCSPTR] = sci_reg_invalid, -- cgit v1.2.3-59-g8ed1b From 40b34ddb0385a2a698dec150b50e6b400fc373a0 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Wed, 11 Jan 2017 16:43:33 +0200 Subject: serial: sh-sci: Remove initialization of zero fields in sci_port_params The compiler zeros uninitialized fields, don't zero them manually. Signed-off-by: Laurent Pinchart Reviewed-by: Geert Uytterhoeven Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/sh-sci.c | 94 --------------------------------------------- 1 file changed, 94 deletions(-) diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index baa041c1f28f..4a12c55eae61 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -160,14 +160,7 @@ struct plat_sci_reg { u8 offset, size; }; -/* Helper for invalidating specific entries of an inherited map. */ -#define sci_reg_invalid { .offset = 0, .size = 0 } - static const struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { - [SCIx_PROBE_REGTYPE] = { - [0 ... SCIx_NR_REGS - 1] = sci_reg_invalid, - }, - /* * Common SCI definitions, dependent on the port's regshift * value. @@ -179,17 +172,6 @@ static const struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { [SCxTDR] = { 0x03, 8 }, [SCxSR] = { 0x04, 8 }, [SCxRDR] = { 0x05, 8 }, - [SCFCR] = sci_reg_invalid, - [SCFDR] = sci_reg_invalid, - [SCTFDR] = sci_reg_invalid, - [SCRFDR] = sci_reg_invalid, - [SCSPTR] = sci_reg_invalid, - [SCLSR] = sci_reg_invalid, - [HSSRR] = sci_reg_invalid, - [SCPCR] = sci_reg_invalid, - [SCPDR] = sci_reg_invalid, - [SCDL] = sci_reg_invalid, - [SCCKS] = sci_reg_invalid, }, /* @@ -204,15 +186,6 @@ static const struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { [SCxRDR] = { 0x0a, 8 }, [SCFCR] = { 0x0c, 8 }, [SCFDR] = { 0x0e, 16 }, - [SCTFDR] = sci_reg_invalid, - [SCRFDR] = sci_reg_invalid, - [SCSPTR] = sci_reg_invalid, - [SCLSR] = sci_reg_invalid, - [HSSRR] = sci_reg_invalid, - [SCPCR] = sci_reg_invalid, - [SCPDR] = sci_reg_invalid, - [SCDL] = sci_reg_invalid, - [SCCKS] = sci_reg_invalid, }, /* @@ -227,15 +200,8 @@ static const struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { [SCxRDR] = { 0x24, 8 }, [SCFCR] = { 0x18, 16 }, [SCFDR] = { 0x1c, 16 }, - [SCTFDR] = sci_reg_invalid, - [SCRFDR] = sci_reg_invalid, - [SCSPTR] = sci_reg_invalid, - [SCLSR] = sci_reg_invalid, - [HSSRR] = sci_reg_invalid, [SCPCR] = { 0x30, 16 }, [SCPDR] = { 0x34, 16 }, - [SCDL] = sci_reg_invalid, - [SCCKS] = sci_reg_invalid, }, /* @@ -249,16 +215,10 @@ static const struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { [SCxSR] = { 0x14, 16 }, [SCxRDR] = { 0x60, 8 }, [SCFCR] = { 0x18, 16 }, - [SCFDR] = sci_reg_invalid, [SCTFDR] = { 0x38, 16 }, [SCRFDR] = { 0x3c, 16 }, - [SCSPTR] = sci_reg_invalid, - [SCLSR] = sci_reg_invalid, - [HSSRR] = sci_reg_invalid, [SCPCR] = { 0x30, 16 }, [SCPDR] = { 0x34, 16 }, - [SCDL] = sci_reg_invalid, - [SCCKS] = sci_reg_invalid, }, /* @@ -274,15 +234,8 @@ static const struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { [SCxRDR] = { 0x14, 8 }, [SCFCR] = { 0x18, 16 }, [SCFDR] = { 0x1c, 16 }, - [SCTFDR] = sci_reg_invalid, - [SCRFDR] = sci_reg_invalid, [SCSPTR] = { 0x20, 16 }, [SCLSR] = { 0x24, 16 }, - [HSSRR] = sci_reg_invalid, - [SCPCR] = sci_reg_invalid, - [SCPDR] = sci_reg_invalid, - [SCDL] = sci_reg_invalid, - [SCCKS] = sci_reg_invalid, }, /* @@ -297,15 +250,6 @@ static const struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { [SCxRDR] = { 0x0a, 8 }, [SCFCR] = { 0x0c, 8 }, [SCFDR] = { 0x0e, 16 }, - [SCTFDR] = sci_reg_invalid, - [SCRFDR] = sci_reg_invalid, - [SCSPTR] = sci_reg_invalid, - [SCLSR] = sci_reg_invalid, - [HSSRR] = sci_reg_invalid, - [SCPCR] = sci_reg_invalid, - [SCPDR] = sci_reg_invalid, - [SCDL] = sci_reg_invalid, - [SCCKS] = sci_reg_invalid, }, /* @@ -320,15 +264,8 @@ static const struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { [SCxRDR] = { 0x14, 8 }, [SCFCR] = { 0x18, 16 }, [SCFDR] = { 0x1c, 16 }, - [SCTFDR] = sci_reg_invalid, - [SCRFDR] = sci_reg_invalid, [SCSPTR] = { 0x20, 16 }, [SCLSR] = { 0x24, 16 }, - [HSSRR] = sci_reg_invalid, - [SCPCR] = sci_reg_invalid, - [SCPDR] = sci_reg_invalid, - [SCDL] = sci_reg_invalid, - [SCCKS] = sci_reg_invalid, }, /* @@ -344,13 +281,8 @@ static const struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { [SCxRDR] = { 0x14, 8 }, [SCFCR] = { 0x18, 16 }, [SCFDR] = { 0x1c, 16 }, - [SCTFDR] = sci_reg_invalid, - [SCRFDR] = sci_reg_invalid, [SCSPTR] = { 0x20, 16 }, [SCLSR] = { 0x24, 16 }, - [HSSRR] = sci_reg_invalid, - [SCPCR] = sci_reg_invalid, - [SCPDR] = sci_reg_invalid, [SCDL] = { 0x30, 16 }, [SCCKS] = { 0x34, 16 }, }, @@ -367,13 +299,9 @@ static const struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { [SCxRDR] = { 0x14, 8 }, [SCFCR] = { 0x18, 16 }, [SCFDR] = { 0x1c, 16 }, - [SCTFDR] = sci_reg_invalid, - [SCRFDR] = sci_reg_invalid, [SCSPTR] = { 0x20, 16 }, [SCLSR] = { 0x24, 16 }, [HSSRR] = { 0x40, 16 }, - [SCPCR] = sci_reg_invalid, - [SCPDR] = sci_reg_invalid, [SCDL] = { 0x30, 16 }, [SCCKS] = { 0x34, 16 }, }, @@ -391,15 +319,7 @@ static const struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { [SCxRDR] = { 0x14, 8 }, [SCFCR] = { 0x18, 16 }, [SCFDR] = { 0x1c, 16 }, - [SCTFDR] = sci_reg_invalid, - [SCRFDR] = sci_reg_invalid, - [SCSPTR] = sci_reg_invalid, [SCLSR] = { 0x24, 16 }, - [HSSRR] = sci_reg_invalid, - [SCPCR] = sci_reg_invalid, - [SCPDR] = sci_reg_invalid, - [SCDL] = sci_reg_invalid, - [SCCKS] = sci_reg_invalid, }, /* @@ -419,11 +339,6 @@ static const struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { [SCRFDR] = { 0x20, 16 }, [SCSPTR] = { 0x24, 16 }, [SCLSR] = { 0x28, 16 }, - [HSSRR] = sci_reg_invalid, - [SCPCR] = sci_reg_invalid, - [SCPDR] = sci_reg_invalid, - [SCDL] = sci_reg_invalid, - [SCCKS] = sci_reg_invalid, }, /* @@ -439,15 +354,6 @@ static const struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { [SCxRDR] = { 0x24, 8 }, [SCFCR] = { 0x18, 16 }, [SCFDR] = { 0x1c, 16 }, - [SCTFDR] = sci_reg_invalid, - [SCRFDR] = sci_reg_invalid, - [SCSPTR] = sci_reg_invalid, - [SCLSR] = sci_reg_invalid, - [HSSRR] = sci_reg_invalid, - [SCPCR] = sci_reg_invalid, - [SCPDR] = sci_reg_invalid, - [SCDL] = sci_reg_invalid, - [SCCKS] = sci_reg_invalid, }, }; -- cgit v1.2.3-59-g8ed1b From e095ee6b447a35ea90c523ce399d5a61753ade25 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Wed, 11 Jan 2017 16:43:34 +0200 Subject: serial: sh-sci: Replace regmap array with port parameters Turn the regmap two-dimensional array to an array of port parameters and store a pointer to the port parameters in the sci_port structure. This will allow handling additional port type dependent parameters. Signed-off-by: Laurent Pinchart Reviewed-by: Geert Uytterhoeven Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/sh-sci.c | 278 ++++++++++++++++++++++++-------------------- 1 file changed, 155 insertions(+), 123 deletions(-) diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index 4a12c55eae61..7e72823f6388 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -101,10 +101,19 @@ enum SCI_CLKS { for ((_sr) = max_sr(_port); (_sr) >= min_sr(_port); (_sr)--) \ if ((_port)->sampling_rate_mask & SCI_SR((_sr))) +struct plat_sci_reg { + u8 offset, size; +}; + +struct sci_port_params { + const struct plat_sci_reg regs[SCIx_NR_REGS]; +}; + struct sci_port { struct uart_port port; /* Platform configuration */ + const struct sci_port_params *params; struct plat_sci_port *cfg; unsigned int overrun_reg; unsigned int overrun_mask; @@ -156,69 +165,73 @@ to_sci_port(struct uart_port *uart) return container_of(uart, struct sci_port, port); } -struct plat_sci_reg { - u8 offset, size; -}; - -static const struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { +static const struct sci_port_params sci_port_params[SCIx_NR_REGTYPES] = { /* * Common SCI definitions, dependent on the port's regshift * value. */ [SCIx_SCI_REGTYPE] = { - [SCSMR] = { 0x00, 8 }, - [SCBRR] = { 0x01, 8 }, - [SCSCR] = { 0x02, 8 }, - [SCxTDR] = { 0x03, 8 }, - [SCxSR] = { 0x04, 8 }, - [SCxRDR] = { 0x05, 8 }, + .regs = { + [SCSMR] = { 0x00, 8 }, + [SCBRR] = { 0x01, 8 }, + [SCSCR] = { 0x02, 8 }, + [SCxTDR] = { 0x03, 8 }, + [SCxSR] = { 0x04, 8 }, + [SCxRDR] = { 0x05, 8 }, + }, }, /* * Common definitions for legacy IrDA ports. */ [SCIx_IRDA_REGTYPE] = { - [SCSMR] = { 0x00, 8 }, - [SCBRR] = { 0x02, 8 }, - [SCSCR] = { 0x04, 8 }, - [SCxTDR] = { 0x06, 8 }, - [SCxSR] = { 0x08, 16 }, - [SCxRDR] = { 0x0a, 8 }, - [SCFCR] = { 0x0c, 8 }, - [SCFDR] = { 0x0e, 16 }, + .regs = { + [SCSMR] = { 0x00, 8 }, + [SCBRR] = { 0x02, 8 }, + [SCSCR] = { 0x04, 8 }, + [SCxTDR] = { 0x06, 8 }, + [SCxSR] = { 0x08, 16 }, + [SCxRDR] = { 0x0a, 8 }, + [SCFCR] = { 0x0c, 8 }, + [SCFDR] = { 0x0e, 16 }, + }, }, /* * Common SCIFA definitions. */ [SCIx_SCIFA_REGTYPE] = { - [SCSMR] = { 0x00, 16 }, - [SCBRR] = { 0x04, 8 }, - [SCSCR] = { 0x08, 16 }, - [SCxTDR] = { 0x20, 8 }, - [SCxSR] = { 0x14, 16 }, - [SCxRDR] = { 0x24, 8 }, - [SCFCR] = { 0x18, 16 }, - [SCFDR] = { 0x1c, 16 }, - [SCPCR] = { 0x30, 16 }, - [SCPDR] = { 0x34, 16 }, + .regs = { + [SCSMR] = { 0x00, 16 }, + [SCBRR] = { 0x04, 8 }, + [SCSCR] = { 0x08, 16 }, + [SCxTDR] = { 0x20, 8 }, + [SCxSR] = { 0x14, 16 }, + [SCxRDR] = { 0x24, 8 }, + [SCFCR] = { 0x18, 16 }, + [SCFDR] = { 0x1c, 16 }, + [SCPCR] = { 0x30, 16 }, + [SCPDR] = { 0x34, 16 }, + }, }, /* * Common SCIFB definitions. */ [SCIx_SCIFB_REGTYPE] = { - [SCSMR] = { 0x00, 16 }, - [SCBRR] = { 0x04, 8 }, - [SCSCR] = { 0x08, 16 }, - [SCxTDR] = { 0x40, 8 }, - [SCxSR] = { 0x14, 16 }, - [SCxRDR] = { 0x60, 8 }, - [SCFCR] = { 0x18, 16 }, - [SCTFDR] = { 0x38, 16 }, - [SCRFDR] = { 0x3c, 16 }, - [SCPCR] = { 0x30, 16 }, - [SCPDR] = { 0x34, 16 }, + .regs = { + [SCSMR] = { 0x00, 16 }, + [SCBRR] = { 0x04, 8 }, + [SCSCR] = { 0x08, 16 }, + [SCxTDR] = { 0x40, 8 }, + [SCxSR] = { 0x14, 16 }, + [SCxRDR] = { 0x60, 8 }, + [SCFCR] = { 0x18, 16 }, + [SCTFDR] = { 0x38, 16 }, + [SCRFDR] = { 0x3c, 16 }, + [SCPCR] = { 0x30, 16 }, + [SCPDR] = { 0x34, 16 }, + }, }, /* @@ -226,46 +239,52 @@ static const struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { * count registers. */ [SCIx_SH2_SCIF_FIFODATA_REGTYPE] = { - [SCSMR] = { 0x00, 16 }, - [SCBRR] = { 0x04, 8 }, - [SCSCR] = { 0x08, 16 }, - [SCxTDR] = { 0x0c, 8 }, - [SCxSR] = { 0x10, 16 }, - [SCxRDR] = { 0x14, 8 }, - [SCFCR] = { 0x18, 16 }, - [SCFDR] = { 0x1c, 16 }, - [SCSPTR] = { 0x20, 16 }, - [SCLSR] = { 0x24, 16 }, + .regs = { + [SCSMR] = { 0x00, 16 }, + [SCBRR] = { 0x04, 8 }, + [SCSCR] = { 0x08, 16 }, + [SCxTDR] = { 0x0c, 8 }, + [SCxSR] = { 0x10, 16 }, + [SCxRDR] = { 0x14, 8 }, + [SCFCR] = { 0x18, 16 }, + [SCFDR] = { 0x1c, 16 }, + [SCSPTR] = { 0x20, 16 }, + [SCLSR] = { 0x24, 16 }, + }, }, /* * Common SH-3 SCIF definitions. */ [SCIx_SH3_SCIF_REGTYPE] = { - [SCSMR] = { 0x00, 8 }, - [SCBRR] = { 0x02, 8 }, - [SCSCR] = { 0x04, 8 }, - [SCxTDR] = { 0x06, 8 }, - [SCxSR] = { 0x08, 16 }, - [SCxRDR] = { 0x0a, 8 }, - [SCFCR] = { 0x0c, 8 }, - [SCFDR] = { 0x0e, 16 }, + .regs = { + [SCSMR] = { 0x00, 8 }, + [SCBRR] = { 0x02, 8 }, + [SCSCR] = { 0x04, 8 }, + [SCxTDR] = { 0x06, 8 }, + [SCxSR] = { 0x08, 16 }, + [SCxRDR] = { 0x0a, 8 }, + [SCFCR] = { 0x0c, 8 }, + [SCFDR] = { 0x0e, 16 }, + }, }, /* * Common SH-4(A) SCIF(B) definitions. */ [SCIx_SH4_SCIF_REGTYPE] = { - [SCSMR] = { 0x00, 16 }, - [SCBRR] = { 0x04, 8 }, - [SCSCR] = { 0x08, 16 }, - [SCxTDR] = { 0x0c, 8 }, - [SCxSR] = { 0x10, 16 }, - [SCxRDR] = { 0x14, 8 }, - [SCFCR] = { 0x18, 16 }, - [SCFDR] = { 0x1c, 16 }, - [SCSPTR] = { 0x20, 16 }, - [SCLSR] = { 0x24, 16 }, + .regs = { + [SCSMR] = { 0x00, 16 }, + [SCBRR] = { 0x04, 8 }, + [SCSCR] = { 0x08, 16 }, + [SCxTDR] = { 0x0c, 8 }, + [SCxSR] = { 0x10, 16 }, + [SCxRDR] = { 0x14, 8 }, + [SCFCR] = { 0x18, 16 }, + [SCFDR] = { 0x1c, 16 }, + [SCSPTR] = { 0x20, 16 }, + [SCLSR] = { 0x24, 16 }, + }, }, /* @@ -273,37 +292,41 @@ static const struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { * External Clock (BRG). */ [SCIx_SH4_SCIF_BRG_REGTYPE] = { - [SCSMR] = { 0x00, 16 }, - [SCBRR] = { 0x04, 8 }, - [SCSCR] = { 0x08, 16 }, - [SCxTDR] = { 0x0c, 8 }, - [SCxSR] = { 0x10, 16 }, - [SCxRDR] = { 0x14, 8 }, - [SCFCR] = { 0x18, 16 }, - [SCFDR] = { 0x1c, 16 }, - [SCSPTR] = { 0x20, 16 }, - [SCLSR] = { 0x24, 16 }, - [SCDL] = { 0x30, 16 }, - [SCCKS] = { 0x34, 16 }, + .regs = { + [SCSMR] = { 0x00, 16 }, + [SCBRR] = { 0x04, 8 }, + [SCSCR] = { 0x08, 16 }, + [SCxTDR] = { 0x0c, 8 }, + [SCxSR] = { 0x10, 16 }, + [SCxRDR] = { 0x14, 8 }, + [SCFCR] = { 0x18, 16 }, + [SCFDR] = { 0x1c, 16 }, + [SCSPTR] = { 0x20, 16 }, + [SCLSR] = { 0x24, 16 }, + [SCDL] = { 0x30, 16 }, + [SCCKS] = { 0x34, 16 }, + }, }, /* * Common HSCIF definitions. */ [SCIx_HSCIF_REGTYPE] = { - [SCSMR] = { 0x00, 16 }, - [SCBRR] = { 0x04, 8 }, - [SCSCR] = { 0x08, 16 }, - [SCxTDR] = { 0x0c, 8 }, - [SCxSR] = { 0x10, 16 }, - [SCxRDR] = { 0x14, 8 }, - [SCFCR] = { 0x18, 16 }, - [SCFDR] = { 0x1c, 16 }, - [SCSPTR] = { 0x20, 16 }, - [SCLSR] = { 0x24, 16 }, - [HSSRR] = { 0x40, 16 }, - [SCDL] = { 0x30, 16 }, - [SCCKS] = { 0x34, 16 }, + .regs = { + [SCSMR] = { 0x00, 16 }, + [SCBRR] = { 0x04, 8 }, + [SCSCR] = { 0x08, 16 }, + [SCxTDR] = { 0x0c, 8 }, + [SCxSR] = { 0x10, 16 }, + [SCxRDR] = { 0x14, 8 }, + [SCFCR] = { 0x18, 16 }, + [SCFDR] = { 0x1c, 16 }, + [SCSPTR] = { 0x20, 16 }, + [SCLSR] = { 0x24, 16 }, + [HSSRR] = { 0x40, 16 }, + [SCDL] = { 0x30, 16 }, + [SCCKS] = { 0x34, 16 }, + }, }, /* @@ -311,15 +334,17 @@ static const struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { * register. */ [SCIx_SH4_SCIF_NO_SCSPTR_REGTYPE] = { - [SCSMR] = { 0x00, 16 }, - [SCBRR] = { 0x04, 8 }, - [SCSCR] = { 0x08, 16 }, - [SCxTDR] = { 0x0c, 8 }, - [SCxSR] = { 0x10, 16 }, - [SCxRDR] = { 0x14, 8 }, - [SCFCR] = { 0x18, 16 }, - [SCFDR] = { 0x1c, 16 }, - [SCLSR] = { 0x24, 16 }, + .regs = { + [SCSMR] = { 0x00, 16 }, + [SCBRR] = { 0x04, 8 }, + [SCSCR] = { 0x08, 16 }, + [SCxTDR] = { 0x0c, 8 }, + [SCxSR] = { 0x10, 16 }, + [SCxRDR] = { 0x14, 8 }, + [SCFCR] = { 0x18, 16 }, + [SCFDR] = { 0x1c, 16 }, + [SCLSR] = { 0x24, 16 }, + }, }, /* @@ -327,18 +352,20 @@ static const struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { * count registers. */ [SCIx_SH4_SCIF_FIFODATA_REGTYPE] = { - [SCSMR] = { 0x00, 16 }, - [SCBRR] = { 0x04, 8 }, - [SCSCR] = { 0x08, 16 }, - [SCxTDR] = { 0x0c, 8 }, - [SCxSR] = { 0x10, 16 }, - [SCxRDR] = { 0x14, 8 }, - [SCFCR] = { 0x18, 16 }, - [SCFDR] = { 0x1c, 16 }, - [SCTFDR] = { 0x1c, 16 }, /* aliased to SCFDR */ - [SCRFDR] = { 0x20, 16 }, - [SCSPTR] = { 0x24, 16 }, - [SCLSR] = { 0x28, 16 }, + .regs = { + [SCSMR] = { 0x00, 16 }, + [SCBRR] = { 0x04, 8 }, + [SCSCR] = { 0x08, 16 }, + [SCxTDR] = { 0x0c, 8 }, + [SCxSR] = { 0x10, 16 }, + [SCxRDR] = { 0x14, 8 }, + [SCFCR] = { 0x18, 16 }, + [SCFDR] = { 0x1c, 16 }, + [SCTFDR] = { 0x1c, 16 }, /* aliased to SCFDR */ + [SCRFDR] = { 0x20, 16 }, + [SCSPTR] = { 0x24, 16 }, + [SCLSR] = { 0x28, 16 }, + }, }, /* @@ -346,18 +373,20 @@ static const struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { * registers. */ [SCIx_SH7705_SCIF_REGTYPE] = { - [SCSMR] = { 0x00, 16 }, - [SCBRR] = { 0x04, 8 }, - [SCSCR] = { 0x08, 16 }, - [SCxTDR] = { 0x20, 8 }, - [SCxSR] = { 0x14, 16 }, - [SCxRDR] = { 0x24, 8 }, - [SCFCR] = { 0x18, 16 }, - [SCFDR] = { 0x1c, 16 }, + .regs = { + [SCSMR] = { 0x00, 16 }, + [SCBRR] = { 0x04, 8 }, + [SCSCR] = { 0x08, 16 }, + [SCxTDR] = { 0x20, 8 }, + [SCxSR] = { 0x14, 16 }, + [SCxRDR] = { 0x24, 8 }, + [SCFCR] = { 0x18, 16 }, + [SCFDR] = { 0x1c, 16 }, + }, }, }; -#define sci_getreg(up, offset) (sci_regmap[to_sci_port(up)->cfg->regtype] + offset) +#define sci_getreg(up, offset) (&to_sci_port(up)->params->regs[offset]) /* * The "offset" here is rather misleading, in that it refers to an enum @@ -2557,6 +2586,8 @@ static int sci_init_single(struct platform_device *dev, return ret; } + sci_port->params = &sci_port_params[p->regtype]; + switch (p->type) { case PORT_SCIFB: port->fifosize = 256; @@ -3069,6 +3100,7 @@ static int __init early_console_setup(struct earlycon_device *device, sci_ports[0].cfg = &port_cfg; sci_ports[0].cfg->type = type; sci_probe_regmap(sci_ports[0].cfg); + sci_ports[0].params = &sci_port_params[sci_ports[0].cfg->regtype]; port_cfg.scscr = sci_serial_in(&sci_ports[0].port, SCSCR); sci_serial_out(&sci_ports[0].port, SCSCR, SCSCR_RE | SCSCR_TE | port_cfg.scscr); -- cgit v1.2.3-59-g8ed1b From daf5a8959a835bd91534e0ab049d0bfe8448536d Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Wed, 11 Jan 2017 16:43:35 +0200 Subject: serial: sh-sci: Constify platform data The driver modifies platform data for internal purpose only. Fix that and make the platform data structure const. Signed-off-by: Laurent Pinchart Reviewed-by: Geert Uytterhoeven Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/sh-sci.c | 97 +++++++++++++++++++++++---------------------- 1 file changed, 49 insertions(+), 48 deletions(-) diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index 7e72823f6388..d50368e58314 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -114,7 +114,7 @@ struct sci_port { /* Platform configuration */ const struct sci_port_params *params; - struct plat_sci_port *cfg; + const struct plat_sci_port *cfg; unsigned int overrun_reg; unsigned int overrun_mask; unsigned int error_mask; @@ -420,41 +420,6 @@ static void sci_serial_out(struct uart_port *p, int offset, int value) WARN(1, "Invalid register access\n"); } -static int sci_probe_regmap(struct plat_sci_port *cfg) -{ - switch (cfg->type) { - case PORT_SCI: - cfg->regtype = SCIx_SCI_REGTYPE; - break; - case PORT_IRDA: - cfg->regtype = SCIx_IRDA_REGTYPE; - break; - case PORT_SCIFA: - cfg->regtype = SCIx_SCIFA_REGTYPE; - break; - case PORT_SCIFB: - cfg->regtype = SCIx_SCIFB_REGTYPE; - break; - case PORT_SCIF: - /* - * The SH-4 is a bit of a misnomer here, although that's - * where this particular port layout originated. This - * configuration (or some slight variation thereof) - * remains the dominant model for all SCIFs. - */ - cfg->regtype = SCIx_SH4_SCIF_REGTYPE; - break; - case PORT_HSCIF: - cfg->regtype = SCIx_HSCIF_REGTYPE; - break; - default: - pr_err("Can't probe register map for given port\n"); - return -EINVAL; - } - - return 0; -} - static void sci_port_enable(struct sci_port *sci_port) { unsigned int i; @@ -2541,9 +2506,50 @@ found: return 0; } +static const struct sci_port_params * +sci_probe_regmap(const struct plat_sci_port *cfg) +{ + unsigned int regtype; + + if (cfg->regtype != SCIx_PROBE_REGTYPE) + return &sci_port_params[cfg->regtype]; + + switch (cfg->type) { + case PORT_SCI: + regtype = SCIx_SCI_REGTYPE; + break; + case PORT_IRDA: + regtype = SCIx_IRDA_REGTYPE; + break; + case PORT_SCIFA: + regtype = SCIx_SCIFA_REGTYPE; + break; + case PORT_SCIFB: + regtype = SCIx_SCIFB_REGTYPE; + break; + case PORT_SCIF: + /* + * The SH-4 is a bit of a misnomer here, although that's + * where this particular port layout originated. This + * configuration (or some slight variation thereof) + * remains the dominant model for all SCIFs. + */ + regtype = SCIx_SH4_SCIF_REGTYPE; + break; + case PORT_HSCIF: + regtype = SCIx_HSCIF_REGTYPE; + break; + default: + pr_err("Can't probe register map for given port\n"); + return NULL; + } + + return &sci_port_params[regtype]; +} + static int sci_init_single(struct platform_device *dev, struct sci_port *sci_port, unsigned int index, - struct plat_sci_port *p, bool early) + const struct plat_sci_port *p, bool early) { struct uart_port *port = &sci_port->port; const struct resource *res; @@ -2580,13 +2586,9 @@ static int sci_init_single(struct platform_device *dev, sci_port->irqs[3] = sci_port->irqs[0]; } - if (p->regtype == SCIx_PROBE_REGTYPE) { - ret = sci_probe_regmap(p); - if (unlikely(ret)) - return ret; - } - - sci_port->params = &sci_port_params[p->regtype]; + sci_port->params = sci_probe_regmap(p); + if (unlikely(sci_port->params == NULL)) + return -EINVAL; switch (p->type) { case PORT_SCIFB: @@ -2806,7 +2808,7 @@ static char early_serial_buf[32]; static int sci_probe_earlyprintk(struct platform_device *pdev) { - struct plat_sci_port *cfg = dev_get_platdata(&pdev->dev); + const struct plat_sci_port *cfg = dev_get_platdata(&pdev->dev); if (early_serial_console.data) return -EEXIST; @@ -3097,10 +3099,9 @@ static int __init early_console_setup(struct earlycon_device *device, device->port.serial_out = sci_serial_out; device->port.type = type; memcpy(&sci_ports[0].port, &device->port, sizeof(struct uart_port)); + port_cfg.type = type; sci_ports[0].cfg = &port_cfg; - sci_ports[0].cfg->type = type; - sci_probe_regmap(sci_ports[0].cfg); - sci_ports[0].params = &sci_port_params[sci_ports[0].cfg->regtype]; + sci_ports[0].params = sci_probe_regmap(&port_cfg); port_cfg.scscr = sci_serial_in(&sci_ports[0].port, SCSCR); sci_serial_out(&sci_ports[0].port, SCSCR, SCSCR_RE | SCSCR_TE | port_cfg.scscr); -- cgit v1.2.3-59-g8ed1b From b2f20ed9c483859e2e83cfb1a3193e40760c18ad Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Wed, 11 Jan 2017 16:43:36 +0200 Subject: serial: sh-sci: Extend sci_port_params with more port parameters The fifo size, overrun register and mask, sampling rate mask and error mask all depend on the port type only and don't need to be computed at runtime. Add them to the sci_port_parameters structure. Signed-off-by: Laurent Pinchart Reviewed-by: Geert Uytterhoeven Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/sh-sci.c | 181 ++++++++++++++++++++++++-------------------- drivers/tty/serial/sh-sci.h | 4 +- 2 files changed, 102 insertions(+), 83 deletions(-) diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index d50368e58314..a8607cacee6c 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -107,6 +107,12 @@ struct plat_sci_reg { struct sci_port_params { const struct plat_sci_reg regs[SCIx_NR_REGS]; + unsigned int fifosize; + unsigned int overrun_reg; + unsigned int overrun_mask; + unsigned int sampling_rate_mask; + unsigned int error_mask; + unsigned int error_clear; }; struct sci_port { @@ -115,10 +121,6 @@ struct sci_port { /* Platform configuration */ const struct sci_port_params *params; const struct plat_sci_port *cfg; - unsigned int overrun_reg; - unsigned int overrun_mask; - unsigned int error_mask; - unsigned int error_clear; unsigned int sampling_rate_mask; resource_size_t reg_size; struct mctrl_gpios *gpios; @@ -179,6 +181,12 @@ static const struct sci_port_params sci_port_params[SCIx_NR_REGTYPES] = { [SCxSR] = { 0x04, 8 }, [SCxRDR] = { 0x05, 8 }, }, + .fifosize = 1, + .overrun_reg = SCxSR, + .overrun_mask = SCI_ORER, + .sampling_rate_mask = SCI_SR(32), + .error_mask = SCI_DEFAULT_ERROR_MASK | SCI_ORER, + .error_clear = SCI_ERROR_CLEAR & ~SCI_ORER, }, /* @@ -195,6 +203,12 @@ static const struct sci_port_params sci_port_params[SCIx_NR_REGTYPES] = { [SCFCR] = { 0x0c, 8 }, [SCFDR] = { 0x0e, 16 }, }, + .fifosize = 1, + .overrun_reg = SCxSR, + .overrun_mask = SCI_ORER, + .sampling_rate_mask = SCI_SR(32), + .error_mask = SCI_DEFAULT_ERROR_MASK | SCI_ORER, + .error_clear = SCI_ERROR_CLEAR & ~SCI_ORER, }, /* @@ -213,6 +227,12 @@ static const struct sci_port_params sci_port_params[SCIx_NR_REGTYPES] = { [SCPCR] = { 0x30, 16 }, [SCPDR] = { 0x34, 16 }, }, + .fifosize = 64, + .overrun_reg = SCxSR, + .overrun_mask = SCIFA_ORER, + .sampling_rate_mask = SCI_SR_SCIFAB, + .error_mask = SCIF_DEFAULT_ERROR_MASK | SCIFA_ORER, + .error_clear = SCIF_ERROR_CLEAR & ~SCIFA_ORER, }, /* @@ -232,6 +252,12 @@ static const struct sci_port_params sci_port_params[SCIx_NR_REGTYPES] = { [SCPCR] = { 0x30, 16 }, [SCPDR] = { 0x34, 16 }, }, + .fifosize = 256, + .overrun_reg = SCxSR, + .overrun_mask = SCIFA_ORER, + .sampling_rate_mask = SCI_SR_SCIFAB, + .error_mask = SCIF_DEFAULT_ERROR_MASK | SCIFA_ORER, + .error_clear = SCIF_ERROR_CLEAR & ~SCIFA_ORER, }, /* @@ -251,6 +277,12 @@ static const struct sci_port_params sci_port_params[SCIx_NR_REGTYPES] = { [SCSPTR] = { 0x20, 16 }, [SCLSR] = { 0x24, 16 }, }, + .fifosize = 16, + .overrun_reg = SCLSR, + .overrun_mask = SCLSR_ORER, + .sampling_rate_mask = SCI_SR(32), + .error_mask = SCIF_DEFAULT_ERROR_MASK, + .error_clear = SCIF_ERROR_CLEAR, }, /* @@ -267,6 +299,12 @@ static const struct sci_port_params sci_port_params[SCIx_NR_REGTYPES] = { [SCFCR] = { 0x0c, 8 }, [SCFDR] = { 0x0e, 16 }, }, + .fifosize = 16, + .overrun_reg = SCLSR, + .overrun_mask = SCLSR_ORER, + .sampling_rate_mask = SCI_SR(32), + .error_mask = SCIF_DEFAULT_ERROR_MASK, + .error_clear = SCIF_ERROR_CLEAR, }, /* @@ -285,6 +323,12 @@ static const struct sci_port_params sci_port_params[SCIx_NR_REGTYPES] = { [SCSPTR] = { 0x20, 16 }, [SCLSR] = { 0x24, 16 }, }, + .fifosize = 16, + .overrun_reg = SCLSR, + .overrun_mask = SCLSR_ORER, + .sampling_rate_mask = SCI_SR(32), + .error_mask = SCIF_DEFAULT_ERROR_MASK, + .error_clear = SCIF_ERROR_CLEAR, }, /* @@ -306,6 +350,12 @@ static const struct sci_port_params sci_port_params[SCIx_NR_REGTYPES] = { [SCDL] = { 0x30, 16 }, [SCCKS] = { 0x34, 16 }, }, + .fifosize = 16, + .overrun_reg = SCLSR, + .overrun_mask = SCLSR_ORER, + .sampling_rate_mask = SCI_SR(32), + .error_mask = SCIF_DEFAULT_ERROR_MASK, + .error_clear = SCIF_ERROR_CLEAR, }, /* @@ -327,6 +377,12 @@ static const struct sci_port_params sci_port_params[SCIx_NR_REGTYPES] = { [SCDL] = { 0x30, 16 }, [SCCKS] = { 0x34, 16 }, }, + .fifosize = 128, + .overrun_reg = SCLSR, + .overrun_mask = SCLSR_ORER, + .sampling_rate_mask = SCI_SR_RANGE(8, 32), + .error_mask = SCIF_DEFAULT_ERROR_MASK, + .error_clear = SCIF_ERROR_CLEAR, }, /* @@ -345,6 +401,12 @@ static const struct sci_port_params sci_port_params[SCIx_NR_REGTYPES] = { [SCFDR] = { 0x1c, 16 }, [SCLSR] = { 0x24, 16 }, }, + .fifosize = 16, + .overrun_reg = SCLSR, + .overrun_mask = SCLSR_ORER, + .sampling_rate_mask = SCI_SR(32), + .error_mask = SCIF_DEFAULT_ERROR_MASK, + .error_clear = SCIF_ERROR_CLEAR, }, /* @@ -366,6 +428,12 @@ static const struct sci_port_params sci_port_params[SCIx_NR_REGTYPES] = { [SCSPTR] = { 0x24, 16 }, [SCLSR] = { 0x28, 16 }, }, + .fifosize = 16, + .overrun_reg = SCLSR, + .overrun_mask = SCLSR_ORER, + .sampling_rate_mask = SCI_SR(32), + .error_mask = SCIF_DEFAULT_ERROR_MASK, + .error_clear = SCIF_ERROR_CLEAR, }, /* @@ -383,6 +451,12 @@ static const struct sci_port_params sci_port_params[SCIx_NR_REGTYPES] = { [SCFCR] = { 0x18, 16 }, [SCFDR] = { 0x1c, 16 }, }, + .fifosize = 16, + .overrun_reg = SCxSR, + .overrun_mask = SCIFA_ORER, + .sampling_rate_mask = SCI_SR(16), + .error_mask = SCIF_DEFAULT_ERROR_MASK | SCIFA_ORER, + .error_clear = SCIF_ERROR_CLEAR & ~SCIFA_ORER, }, }; @@ -545,7 +619,7 @@ static void sci_clear_SCxSR(struct uart_port *port, unsigned int mask) if (port->type == PORT_SCI) { /* Just store the mask */ serial_port_out(port, SCxSR, mask); - } else if (to_sci_port(port)->overrun_mask == SCIFA_ORER) { + } else if (to_sci_port(port)->params->overrun_mask == SCIFA_ORER) { /* SCIFA/SCIFB and SCIF on SH7705/SH7720/SH7721 */ /* Only clear the status bits we want to clear */ serial_port_out(port, SCxSR, @@ -640,11 +714,13 @@ static void sci_init_pins(struct uart_port *port, unsigned int cflag) static int sci_txfill(struct uart_port *port) { + struct sci_port *s = to_sci_port(port); + unsigned int fifo_mask = (s->params->fifosize << 1) - 1; const struct plat_sci_reg *reg; reg = sci_getreg(port, SCTFDR); if (reg->size) - return serial_port_in(port, SCTFDR) & ((port->fifosize << 1) - 1); + return serial_port_in(port, SCTFDR) & fifo_mask; reg = sci_getreg(port, SCFDR); if (reg->size) @@ -660,15 +736,17 @@ static int sci_txroom(struct uart_port *port) static int sci_rxfill(struct uart_port *port) { + struct sci_port *s = to_sci_port(port); + unsigned int fifo_mask = (s->params->fifosize << 1) - 1; const struct plat_sci_reg *reg; reg = sci_getreg(port, SCRFDR); if (reg->size) - return serial_port_in(port, SCRFDR) & ((port->fifosize << 1) - 1); + return serial_port_in(port, SCRFDR) & fifo_mask; reg = sci_getreg(port, SCFDR); if (reg->size) - return serial_port_in(port, SCFDR) & ((port->fifosize << 1) - 1); + return serial_port_in(port, SCFDR) & fifo_mask; return (serial_port_in(port, SCxSR) & SCxSR_RDxF(port)) != 0; } @@ -879,7 +957,7 @@ static int sci_handle_errors(struct uart_port *port) struct sci_port *s = to_sci_port(port); /* Handle overruns */ - if (status & s->overrun_mask) { + if (status & s->params->overrun_mask) { port->icount.overrun++; /* overrun error */ @@ -945,14 +1023,14 @@ static int sci_handle_fifo_overrun(struct uart_port *port) int copied = 0; u16 status; - reg = sci_getreg(port, s->overrun_reg); + reg = sci_getreg(port, s->params->overrun_reg); if (!reg->size) return 0; - status = serial_port_in(port, s->overrun_reg); - if (status & s->overrun_mask) { - status &= ~s->overrun_mask; - serial_port_out(port, s->overrun_reg, status); + status = serial_port_in(port, s->params->overrun_reg); + if (status & s->params->overrun_mask) { + status &= ~s->params->overrun_mask; + serial_port_out(port, s->params->overrun_reg, status); port->icount.overrun++; @@ -1541,12 +1619,10 @@ static irqreturn_t sci_mpxed_interrupt(int irq, void *ptr) ssr_status = serial_port_in(port, SCxSR); scr_status = serial_port_in(port, SCSCR); - if (s->overrun_reg == SCxSR) + if (s->params->overrun_reg == SCxSR) orer_status = ssr_status; - else { - if (sci_getreg(port, s->overrun_reg)->size) - orer_status = serial_port_in(port, s->overrun_reg); - } + else if (sci_getreg(port, s->params->overrun_reg)->size) + orer_status = serial_port_in(port, s->params->overrun_reg); err_enabled = scr_status & port_rx_irq_mask(port); @@ -1572,7 +1648,7 @@ static irqreturn_t sci_mpxed_interrupt(int irq, void *ptr) ret = sci_br_interrupt(irq, ptr); /* Overrun Interrupt */ - if (orer_status & s->overrun_mask) { + if (orer_status & s->params->overrun_mask) { sci_handle_fifo_overrun(port); ret = IRQ_HANDLED; } @@ -2590,51 +2666,13 @@ static int sci_init_single(struct platform_device *dev, if (unlikely(sci_port->params == NULL)) return -EINVAL; - switch (p->type) { - case PORT_SCIFB: - port->fifosize = 256; - sci_port->overrun_reg = SCxSR; - sci_port->overrun_mask = SCIFA_ORER; - sci_port->sampling_rate_mask = SCI_SR_SCIFAB; - break; - case PORT_HSCIF: - port->fifosize = 128; - sci_port->overrun_reg = SCLSR; - sci_port->overrun_mask = SCLSR_ORER; - sci_port->sampling_rate_mask = SCI_SR_RANGE(8, 32); - break; - case PORT_SCIFA: - port->fifosize = 64; - sci_port->overrun_reg = SCxSR; - sci_port->overrun_mask = SCIFA_ORER; - sci_port->sampling_rate_mask = SCI_SR_SCIFAB; - break; - case PORT_SCIF: - port->fifosize = 16; - if (p->regtype == SCIx_SH7705_SCIF_REGTYPE) { - sci_port->overrun_reg = SCxSR; - sci_port->overrun_mask = SCIFA_ORER; - sci_port->sampling_rate_mask = SCI_SR(16); - } else { - sci_port->overrun_reg = SCLSR; - sci_port->overrun_mask = SCLSR_ORER; - sci_port->sampling_rate_mask = SCI_SR(32); - } - break; - default: - port->fifosize = 1; - sci_port->overrun_reg = SCxSR; - sci_port->overrun_mask = SCI_ORER; - sci_port->sampling_rate_mask = SCI_SR(32); - break; - } - /* SCIFA on sh7723 and sh7724 need a custom sampling rate that doesn't * match the SoC datasheet, this should be investigated. Let platform * data override the sampling rate for now. */ - if (p->sampling_rate) - sci_port->sampling_rate_mask = SCI_SR(p->sampling_rate); + sci_port->sampling_rate_mask = p->sampling_rate + ? SCI_SR(p->sampling_rate) + : sci_port->params->sampling_rate_mask; if (!early) { ret = sci_init_clocks(sci_port, &dev->dev); @@ -2650,29 +2688,10 @@ static int sci_init_single(struct platform_device *dev, sci_port->break_timer.function = sci_break_timer; init_timer(&sci_port->break_timer); - /* - * Establish some sensible defaults for the error detection. - */ - if (p->type == PORT_SCI) { - sci_port->error_mask = SCI_DEFAULT_ERROR_MASK; - sci_port->error_clear = SCI_ERROR_CLEAR; - } else { - sci_port->error_mask = SCIF_DEFAULT_ERROR_MASK; - sci_port->error_clear = SCIF_ERROR_CLEAR; - } - - /* - * Make the error mask inclusive of overrun detection, if - * supported. - */ - if (sci_port->overrun_reg == SCxSR) { - sci_port->error_mask |= sci_port->overrun_mask; - sci_port->error_clear &= ~sci_port->overrun_mask; - } - port->type = p->type; port->flags = UPF_FIXED_PORT | UPF_BOOT_AUTOCONF | p->flags; port->regshift = p->regshift; + port->fifosize = sci_port->params->fifosize; /* * The UART port needs an IRQ value, so we peg this to the RX IRQ diff --git a/drivers/tty/serial/sh-sci.h b/drivers/tty/serial/sh-sci.h index ffa6d688c335..08073f0db732 100644 --- a/drivers/tty/serial/sh-sci.h +++ b/drivers/tty/serial/sh-sci.h @@ -151,12 +151,12 @@ enum { #define SCxSR_PER(port) (((port)->type == PORT_SCI) ? SCI_PER : SCIF_PER) #define SCxSR_BRK(port) (((port)->type == PORT_SCI) ? 0x00 : SCIF_BRK) -#define SCxSR_ERRORS(port) (to_sci_port(port)->error_mask) +#define SCxSR_ERRORS(port) (to_sci_port(port)->params->error_mask) #define SCxSR_RDxF_CLEAR(port) \ (((port)->type == PORT_SCI) ? SCI_RDxF_CLEAR : SCIF_RDxF_CLEAR) #define SCxSR_ERROR_CLEAR(port) \ - (to_sci_port(port)->error_clear) + (to_sci_port(port)->params->error_clear) #define SCxSR_TDxE_CLEAR(port) \ (((port)->type == PORT_SCI) ? SCI_TDxE_CLEAR : SCIF_TDxE_CLEAR) #define SCxSR_BREAK_CLEAR(port) \ -- cgit v1.2.3-59-g8ed1b From 219fb0c1436e4893a290ba270bc0e644d02465a3 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Wed, 11 Jan 2017 16:43:37 +0200 Subject: serial: sh-sci: Remove the platform data dma slave rx/tx channel IDs Only SH platforms still use platform data for the sh-sci, and none of them declare DMA channels connected to the SCI. Remove the corresponding platform data fields and simplify the driver accordingly. Signed-off-by: Laurent Pinchart Reviewed-by: Geert Uytterhoeven Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/sh-sci.c | 23 ++++++----------------- include/linux/serial_sci.h | 3 --- 2 files changed, 6 insertions(+), 20 deletions(-) diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index a8607cacee6c..c6aa5b9c2bfd 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -1387,20 +1387,14 @@ static void rx_timer_fn(unsigned long arg) } static struct dma_chan *sci_request_dma_chan(struct uart_port *port, - enum dma_transfer_direction dir, - unsigned int id) + enum dma_transfer_direction dir) { - dma_cap_mask_t mask; struct dma_chan *chan; struct dma_slave_config cfg; int ret; - dma_cap_zero(mask); - dma_cap_set(DMA_SLAVE, mask); - - chan = dma_request_slave_channel_compat(mask, shdma_chan_filter, - (void *)(unsigned long)id, port->dev, - dir == DMA_MEM_TO_DEV ? "tx" : "rx"); + chan = dma_request_slave_channel(port->dev, + dir == DMA_MEM_TO_DEV ? "tx" : "rx"); if (!chan) { dev_warn(port->dev, "dma_request_slave_channel_compat failed\n"); @@ -1436,12 +1430,11 @@ static void sci_request_dma(struct uart_port *port) dev_dbg(port->dev, "%s: port %d\n", __func__, port->line); - if (!port->dev->of_node && - (s->cfg->dma_slave_tx <= 0 || s->cfg->dma_slave_rx <= 0)) + if (!port->dev->of_node) return; s->cookie_tx = -EINVAL; - chan = sci_request_dma_chan(port, DMA_MEM_TO_DEV, s->cfg->dma_slave_tx); + chan = sci_request_dma_chan(port, DMA_MEM_TO_DEV); dev_dbg(port->dev, "%s: TX: got channel %p\n", __func__, chan); if (chan) { s->chan_tx = chan; @@ -1463,7 +1456,7 @@ static void sci_request_dma(struct uart_port *port) INIT_WORK(&s->work_tx, work_fn_tx); } - chan = sci_request_dma_chan(port, DMA_DEV_TO_MEM, s->cfg->dma_slave_rx); + chan = sci_request_dma_chan(port, DMA_DEV_TO_MEM); dev_dbg(port->dev, "%s: RX: got channel %p\n", __func__, chan); if (chan) { unsigned int i; @@ -2706,10 +2699,6 @@ static int sci_init_single(struct platform_device *dev, port->serial_in = sci_serial_in; port->serial_out = sci_serial_out; - if (p->dma_slave_tx > 0 && p->dma_slave_rx > 0) - dev_dbg(port->dev, "DMA tx %d, rx %d\n", - p->dma_slave_tx, p->dma_slave_rx); - return 0; } diff --git a/include/linux/serial_sci.h b/include/linux/serial_sci.h index 9f2bfd055742..1a894c47bfc0 100644 --- a/include/linux/serial_sci.h +++ b/include/linux/serial_sci.h @@ -71,9 +71,6 @@ struct plat_sci_port { unsigned char regtype; struct plat_sci_port_ops *ops; - - unsigned int dma_slave_tx; - unsigned int dma_slave_rx; }; #endif /* __LINUX_SERIAL_SCI_H */ -- cgit v1.2.3-59-g8ed1b From d5cb1319a91d4f1328b1c70b82c5899acd96af85 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Wed, 11 Jan 2017 16:43:38 +0200 Subject: serial: sh-sci: Remove manual break debouncing The sh-sci driver implements manual break debouncing for a few SH platforms by reading the value of the RX pin port register. This feature is optional and the driver considers all negative or zero values of the platform data port_reg field as invalid. As the four platforms that set the field to a register address all use an address higher than 0x7fffffff, the driver will always consider the value as invalid and never perform debouncing. The feature is unused, remove it. Debouncing could be implemented properly in the future using the pinctrl and GPIO APIs if desired. Signed-off-by: Laurent Pinchart Reviewed-by: Geert Uytterhoeven Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/sh-sci.c | 124 +++----------------------------------------- include/linux/serial_sci.h | 5 -- 2 files changed, 7 insertions(+), 122 deletions(-) diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index c6aa5b9c2bfd..ae1404e701ea 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -125,10 +125,6 @@ struct sci_port { resource_size_t reg_size; struct mctrl_gpios *gpios; - /* Break timer */ - struct timer_list break_timer; - int break_flag; - /* Clocks */ struct clk *clks[SCI_NUM_CLKS]; unsigned long clk_rates[SCI_NUM_CLKS]; @@ -517,14 +513,6 @@ static void sci_port_disable(struct sci_port *sci_port) if (!sci_port->port.dev) return; - /* Cancel the break timer to ensure that the timer handler will not try - * to access the hardware with clocks and power disabled. Reset the - * break flag to make the break debouncing state machine ready for the - * next break. - */ - del_timer_sync(&sci_port->break_timer); - sci_port->break_flag = 0; - for (i = SCI_NUM_CLKS; i-- > 0; ) clk_disable_unprepare(sci_port->clks[i]); @@ -751,20 +739,6 @@ static int sci_rxfill(struct uart_port *port) return (serial_port_in(port, SCxSR) & SCxSR_RDxF(port)) != 0; } -/* - * SCI helper for checking the state of the muxed port/RXD pins. - */ -static inline int sci_rxd_in(struct uart_port *port) -{ - struct sci_port *s = to_sci_port(port); - - if (s->cfg->port_reg <= 0) - return 1; - - /* Cast for ARM damage */ - return !!__raw_readb((void __iomem *)(uintptr_t)s->cfg->port_reg); -} - /* ********************************************************************** * * the interrupt related routines * * ********************************************************************** */ @@ -832,7 +806,6 @@ static void sci_transmit_chars(struct uart_port *port) static void sci_receive_chars(struct uart_port *port) { - struct sci_port *sci_port = to_sci_port(port); struct tty_port *tport = &port->state->port; int i, count, copied = 0; unsigned short status; @@ -852,8 +825,7 @@ static void sci_receive_chars(struct uart_port *port) if (port->type == PORT_SCI) { char c = serial_port_in(port, SCxRDR); - if (uart_handle_sysrq_char(port, c) || - sci_port->break_flag) + if (uart_handle_sysrq_char(port, c)) count = 0; else tty_insert_flip_char(tport, c, TTY_NORMAL); @@ -862,25 +834,6 @@ static void sci_receive_chars(struct uart_port *port) char c = serial_port_in(port, SCxRDR); status = serial_port_in(port, SCxSR); -#if defined(CONFIG_CPU_SH3) - /* Skip "chars" during break */ - if (sci_port->break_flag) { - if ((c == 0) && - (status & SCxSR_FER(port))) { - count--; i--; - continue; - } - - /* Nonzero => end-of-break */ - dev_dbg(port->dev, "debounce<%02x>\n", c); - sci_port->break_flag = 0; - - if (STEPFN(c)) { - count--; i--; - continue; - } - } -#endif /* CONFIG_CPU_SH3 */ if (uart_handle_sysrq_char(port, c)) { count--; i--; continue; @@ -918,37 +871,6 @@ static void sci_receive_chars(struct uart_port *port) } } -#define SCI_BREAK_JIFFIES (HZ/20) - -/* - * The sci generates interrupts during the break, - * 1 per millisecond or so during the break period, for 9600 baud. - * So dont bother disabling interrupts. - * But dont want more than 1 break event. - * Use a kernel timer to periodically poll the rx line until - * the break is finished. - */ -static inline void sci_schedule_break_timer(struct sci_port *port) -{ - mod_timer(&port->break_timer, jiffies + SCI_BREAK_JIFFIES); -} - -/* Ensure that two consecutive samples find the break over. */ -static void sci_break_timer(unsigned long data) -{ - struct sci_port *port = (struct sci_port *)data; - - if (sci_rxd_in(&port->port) == 0) { - port->break_flag = 1; - sci_schedule_break_timer(port); - } else if (port->break_flag == 1) { - /* break is over. */ - port->break_flag = 2; - sci_schedule_break_timer(port); - } else - port->break_flag = 0; -} - static int sci_handle_errors(struct uart_port *port) { int copied = 0; @@ -968,35 +890,13 @@ static int sci_handle_errors(struct uart_port *port) } if (status & SCxSR_FER(port)) { - if (sci_rxd_in(port) == 0) { - /* Notify of BREAK */ - struct sci_port *sci_port = to_sci_port(port); - - if (!sci_port->break_flag) { - port->icount.brk++; - - sci_port->break_flag = 1; - sci_schedule_break_timer(sci_port); - - /* Do sysrq handling. */ - if (uart_handle_break(port)) - return 0; - - dev_dbg(port->dev, "BREAK detected\n"); - - if (tty_insert_flip_char(tport, 0, TTY_BREAK)) - copied++; - } - - } else { - /* frame error */ - port->icount.frame++; + /* frame error */ + port->icount.frame++; - if (tty_insert_flip_char(tport, 0, TTY_FRAME)) - copied++; + if (tty_insert_flip_char(tport, 0, TTY_FRAME)) + copied++; - dev_notice(port->dev, "frame error\n"); - } + dev_notice(port->dev, "frame error\n"); } if (status & SCxSR_PER(port)) { @@ -1049,17 +949,11 @@ static int sci_handle_breaks(struct uart_port *port) int copied = 0; unsigned short status = serial_port_in(port, SCxSR); struct tty_port *tport = &port->state->port; - struct sci_port *s = to_sci_port(port); if (uart_handle_break(port)) return 0; - if (!s->break_flag && status & SCxSR_BRK(port)) { -#if defined(CONFIG_CPU_SH3) - /* Debounce break */ - s->break_flag = 1; -#endif - + if (status & SCxSR_BRK(port)) { port->icount.brk++; /* Notify of BREAK */ @@ -2677,10 +2571,6 @@ static int sci_init_single(struct platform_device *dev, pm_runtime_enable(&dev->dev); } - sci_port->break_timer.data = (unsigned long)sci_port; - sci_port->break_timer.function = sci_break_timer; - init_timer(&sci_port->break_timer); - port->type = p->type; port->flags = UPF_FIXED_PORT | UPF_BOOT_AUTOCONF | p->flags; port->regshift = p->regshift; diff --git a/include/linux/serial_sci.h b/include/linux/serial_sci.h index 1a894c47bfc0..b4419931bf4c 100644 --- a/include/linux/serial_sci.h +++ b/include/linux/serial_sci.h @@ -9,8 +9,6 @@ * Generic header for SuperH (H)SCI(F) (used by sh/sh64 and related parts) */ -#define SCIx_NOT_SUPPORTED (-1) - /* Serial Control Register (@ = not supported by all parts) */ #define SCSCR_TIE BIT(7) /* Transmit Interrupt Enable */ #define SCSCR_RIE BIT(6) /* Receive Interrupt Enable */ @@ -41,8 +39,6 @@ enum { SCIx_NR_REGTYPES, }; -struct device; - struct plat_sci_port_ops { void (*init_pins)(struct uart_port *, unsigned int cflag); }; @@ -66,7 +62,6 @@ struct plat_sci_port { /* * Platform overrides if necessary, defaults otherwise. */ - int port_reg; unsigned char regshift; unsigned char regtype; -- cgit v1.2.3-59-g8ed1b From 97ed9790c514066bfae67f22e084b505ed5af436 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Wed, 11 Jan 2017 16:43:39 +0200 Subject: serial: sh-sci: Remove unused platform data capabilities field The field isn't set by any platform but is only used internally in the driver to hold data parsed from DT. Move it to the sci_port structure. Signed-off-by: Laurent Pinchart Reviewed-by: Geert Uytterhoeven Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/sh-sci.c | 11 +++++++---- include/linux/serial_sci.h | 6 ------ 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index ae1404e701ea..a04ed40279d1 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -149,6 +149,7 @@ struct sci_port { unsigned int rx_timeout; #endif + bool has_rtscts; bool autorts; }; @@ -680,7 +681,7 @@ static void sci_init_pins(struct uart_port *port, unsigned int cflag) /* Enable RXD and TXD pin functions */ ctrl &= ~(SCPCR_RXDC | SCPCR_TXDC); - if (to_sci_port(port)->cfg->capabilities & SCIx_HAVE_RTSCTS) { + if (to_sci_port(port)->has_rtscts) { /* RTS# is output, driven 1 */ ctrl |= SCPCR_RTSC; serial_port_out(port, SCPDR, @@ -1738,7 +1739,7 @@ static void sci_set_mctrl(struct uart_port *port, unsigned int mctrl) mctrl_gpio_set(s->gpios, mctrl); - if (!(s->cfg->capabilities & SCIx_HAVE_RTSCTS)) + if (!s->has_rtscts) return; if (!(mctrl & TIOCM_RTS)) { @@ -2809,6 +2810,7 @@ sci_parse_dt(struct platform_device *pdev, unsigned int *dev_id) struct device_node *np = pdev->dev.of_node; const struct of_device_id *match; struct plat_sci_port *p; + struct sci_port *sp; int id; if (!IS_ENABLED(CONFIG_OF) || !np) @@ -2829,13 +2831,14 @@ sci_parse_dt(struct platform_device *pdev, unsigned int *dev_id) return NULL; } + sp = &sci_ports[id]; *dev_id = id; p->type = SCI_OF_TYPE(match->data); p->regtype = SCI_OF_REGTYPE(match->data); if (of_find_property(np, "uart-has-rtscts", NULL)) - p->capabilities |= SCIx_HAVE_RTSCTS; + sp->has_rtscts = true; return p; } @@ -2863,7 +2866,7 @@ static int sci_probe_single(struct platform_device *dev, if (IS_ERR(sciport->gpios) && PTR_ERR(sciport->gpios) != -ENOSYS) return PTR_ERR(sciport->gpios); - if (p->capabilities & SCIx_HAVE_RTSCTS) { + if (sciport->has_rtscts) { if (!IS_ERR_OR_NULL(mctrl_gpio_to_gpiod(sciport->gpios, UART_GPIO_CTS)) || !IS_ERR_OR_NULL(mctrl_gpio_to_gpiod(sciport->gpios, diff --git a/include/linux/serial_sci.h b/include/linux/serial_sci.h index b4419931bf4c..f9a4526f4ec5 100644 --- a/include/linux/serial_sci.h +++ b/include/linux/serial_sci.h @@ -43,18 +43,12 @@ struct plat_sci_port_ops { void (*init_pins)(struct uart_port *, unsigned int cflag); }; -/* - * Port-specific capabilities - */ -#define SCIx_HAVE_RTSCTS BIT(0) - /* * Platform device specific platform_data struct */ struct plat_sci_port { unsigned int type; /* SCI / SCIF / IRDA / HSCIF */ upf_t flags; /* UPF_* flags */ - unsigned long capabilities; /* Port features/capabilities */ unsigned int sampling_rate; unsigned int scscr; /* SCSCR initialization */ -- cgit v1.2.3-59-g8ed1b From dfc80387aefb78161f83732804c6d01c89c24595 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Wed, 11 Jan 2017 16:43:40 +0200 Subject: serial: sh-sci: Compute the regshift value for SCI ports SCI instances found in SH SoCs have different spacing between registers depending on the SoC. The platform data contains a regshift field that tells the driver by how many bits to shift the register offset to compute its address. We can compute the regshift value automatically based on the memory resource size, there's no need to pass the value through platform data. Fix the sh7750 SCI and sh7760 SIM port memory resources length to ensure proper computation of the regshift value. Signed-off-by: Laurent Pinchart Reviewed-by: Geert Uytterhoeven Signed-off-by: Greg Kroah-Hartman --- arch/sh/kernel/cpu/sh3/setup-sh770x.c | 1 - arch/sh/kernel/cpu/sh4/setup-sh7750.c | 3 +-- arch/sh/kernel/cpu/sh4/setup-sh7760.c | 10 ++++++++-- drivers/tty/serial/sh-sci.c | 8 +++++++- include/linux/serial_sci.h | 1 - 5 files changed, 16 insertions(+), 7 deletions(-) diff --git a/arch/sh/kernel/cpu/sh3/setup-sh770x.c b/arch/sh/kernel/cpu/sh3/setup-sh770x.c index 592cd9ab30c4..59a88611df55 100644 --- a/arch/sh/kernel/cpu/sh3/setup-sh770x.c +++ b/arch/sh/kernel/cpu/sh3/setup-sh770x.c @@ -111,7 +111,6 @@ static struct platform_device rtc_device = { static struct plat_sci_port scif0_platform_data = { .type = PORT_SCI, .ops = &sh770x_sci_port_ops, - .regshift = 1, }; static struct resource scif0_resources[] = { diff --git a/arch/sh/kernel/cpu/sh4/setup-sh7750.c b/arch/sh/kernel/cpu/sh4/setup-sh7750.c index d98a55416306..57d30689204d 100644 --- a/arch/sh/kernel/cpu/sh4/setup-sh7750.c +++ b/arch/sh/kernel/cpu/sh4/setup-sh7750.c @@ -39,11 +39,10 @@ static struct platform_device rtc_device = { static struct plat_sci_port sci_platform_data = { .type = PORT_SCI, - .regshift = 2, }; static struct resource sci_resources[] = { - DEFINE_RES_MEM(0xffe00000, 0x100), + DEFINE_RES_MEM(0xffe00000, 0x20), DEFINE_RES_IRQ(evt2irq(0x4e0)), }; diff --git a/arch/sh/kernel/cpu/sh4/setup-sh7760.c b/arch/sh/kernel/cpu/sh4/setup-sh7760.c index 0c0cdfc69dcc..e51fe1734e13 100644 --- a/arch/sh/kernel/cpu/sh4/setup-sh7760.c +++ b/arch/sh/kernel/cpu/sh4/setup-sh7760.c @@ -200,12 +200,18 @@ static struct platform_device scif2_device = { }; static struct plat_sci_port scif3_platform_data = { + /* + * This is actually a SIM card module serial port, based on an SCI with + * additional registers. The sh-sci driver doesn't support the SIM port + * type, declare it as a SCI. Don't declare the additional registers in + * the memory resource or the driver will compute an incorrect regshift + * value. + */ .type = PORT_SCI, - .regshift = 2, }; static struct resource scif3_resources[] = { - DEFINE_RES_MEM(0xfe480000, 0x100), + DEFINE_RES_MEM(0xfe480000, 0x10), DEFINE_RES_IRQ(evt2irq(0xc00)), DEFINE_RES_IRQ(evt2irq(0xc20)), DEFINE_RES_IRQ(evt2irq(0xc40)), diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index a04ed40279d1..a18f4cb8e1fb 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -2574,9 +2574,15 @@ static int sci_init_single(struct platform_device *dev, port->type = p->type; port->flags = UPF_FIXED_PORT | UPF_BOOT_AUTOCONF | p->flags; - port->regshift = p->regshift; port->fifosize = sci_port->params->fifosize; + if (port->type == PORT_SCI) { + if (sci_port->reg_size >= 0x20) + port->regshift = 2; + else + port->regshift = 1; + } + /* * The UART port needs an IRQ value, so we peg this to the RX IRQ * for the multi-IRQ ports, which is where we are primarily diff --git a/include/linux/serial_sci.h b/include/linux/serial_sci.h index f9a4526f4ec5..e598eaef3962 100644 --- a/include/linux/serial_sci.h +++ b/include/linux/serial_sci.h @@ -56,7 +56,6 @@ struct plat_sci_port { /* * Platform overrides if necessary, defaults otherwise. */ - unsigned char regshift; unsigned char regtype; struct plat_sci_port_ops *ops; -- cgit v1.2.3-59-g8ed1b From 6a171b29937984a5e0bf29d6577b055998f03edb Mon Sep 17 00:00:00 2001 From: Jason Uy Date: Wed, 11 Jan 2017 11:48:20 -0800 Subject: serial: 8250_dw: Allow hardware flow control to be used In the most common use case, the Synopsys DW UART driver does not set the set_termios callback function. This prevents UPSTAT_AUTOCTS from being set when the UART flag CRTSCTS is set. As a result, the driver will use software flow control as opposed to hardware flow control. To fix the problem, the set_termios callback function is set to the DW specific function. The logic to set UPSTAT_AUTOCTS is moved so that any clock error will not affect setting the hardware flow control. Reviewed-by: Scott Branden Reviewed-by: Ray Jui Signed-off-by: Jason Uy Reviewed-by: Kefeng Wang Reviewed-by: Andy Shevchenko Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_dw.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/tty/serial/8250/8250_dw.c b/drivers/tty/serial/8250/8250_dw.c index c89fafc972b6..c89ae4581378 100644 --- a/drivers/tty/serial/8250/8250_dw.c +++ b/drivers/tty/serial/8250/8250_dw.c @@ -248,11 +248,11 @@ static void dw8250_set_termios(struct uart_port *p, struct ktermios *termios, if (!ret) p->uartclk = rate; +out: p->status &= ~UPSTAT_AUTOCTS; if (termios->c_cflag & CRTSCTS) p->status |= UPSTAT_AUTOCTS; -out: serial8250_do_set_termios(p, termios, old); } @@ -326,13 +326,11 @@ static void dw8250_quirks(struct uart_port *p, struct dw8250_data *data) p->serial_in = dw8250_serial_in32; data->uart_16550_compatible = true; } - p->set_termios = dw8250_set_termios; } /* Platforms with iDMA */ if (platform_get_resource_byname(to_platform_device(p->dev), IORESOURCE_MEM, "lpss_priv")) { - p->set_termios = dw8250_set_termios; data->dma.rx_param = p->dev->parent; data->dma.tx_param = p->dev->parent; data->dma.fn = dw8250_idma_filter; @@ -414,6 +412,7 @@ static int dw8250_probe(struct platform_device *pdev) p->serial_in = dw8250_serial_in; p->serial_out = dw8250_serial_out; p->set_ldisc = dw8250_set_ldisc; + p->set_termios = dw8250_set_termios; p->membase = devm_ioremap(dev, regs->start, resource_size(regs)); if (!p->membase) -- cgit v1.2.3-59-g8ed1b From 4831e0d9054c62c0bd134315de34e7701804707a Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Wed, 11 Jan 2017 16:31:35 +0200 Subject: serial: 8250_mid: handle interrupt correctly in DMA case Starting from Tangier B0 and continuing on Anniedale the HSU DMA interrupt line is actually shared with UART. Handling them independently is racy and quite often comes with the following traceback. irq 54: nobody cared (try booting with the "irqpoll" option) CPU: 0 PID: 0 Comm: swapper/0 Not tainted 4.9.0-rc6-edison64-86244934+ #1 Hardware name: Intel Corporation Merrifield/BODEGA BAY, BIOS 542 2015.01.21:18.19.48 ffff88003f203eb0 ffffffff8130e718 ffff880032627000 ffff88003262709c ffff88003f203ed8 ffffffff810a3960 ffff880032627000 0000000000000000 ffff880032627000 ffff88003f203f10 ffffffff810a3cc7 ffff880032627000 Call Trace: [] dump_stack+0x4d/0x65 [] __report_bad_irq+0x30/0xc0 [] note_interrupt+0x227/0x270 [] handle_irq_event_percpu+0x40/0x50 [] handle_irq_event+0x27/0x50 [] handle_fasteoi_irq+0x85/0x150 [] handle_irq+0x6e/0x120 [] ? _local_bh_enable+0x1c/0x50 [] do_IRQ+0x46/0xd0 [] common_interrupt+0x7f/0x7f [] ? mwait_idle+0x7d/0x140 [] arch_cpu_idle+0xa/0x10 [] default_idle_call+0x20/0x30 [] cpu_startup_entry+0x16d/0x1d0 [] rest_init+0x6d/0x70 [] start_kernel+0x3e2/0x3ef [] x86_64_start_reservations+0x38/0x3a [] x86_64_start_kernel+0xea/0xed handlers: [] serial8250_interrupt Disabling IRQ #54 Fix this by handling interrupt only in one place. The issue is discussed here: https://github.com/andy-shev/linux/issues/5 Moreover this also fixes another bug when Rx DMA returns wrong residue and we can't rely on it. Reviewed-by: Heikki Krogerus Signed-off-by: Andy Shevchenko Acked-by: Vinod Koul Signed-off-by: Greg Kroah-Hartman --- drivers/dma/hsu/pci.c | 17 +++++++++++++++-- drivers/tty/serial/8250/8250_mid.c | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 2 deletions(-) diff --git a/drivers/dma/hsu/pci.c b/drivers/dma/hsu/pci.c index 4875fa428e81..ad45cd344bba 100644 --- a/drivers/dma/hsu/pci.c +++ b/drivers/dma/hsu/pci.c @@ -23,15 +23,28 @@ #define HSU_PCI_CHAN_OFFSET 0x100 +#define PCI_DEVICE_ID_INTEL_MFLD_HSU_DMA 0x081e +#define PCI_DEVICE_ID_INTEL_MRFLD_HSU_DMA 0x1192 + static irqreturn_t hsu_pci_irq(int irq, void *dev) { struct hsu_dma_chip *chip = dev; + struct pci_dev *pdev = to_pci_dev(chip->dev); u32 dmaisr; u32 status; unsigned short i; int ret = 0; int err; + /* + * On Intel Tangier B0 and Anniedale the interrupt line, disregarding + * to have different numbers, is shared between HSU DMA and UART IPs. + * Thus on such SoCs we are expecting that IRQ handler is called in + * UART driver only. + */ + if (pdev->device == PCI_DEVICE_ID_INTEL_MRFLD_HSU_DMA) + return IRQ_HANDLED; + dmaisr = readl(chip->regs + HSU_PCI_DMAISR); for (i = 0; i < chip->hsu->nr_channels; i++) { if (dmaisr & 0x1) { @@ -113,8 +126,8 @@ static void hsu_pci_remove(struct pci_dev *pdev) } static const struct pci_device_id hsu_pci_id_table[] = { - { PCI_VDEVICE(INTEL, 0x081e), 0 }, - { PCI_VDEVICE(INTEL, 0x1192), 0 }, + { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_MFLD_HSU_DMA), 0 }, + { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_MRFLD_HSU_DMA), 0 }, { } }; MODULE_DEVICE_TABLE(pci, hsu_pci_id_table); diff --git a/drivers/tty/serial/8250/8250_mid.c b/drivers/tty/serial/8250/8250_mid.c index ac013edf4992..6730d9eef81e 100644 --- a/drivers/tty/serial/8250/8250_mid.c +++ b/drivers/tty/serial/8250/8250_mid.c @@ -75,6 +75,37 @@ static int pnw_setup(struct mid8250 *mid, struct uart_port *p) return 0; } +static int tng_handle_irq(struct uart_port *p) +{ + struct mid8250 *mid = p->private_data; + struct uart_8250_port *up = up_to_u8250p(p); + struct hsu_dma_chip *chip; + u32 status; + int ret = 0; + int err; + + chip = pci_get_drvdata(mid->dma_dev); + + /* Rx DMA */ + err = hsu_dma_get_status(chip, mid->dma_index * 2 + 1, &status); + if (err > 0) { + serial8250_rx_dma_flush(up); + ret |= 1; + } else if (err == 0) + ret |= hsu_dma_do_irq(chip, mid->dma_index * 2 + 1, status); + + /* Tx DMA */ + err = hsu_dma_get_status(chip, mid->dma_index * 2, &status); + if (err > 0) + ret |= 1; + else if (err == 0) + ret |= hsu_dma_do_irq(chip, mid->dma_index * 2, status); + + /* UART */ + ret |= serial8250_handle_irq(p, serial_port_in(p, UART_IIR)); + return IRQ_RETVAL(ret); +} + static int tng_setup(struct mid8250 *mid, struct uart_port *p) { struct pci_dev *pdev = to_pci_dev(p->dev); @@ -90,6 +121,8 @@ static int tng_setup(struct mid8250 *mid, struct uart_port *p) mid->dma_index = index; mid->dma_dev = pci_get_slot(pdev->bus, PCI_DEVFN(5, 0)); + + p->handle_irq = tng_handle_irq; return 0; } -- cgit v1.2.3-59-g8ed1b From 6d59225f2da7e8db31aa10b458eef7e8d8f53076 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Wed, 11 Jan 2017 16:31:36 +0200 Subject: serial: 8250_mid: enable MSI on Denverton Enable MSI type of interrupt if PCI BIOS supports it. Reviewed-by: Heikki Krogerus Signed-off-by: Andy Shevchenko Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_mid.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/tty/serial/8250/8250_mid.c b/drivers/tty/serial/8250/8250_mid.c index 6730d9eef81e..85011c9ac0ee 100644 --- a/drivers/tty/serial/8250/8250_mid.c +++ b/drivers/tty/serial/8250/8250_mid.c @@ -164,8 +164,14 @@ static int dnv_setup(struct mid8250 *mid, struct uart_port *p) unsigned int bar = FL_GET_BASE(mid->board->flags); int ret; + ret = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_ALL_TYPES); + if (ret < 0) + return ret; + + p->irq = pci_irq_vector(pdev, 0); + chip->dev = &pdev->dev; - chip->irq = pdev->irq; + chip->irq = pci_irq_vector(pdev, 0); chip->regs = p->membase; chip->length = pci_resource_len(pdev, bar); chip->offset = DNV_DMA_CHAN_OFFSET; -- cgit v1.2.3-59-g8ed1b From 216e234d66860c265f0c20d11d768e4596a8d2e6 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Wed, 11 Jan 2017 16:31:37 +0200 Subject: serial: 8250_mid: set PCI master only for DMA capable device There is no need to set PCI bus mastering when device is not doing any DMA. It includes MSI type of interrupts. Currently only UART on Denverton, which is DMA capable, might have MSI enabled. Taking above into account enable bus mastering for Denverton case only. Reviewed-by: Heikki Krogerus Reviewed-by: Jan Kiszka Signed-off-by: Andy Shevchenko Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_mid.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/tty/serial/8250/8250_mid.c b/drivers/tty/serial/8250/8250_mid.c index 85011c9ac0ee..ec957cce8c9a 100644 --- a/drivers/tty/serial/8250/8250_mid.c +++ b/drivers/tty/serial/8250/8250_mid.c @@ -164,6 +164,8 @@ static int dnv_setup(struct mid8250 *mid, struct uart_port *p) unsigned int bar = FL_GET_BASE(mid->board->flags); int ret; + pci_set_master(pdev); + ret = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_ALL_TYPES); if (ret < 0) return ret; @@ -289,8 +291,6 @@ static int mid8250_probe(struct pci_dev *pdev, const struct pci_device_id *id) if (ret) return ret; - pci_set_master(pdev); - mid = devm_kzalloc(&pdev->dev, sizeof(*mid), GFP_KERNEL); if (!mid) return -ENOMEM; -- cgit v1.2.3-59-g8ed1b From 1ea146a7dc9acbdbecadf9adc9eb2a75fa722a3f Mon Sep 17 00:00:00 2001 From: Bhumika Goyal Date: Sun, 15 Jan 2017 16:30:30 +0530 Subject: tty: serial: constify dev_pm_ops structures Declare dev_pm_ops structures as const as they are only stored in the pm field of a device_driver structure. This field is of type const, so dev_pm_ops structures having similar properties can be declared const too. Size details after cross compiling the .o file for blackfin architecture. File size before: text data bss dec hex filename 3572 320 16 3908 f44 tty/serial/bfin_sport_uart.o File size after: text data bss dec hex filename 3664 228 16 3908 f44 tty/serial/bfin_sport_uart.o Signed-off-by: Bhumika Goyal Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/bfin_sport_uart.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/serial/bfin_sport_uart.c b/drivers/tty/serial/bfin_sport_uart.c index 984e1c050096..6b03fb12cd19 100644 --- a/drivers/tty/serial/bfin_sport_uart.c +++ b/drivers/tty/serial/bfin_sport_uart.c @@ -740,7 +740,7 @@ static int sport_uart_resume(struct device *dev) return 0; } -static struct dev_pm_ops bfin_sport_uart_dev_pm_ops = { +static const struct dev_pm_ops bfin_sport_uart_dev_pm_ops = { .suspend = sport_uart_suspend, .resume = sport_uart_resume, }; -- cgit v1.2.3-59-g8ed1b From 7951ffc9eadefded3e7c83a453930e6522c2d1b7 Mon Sep 17 00:00:00 2001 From: Alexander Sverdlin Date: Wed, 18 Jan 2017 10:47:33 +0100 Subject: serial: pl011: Mark console as CON_ANYTIME Exactly as in a80c49db ("serial8250: Mark console as CON_ANYTIME"), to enable printk() during CPU hot-plugging. Actually most of the serial console drivers do not use per-cpu resources and can be marked as CON_ANYTIME. Signed-off-by: Alexander Sverdlin Cc: Russell King Cc: Jiri Slaby Cc: linux-serial@vger.kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/amba-pl011.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c index d4171d71a258..812347245d3f 100644 --- a/drivers/tty/serial/amba-pl011.c +++ b/drivers/tty/serial/amba-pl011.c @@ -2376,7 +2376,7 @@ static struct console amba_console = { .device = uart_console_device, .setup = pl011_console_setup, .match = pl011_console_match, - .flags = CON_PRINTBUFFER, + .flags = CON_PRINTBUFFER | CON_ANYTIME, .index = -1, .data = &amba_reg, }; -- cgit v1.2.3-59-g8ed1b From 28ec9570a22fcf42d5154f6a48dc5b2afdd8d9a3 Mon Sep 17 00:00:00 2001 From: Lokesh Vutla Date: Thu, 19 Jan 2017 15:29:38 +0530 Subject: serial: omap: Add omapserial earlycon Add DT earlycon for omap_serial driver. This boot console is included with CONFIG_SERIAL_EARLYCON=y, CONFIG_OF=y, CONFIG_SERIAL_OMAP=y, and CONFIG_OF_EARLY_FLATTREE=y. This boot console is enabled with the command line option "earlycon" (without "=...") when the DT 'stdout-path' property matches a compatible uart. Signed-off-by: Lokesh Vutla Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/omap-serial.c | 55 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c index a2a529994ba5..3bbc4b5b6245 100644 --- a/drivers/tty/serial/omap-serial.c +++ b/drivers/tty/serial/omap-serial.c @@ -1234,6 +1234,61 @@ out: #ifdef CONFIG_SERIAL_OMAP_CONSOLE +#ifdef CONFIG_SERIAL_EARLYCON +static unsigned int __init omap_serial_early_in(struct uart_port *port, + int offset) +{ + offset <<= port->regshift; + return readw(port->membase + offset); +} + +static void __init omap_serial_early_out(struct uart_port *port, int offset, + int value) +{ + offset <<= port->regshift; + writew(value, port->membase + offset); +} + +static void __init omap_serial_early_putc(struct uart_port *port, int c) +{ + unsigned int status; + + for (;;) { + status = omap_serial_early_in(port, UART_LSR); + if ((status & BOTH_EMPTY) == BOTH_EMPTY) + break; + cpu_relax(); + } + omap_serial_early_out(port, UART_TX, c); +} + +static void __init early_omap_serial_write(struct console *console, + const char *s, unsigned int count) +{ + struct earlycon_device *device = console->data; + struct uart_port *port = &device->port; + + uart_console_write(port, s, count, omap_serial_early_putc); +} + +static int __init early_omap_serial_setup(struct earlycon_device *device, + const char *options) +{ + struct uart_port *port = &device->port; + + if (!(device->port.membase || device->port.iobase)) + return -ENODEV; + + port->regshift = 2; + device->con->write = early_omap_serial_write; + return 0; +} + +OF_EARLYCON_DECLARE(omapserial, "ti,omap2-uart", early_omap_serial_setup); +OF_EARLYCON_DECLARE(omapserial, "ti,omap3-uart", early_omap_serial_setup); +OF_EARLYCON_DECLARE(omapserial, "ti,omap4-uart", early_omap_serial_setup); +#endif /* CONFIG_SERIAL_EARLYCON */ + static struct uart_omap_port *serial_omap_console_ports[OMAP_MAX_HSUART_PORTS]; static struct uart_driver serial_omap_reg; -- cgit v1.2.3-59-g8ed1b From 2cc32b18d1243d65dc312478be08dd5856b44523 Mon Sep 17 00:00:00 2001 From: Arvind Yadav Date: Thu, 19 Jan 2017 13:30:44 +0530 Subject: tty: serial: 8250: 8250_gsc:- Handle return NULL error from ioremap_nocache Here, If ioremap_nocache will fail. It will return NULL. Kernel can run into a NULL-pointer dereference. This error check will avoid NULL pointer dereference. Signed-off-by: Arvind Yadav Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_gsc.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/tty/serial/8250/8250_gsc.c b/drivers/tty/serial/8250/8250_gsc.c index b1e6ae9f1ff9..63306de4390d 100644 --- a/drivers/tty/serial/8250/8250_gsc.c +++ b/drivers/tty/serial/8250/8250_gsc.c @@ -60,6 +60,10 @@ static int __init serial_init_chip(struct parisc_device *dev) 7272727 : 1843200; uart.port.mapbase = address; uart.port.membase = ioremap_nocache(address, 16); + if (!uart.port.membase) { + dev_warn(&dev->dev, "Failed to map memory\n"); + return -ENOMEM; + } uart.port.irq = dev->irq; uart.port.flags = UPF_BOOT_AUTOCONF; uart.port.dev = &dev->dev; -- cgit v1.2.3-59-g8ed1b From 9ed90d20449b01beb71a4e125d291a36c80c4ad4 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Mon, 16 Jan 2017 16:54:28 -0600 Subject: tty: move the non-file related parts of tty_release to new tty_release_struct For in-kernel tty users, we need to be able to create and destroy 'struct tty' that are not associated with a file. The creation side is fine, but tty_release() needs to be split into the file handle portion and the struct tty portion. Introduce a new function, tty_release_struct, to handle just the destroying of a struct tty. Signed-off-by: Rob Herring Reviewed-by: Andy Shevchenko Reviewed-By: Sebastian Reichel Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_io.c | 50 ++++++++++++++++++++++++++++++++------------------ include/linux/tty.h | 1 + 2 files changed, 33 insertions(+), 18 deletions(-) diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index 734a635e7363..4790c0fb5a45 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -1744,6 +1744,37 @@ static int tty_release_checks(struct tty_struct *tty, int idx) return 0; } +/** + * tty_release_struct - release a tty struct + * @tty: tty device + * @idx: index of the tty + * + * Performs the final steps to release and free a tty device. It is + * roughly the reverse of tty_init_dev. + */ +void tty_release_struct(struct tty_struct *tty, int idx) +{ + /* + * Ask the line discipline code to release its structures + */ + tty_ldisc_release(tty); + + /* Wait for pending work before tty destruction commmences */ + tty_flush_works(tty); + + tty_debug_hangup(tty, "freeing structure\n"); + /* + * The release_tty function takes care of the details of clearing + * the slots and preserving the termios structure. The tty_unlock_pair + * should be safe as we keep a kref while the tty is locked (so the + * unlock never unlocks a freed tty). + */ + mutex_lock(&tty_mutex); + release_tty(tty, idx); + mutex_unlock(&tty_mutex); +} +EXPORT_SYMBOL_GPL(tty_release_struct); + /** * tty_release - vfs callback for close * @inode: inode of tty @@ -1898,25 +1929,8 @@ int tty_release(struct inode *inode, struct file *filp) return 0; tty_debug_hangup(tty, "final close\n"); - /* - * Ask the line discipline code to release its structures - */ - tty_ldisc_release(tty); - - /* Wait for pending work before tty destruction commmences */ - tty_flush_works(tty); - - tty_debug_hangup(tty, "freeing structure\n"); - /* - * The release_tty function takes care of the details of clearing - * the slots and preserving the termios structure. The tty_unlock_pair - * should be safe as we keep a kref while the tty is locked (so the - * unlock never unlocks a freed tty). - */ - mutex_lock(&tty_mutex); - release_tty(tty, idx); - mutex_unlock(&tty_mutex); + tty_release_struct(tty, idx); return 0; } diff --git a/include/linux/tty.h b/include/linux/tty.h index 40144f382516..86c7853282b7 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -528,6 +528,7 @@ extern int tty_alloc_file(struct file *file); extern void tty_add_file(struct tty_struct *tty, struct file *file); extern void tty_free_file(struct file *file); extern struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx); +extern void tty_release_struct(struct tty_struct *tty, int idx); extern int tty_release(struct inode *inode, struct file *filp); extern void tty_init_termios(struct tty_struct *tty); extern int tty_standard_install(struct tty_driver *driver, -- cgit v1.2.3-59-g8ed1b From 8c9faa556a37e62799fd22d7409386b1b8ddd4e7 Mon Sep 17 00:00:00 2001 From: Martin Blumenstingl Date: Sun, 15 Jan 2017 23:32:52 +0100 Subject: tty: serial: meson: allow baud-rates higher than 115200 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The vendor driver allows setting baud-rates higher than 115200 baud. There is a check in the vendor driver which prevents using more than 115200 baud during startup, however it does not have such a check in .set_termios. Higher baud-rates are often used by the bluetooth modules embedded into the SDIO wifi chips (Amlogic devices use brcmfmac based wifi chips quite often, 2000000 baud seems to be a common value for the UART baud-rate in Amlogic's "libbt"). I have tested this on a Meson GXL device with uart_A (to which the bluetooth module is connected, where initialization times out with 115200 baud) and uart_AO (which I manually set to 2000000 baud and then connected with my USB UART adapter to that). Signed-off-by: Martin Blumenstingl Acked-by: Kevin Hilman Tested-by: Andreas Färber Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/meson_uart.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c index 6aea0f4a9165..60f16795d16b 100644 --- a/drivers/tty/serial/meson_uart.c +++ b/drivers/tty/serial/meson_uart.c @@ -364,7 +364,7 @@ static void meson_uart_set_termios(struct uart_port *port, writel(val, port->membase + AML_UART_CONTROL); - baud = uart_get_baud_rate(port, termios, old, 9600, 115200); + baud = uart_get_baud_rate(port, termios, old, 9600, 4000000); meson_uart_change_speed(port, baud); port->read_status_mask = AML_UART_TX_FIFO_WERR; -- cgit v1.2.3-59-g8ed1b From ed3f0af8c0b7e161efc5ba7228ca4cbd747c903d Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Mon, 16 Jan 2017 16:54:29 -0600 Subject: tty_port: allow a port to be opened with a tty that has no file handle Let us create tty objects entirely in kernel space. Untested proposal to show why all the ideas around rewriting half the uart stack are not needed. With this a kernel created non file backed tty object could be used to handle data, and set terminal modes. Not all ldiscs can cope with this as N_TTY in particular has to work back to the fs/tty layer. The tty_port code is however otherwise clean of file handles as far as I can tell as is the low level tty port write path used by the ldisc, the configuration low level interfaces and most of the ldiscs. Currently you don't have any exposure to see tty hangups because those are built around the file layer. However a) it's a fixed port so you probably don't care about that b) if you do we can add a callback and c) you almost certainly don't want the userspace tear down/rebuild behaviour anyway. This should however be sufficient if we wanted for example to enumerate all the bluetooth bound fixed ports via ACPI and make them directly available. It doesn't deal with the case of a user opening a port that's also kernel opened and that would need some locking out (so it returned EBUSY if bound to a kernel device of some kind). That needs resolving along with how you "up" or "down" your new bluetooth device, or enumerate it while providing the existing tty API to avoid regressions (and to debug). Signed-off-by: Alan Cox Reviewed-by: Andy Shevchenko Reviewed-By: Sebastian Reichel Signed-off-by: Rob Herring Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_io.c | 2 +- drivers/tty/tty_port.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index 4790c0fb5a45..a1fd3f7d487a 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -855,7 +855,7 @@ static void tty_vhangup_session(struct tty_struct *tty) int tty_hung_up_p(struct file *filp) { - return (filp->f_op == &hung_up_tty_fops); + return (filp && filp->f_op == &hung_up_tty_fops); } EXPORT_SYMBOL(tty_hung_up_p); diff --git a/drivers/tty/tty_port.c b/drivers/tty/tty_port.c index c3f9d93ba227..606d9e5bf28f 100644 --- a/drivers/tty/tty_port.c +++ b/drivers/tty/tty_port.c @@ -335,7 +335,7 @@ EXPORT_SYMBOL(tty_port_lower_dtr_rts); * tty_port_block_til_ready - Waiting logic for tty open * @port: the tty port being opened * @tty: the tty device being bound - * @filp: the file pointer of the opener + * @filp: the file pointer of the opener or NULL * * Implement the core POSIX/SuS tty behaviour when opening a tty device. * Handles: @@ -369,7 +369,7 @@ int tty_port_block_til_ready(struct tty_port *port, tty_port_set_active(port, 1); return 0; } - if (filp->f_flags & O_NONBLOCK) { + if (filp == NULL || (filp->f_flags & O_NONBLOCK)) { /* Indicate we are open */ if (C_BAUD(tty)) tty_port_raise_dtr_rts(port); -- cgit v1.2.3-59-g8ed1b From 3086365db61ec00d206afa2dbaec4b3d771a38f1 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Mon, 16 Jan 2017 16:54:30 -0600 Subject: tty_port: make tty_port_register_device wrap tty_port_register_device_attr tty_register_device is just a wrapper for tty_register_device_attr with NULL passed for drvdata and attr_grp. So similarly make tty_port_register_device a wrapper of tty_port_register_device_attr so that additions don't have to be made in both functions. Signed-off-by: Rob Herring Reviewed-by: Andy Shevchenko Reviewed-By: Sebastian Reichel Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_port.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/tty/tty_port.c b/drivers/tty/tty_port.c index 606d9e5bf28f..1d8804843103 100644 --- a/drivers/tty/tty_port.c +++ b/drivers/tty/tty_port.c @@ -67,8 +67,7 @@ struct device *tty_port_register_device(struct tty_port *port, struct tty_driver *driver, unsigned index, struct device *device) { - tty_port_link_device(port, driver, index); - return tty_register_device(driver, index, device); + return tty_port_register_device_attr(port, driver, index, device, NULL, NULL); } EXPORT_SYMBOL_GPL(tty_port_register_device); -- cgit v1.2.3-59-g8ed1b From c92d781f1a5ea19708b1e1e2b85a3fbd4a738b30 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Mon, 16 Jan 2017 16:54:31 -0600 Subject: tty: constify tty_ldisc_receive_buf buffer pointer This is needed to work with the client operations which uses const ptrs. Really, the flags pointer could be const, too, but this would be a tree wide fix. Signed-off-by: Rob Herring Reviewed-by: Andy Shevchenko Reviewed-By: Sebastian Reichel Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_buffer.c | 2 +- include/linux/tty.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/tty/tty_buffer.c b/drivers/tty/tty_buffer.c index aa80dc94ddc2..f4dc3e296dd5 100644 --- a/drivers/tty/tty_buffer.c +++ b/drivers/tty/tty_buffer.c @@ -422,7 +422,7 @@ EXPORT_SYMBOL_GPL(tty_prepare_flip_string); * * Returns the number of bytes not processed */ -int tty_ldisc_receive_buf(struct tty_ldisc *ld, unsigned char *p, +int tty_ldisc_receive_buf(struct tty_ldisc *ld, const unsigned char *p, char *f, int count) { if (ld->ops->receive_buf2) diff --git a/include/linux/tty.h b/include/linux/tty.h index 86c7853282b7..21c0fabfed60 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -657,7 +657,7 @@ extern int tty_ldisc_setup(struct tty_struct *tty, struct tty_struct *o_tty); extern void tty_ldisc_release(struct tty_struct *tty); extern void tty_ldisc_init(struct tty_struct *tty); extern void tty_ldisc_deinit(struct tty_struct *tty); -extern int tty_ldisc_receive_buf(struct tty_ldisc *ld, unsigned char *p, +extern int tty_ldisc_receive_buf(struct tty_ldisc *ld, const unsigned char *p, char *f, int count); /* n_tty.c */ -- cgit v1.2.3-59-g8ed1b From 75f54acc086940ccef8b6d67ba8537529bda104c Mon Sep 17 00:00:00 2001 From: Vignesh R Date: Fri, 20 Jan 2017 13:46:52 +0530 Subject: serial: 8250_omap: pause DMA only if DMA transfer in progress It is possible that DMA transfer is already complete but, completion handler is yet to be called, when dmaengine_pause() is called in case of error condition(like break/rx timeout). This leads to dmaengine_pause() API to return EINVAL (as descriptor is already NULL) causing rx_dma_broken flag to be set and effectively disabling RX DMA. Fix this by calling dmaengine_pause() only when transfer is in progress. Signed-off-by: Vignesh R Acked-by: Tony Lindgren Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_omap.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/tty/serial/8250/8250_omap.c b/drivers/tty/serial/8250/8250_omap.c index 61ad6c3b20a0..4ad1934ef6ed 100644 --- a/drivers/tty/serial/8250/8250_omap.c +++ b/drivers/tty/serial/8250/8250_omap.c @@ -790,6 +790,7 @@ static void omap_8250_rx_dma_flush(struct uart_8250_port *p) { struct omap8250_priv *priv = p->port.private_data; struct uart_8250_dma *dma = p->dma; + struct dma_tx_state state; unsigned long flags; int ret; @@ -800,10 +801,12 @@ static void omap_8250_rx_dma_flush(struct uart_8250_port *p) return; } - ret = dmaengine_pause(dma->rxchan); - if (WARN_ON_ONCE(ret)) - priv->rx_dma_broken = true; - + ret = dmaengine_tx_status(dma->rxchan, dma->rx_cookie, &state); + if (ret == DMA_IN_PROGRESS) { + ret = dmaengine_pause(dma->rxchan); + if (WARN_ON_ONCE(ret)) + priv->rx_dma_broken = true; + } spin_unlock_irqrestore(&priv->rx_dma_lock, flags); __dma_rx_do_complete(p); -- cgit v1.2.3-59-g8ed1b From b6ffcf21082300519bc4f9c3d24f61207cc9eae4 Mon Sep 17 00:00:00 2001 From: Vignesh R Date: Fri, 20 Jan 2017 13:46:53 +0530 Subject: serial: 8250_omap: Add OMAP_DMA_TX_KICK quirk for AM437x UART uses as EDMA as dma engine on AM437x SoC and therefore, requires OMAP_DMA_TX_KICK quirk just like AM33xx. So, enable OMAP_DMA_TX_KICK quirk for AM437x platform as well. While at that, drop use of of_machine_is_compatible() and instead pass quirks via device data. Signed-off-by: Vignesh R Acked-by: Tony Lindgren Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_omap.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/tty/serial/8250/8250_omap.c b/drivers/tty/serial/8250/8250_omap.c index 4ad1934ef6ed..97766dcd67d4 100644 --- a/drivers/tty/serial/8250/8250_omap.c +++ b/drivers/tty/serial/8250/8250_omap.c @@ -1078,15 +1078,15 @@ static int omap8250_no_handle_irq(struct uart_port *port) } static const u8 am3352_habit = OMAP_DMA_TX_KICK | UART_ERRATA_CLOCK_DISABLE; -static const u8 am4372_habit = UART_ERRATA_CLOCK_DISABLE; +static const u8 dra742_habit = UART_ERRATA_CLOCK_DISABLE; static const struct of_device_id omap8250_dt_ids[] = { { .compatible = "ti,omap2-uart" }, { .compatible = "ti,omap3-uart" }, { .compatible = "ti,omap4-uart" }, { .compatible = "ti,am3352-uart", .data = &am3352_habit, }, - { .compatible = "ti,am4372-uart", .data = &am4372_habit, }, - { .compatible = "ti,dra742-uart", .data = &am4372_habit, }, + { .compatible = "ti,am4372-uart", .data = &am3352_habit, }, + { .compatible = "ti,dra742-uart", .data = &dra742_habit, }, {}, }; MODULE_DEVICE_TABLE(of, omap8250_dt_ids); @@ -1221,9 +1221,6 @@ static int omap8250_probe(struct platform_device *pdev) priv->omap8250_dma.rx_size = RX_TRIGGER; priv->omap8250_dma.rxconf.src_maxburst = RX_TRIGGER; priv->omap8250_dma.txconf.dst_maxburst = TX_TRIGGER; - - if (of_machine_is_compatible("ti,am33xx")) - priv->habit |= OMAP_DMA_TX_KICK; /* * pause is currently not supported atleast on omap-sdma * and edma on most earlier kernels. -- cgit v1.2.3-59-g8ed1b From aa75941ca1de08e876ec21f7eaf390a5de62519f Mon Sep 17 00:00:00 2001 From: Vignesh R Date: Fri, 20 Jan 2017 13:46:54 +0530 Subject: serial: 8250_omap: Remove rx_dma_broken flag 8250 UART DMA support was marked broken by default as it was not possible to pause ongoing RX DMA transfer. Now that both SDMA and EDMA can support pause operation for RX DMA transactions, don't set rx_dma_broken to true by default. With this patch 8250_omap driver will use DMA by default. Signed-off-by: Vignesh R Acked-by: Tony Lindgren Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_omap.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/drivers/tty/serial/8250/8250_omap.c b/drivers/tty/serial/8250/8250_omap.c index 97766dcd67d4..68a6393d9636 100644 --- a/drivers/tty/serial/8250/8250_omap.c +++ b/drivers/tty/serial/8250/8250_omap.c @@ -1221,11 +1221,6 @@ static int omap8250_probe(struct platform_device *pdev) priv->omap8250_dma.rx_size = RX_TRIGGER; priv->omap8250_dma.rxconf.src_maxburst = RX_TRIGGER; priv->omap8250_dma.txconf.dst_maxburst = TX_TRIGGER; - /* - * pause is currently not supported atleast on omap-sdma - * and edma on most earlier kernels. - */ - priv->rx_dma_broken = true; } } #endif -- cgit v1.2.3-59-g8ed1b From 5935a2b3a57c03d7e6fea967ef0b926f82fc995e Mon Sep 17 00:00:00 2001 From: Yasir-Khan Date: Mon, 23 Jan 2017 13:26:08 +0100 Subject: serial: xuartps: Enable uart loopback mode This patch adds xilinx uart loopback support by modifying the cdns_uart_set_mctrl function to handle the switch to loopback mode. After this patch, the loopback mode can be enabled/disabled by setting/clearing the TIOCM_LOOP modem bit via TIOCMBIS/TIOCMBIC ioctls respectively. Signed-off-by: Yasir-Khan Signed-off-by: Michal Simek Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/xilinx_uartps.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c index dd4c02fa4820..ad77d0ed0c46 100644 --- a/drivers/tty/serial/xilinx_uartps.c +++ b/drivers/tty/serial/xilinx_uartps.c @@ -93,6 +93,7 @@ MODULE_PARM_DESC(rx_timeout, "Rx timeout, 1-255"); #define CDNS_UART_MR_CLKSEL 0x00000001 /* Pre-scalar selection */ #define CDNS_UART_MR_CHMODE_L_LOOP 0x00000200 /* Local loop back mode */ #define CDNS_UART_MR_CHMODE_NORM 0x00000000 /* Normal mode */ +#define CDNS_UART_MR_CHMODE_MASK 0x00000300 /* Mask for mode bits */ #define CDNS_UART_MR_STOPMODE_2_BIT 0x00000080 /* 2 stop bits */ #define CDNS_UART_MR_STOPMODE_1_BIT 0x00000000 /* 1 stop bit */ @@ -998,17 +999,25 @@ static unsigned int cdns_uart_get_mctrl(struct uart_port *port) static void cdns_uart_set_mctrl(struct uart_port *port, unsigned int mctrl) { u32 val; + u32 mode_reg; val = readl(port->membase + CDNS_UART_MODEMCR); + mode_reg = readl(port->membase + CDNS_UART_MR); val &= ~(CDNS_UART_MODEMCR_RTS | CDNS_UART_MODEMCR_DTR); + mode_reg &= ~CDNS_UART_MR_CHMODE_MASK; if (mctrl & TIOCM_RTS) val |= CDNS_UART_MODEMCR_RTS; if (mctrl & TIOCM_DTR) val |= CDNS_UART_MODEMCR_DTR; + if (mctrl & TIOCM_LOOP) + mode_reg |= CDNS_UART_MR_CHMODE_L_LOOP; + else + mode_reg |= CDNS_UART_MR_CHMODE_NORM; writel(val, port->membase + CDNS_UART_MODEMCR); + writel(mode_reg, port->membase + CDNS_UART_MR); } #ifdef CONFIG_CONSOLE_POLL -- cgit v1.2.3-59-g8ed1b From f99b63afb943c920bde71bf69880be5578c4c4f6 Mon Sep 17 00:00:00 2001 From: Paul Gortmaker Date: Sat, 21 Jan 2017 22:08:25 -0500 Subject: serial: hp300: mask the warning for people just doing build coverage Currently this warning is triggered for allmodconfig on m68k. It is well intentioned, in that if you are building the driver but not enabling one of the platforms where the hardware exists, you get a warning. The warning dates back to pre-git days, and now we have COMPILE_TEST so we can use that to mask the warning for people who are obviously just doing build coverage on tree wide changes. Cc: Greg Kroah-Hartman Cc: Jiri Slaby Cc: Geert Uytterhoeven Cc: linux-m68k@lists.linux-m68k.org Cc: linux-serial@vger.kernel.org Signed-off-by: Paul Gortmaker Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_hp300.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/serial/8250/8250_hp300.c b/drivers/tty/serial/8250/8250_hp300.c index 38166db2b824..115190b7962a 100644 --- a/drivers/tty/serial/8250/8250_hp300.c +++ b/drivers/tty/serial/8250/8250_hp300.c @@ -19,7 +19,7 @@ #include "8250.h" -#if !defined(CONFIG_HPDCA) && !defined(CONFIG_HPAPCI) +#if !defined(CONFIG_HPDCA) && !defined(CONFIG_HPAPCI) && !defined(CONFIG_COMPILE_TEST) #warning CONFIG_SERIAL_8250 defined but neither CONFIG_HPDCA nor CONFIG_HPAPCI defined, are you sure? #endif -- cgit v1.2.3-59-g8ed1b From 4e0f5cc65098ea32a1e77baae74215b9bd5276b1 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Fri, 20 Jan 2017 12:22:31 -0800 Subject: serial: 8250_omap: Fix probe and remove for PM runtime Otherwise the interconnect related code implementing PM runtime will produce these errors on a failed probe: omap_uart 48066000.serial: omap_device: omap_device_enable() called from invalid state 1 omap_uart 48066000.serial: use pm_runtime_put_sync_suspend() in driver? Note that we now also need to check for priv in omap8250_runtime_suspend() as it has not yet been registered if probe fails. And we need to use pm_runtime_put_sync() to properly idle the device like we already do in omap8250_remove(). Fixes: 61929cf0169d ("tty: serial: Add 8250-core based omap driver") Signed-off-by: Tony Lindgren Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_omap.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/tty/serial/8250/8250_omap.c b/drivers/tty/serial/8250/8250_omap.c index 68a6393d9636..e7e64913a748 100644 --- a/drivers/tty/serial/8250/8250_omap.c +++ b/drivers/tty/serial/8250/8250_omap.c @@ -1235,7 +1235,8 @@ static int omap8250_probe(struct platform_device *pdev) pm_runtime_put_autosuspend(&pdev->dev); return 0; err: - pm_runtime_put(&pdev->dev); + pm_runtime_dont_use_autosuspend(&pdev->dev); + pm_runtime_put_sync(&pdev->dev); pm_runtime_disable(&pdev->dev); return ret; } @@ -1244,6 +1245,7 @@ static int omap8250_remove(struct platform_device *pdev) { struct omap8250_priv *priv = platform_get_drvdata(pdev); + pm_runtime_dont_use_autosuspend(&pdev->dev); pm_runtime_put_sync(&pdev->dev); pm_runtime_disable(&pdev->dev); serial8250_unregister_port(priv->line); @@ -1343,6 +1345,10 @@ static int omap8250_runtime_suspend(struct device *dev) struct omap8250_priv *priv = dev_get_drvdata(dev); struct uart_8250_port *up; + /* In case runtime-pm tries this before we are setup */ + if (!priv) + return 0; + up = serial8250_get_port(priv->line); /* * When using 'no_console_suspend', the console UART must not be -- cgit v1.2.3-59-g8ed1b From 66da39eb91b42ab70dd49ef0b9ac5f4cfa76c9c3 Mon Sep 17 00:00:00 2001 From: Manuel Schölling Date: Fri, 13 Jan 2017 21:07:55 +0100 Subject: console: Move scrollback data into its own struct MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This refactoring is in preparation for persistent scrollback support for VGA console. Signed-off-by: Manuel Schölling Reviewed-by: Andrey Utkin Tested-by: Andrey Utkin Tested-by: Adam Borowski Signed-off-by: Greg Kroah-Hartman --- drivers/video/console/vgacon.c | 91 ++++++++++++++++++++++-------------------- 1 file changed, 47 insertions(+), 44 deletions(-) diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c index c22a56232b7c..48b97648d4af 100644 --- a/drivers/video/console/vgacon.c +++ b/drivers/video/console/vgacon.c @@ -162,31 +162,34 @@ static inline void vga_set_mem_top(struct vc_data *c) #ifdef CONFIG_VGACON_SOFT_SCROLLBACK /* software scrollback */ -static void *vgacon_scrollback; -static int vgacon_scrollback_tail; -static int vgacon_scrollback_size; -static int vgacon_scrollback_rows; -static int vgacon_scrollback_cnt; -static int vgacon_scrollback_cur; -static int vgacon_scrollback_save; -static int vgacon_scrollback_restore; +static struct vgacon_scrollback_info { + void *data; + int tail; + int size; + int rows; + int cnt; + int cur; + int save; + int restore; +} vgacon_scrollback; static void vgacon_scrollback_init(int pitch) { int rows = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024/pitch; - if (vgacon_scrollback) { - vgacon_scrollback_cnt = 0; - vgacon_scrollback_tail = 0; - vgacon_scrollback_cur = 0; - vgacon_scrollback_rows = rows - 1; - vgacon_scrollback_size = rows * pitch; + if (vgacon_scrollback.data) { + vgacon_scrollback.cnt = 0; + vgacon_scrollback.tail = 0; + vgacon_scrollback.cur = 0; + vgacon_scrollback.rows = rows - 1; + vgacon_scrollback.size = rows * pitch; } } static void vgacon_scrollback_startup(void) { - vgacon_scrollback = kcalloc(CONFIG_VGACON_SOFT_SCROLLBACK_SIZE, 1024, GFP_NOWAIT); + vgacon_scrollback.data = kcalloc(CONFIG_VGACON_SOFT_SCROLLBACK_SIZE, + 1024, GFP_NOWAIT); vgacon_scrollback_init(vga_video_num_columns * 2); } @@ -194,38 +197,38 @@ static void vgacon_scrollback_update(struct vc_data *c, int t, int count) { void *p; - if (!vgacon_scrollback_size || c->vc_num != fg_console) + if (!vgacon_scrollback.size || c->vc_num != fg_console) return; p = (void *) (c->vc_origin + t * c->vc_size_row); while (count--) { - scr_memcpyw(vgacon_scrollback + vgacon_scrollback_tail, + scr_memcpyw(vgacon_scrollback.data + vgacon_scrollback.tail, p, c->vc_size_row); - vgacon_scrollback_cnt++; + vgacon_scrollback.cnt++; p += c->vc_size_row; - vgacon_scrollback_tail += c->vc_size_row; + vgacon_scrollback.tail += c->vc_size_row; - if (vgacon_scrollback_tail >= vgacon_scrollback_size) - vgacon_scrollback_tail = 0; + if (vgacon_scrollback.tail >= vgacon_scrollback.size) + vgacon_scrollback.tail = 0; - if (vgacon_scrollback_cnt > vgacon_scrollback_rows) - vgacon_scrollback_cnt = vgacon_scrollback_rows; + if (vgacon_scrollback.cnt > vgacon_scrollback.rows) + vgacon_scrollback.cnt = vgacon_scrollback.rows; - vgacon_scrollback_cur = vgacon_scrollback_cnt; + vgacon_scrollback.cur = vgacon_scrollback.cnt; } } static void vgacon_restore_screen(struct vc_data *c) { - vgacon_scrollback_save = 0; + vgacon_scrollback.save = 0; - if (!vga_is_gfx && !vgacon_scrollback_restore) { + if (!vga_is_gfx && !vgacon_scrollback.restore) { scr_memcpyw((u16 *) c->vc_origin, (u16 *) c->vc_screenbuf, c->vc_screenbuf_size > vga_vram_size ? vga_vram_size : c->vc_screenbuf_size); - vgacon_scrollback_restore = 1; - vgacon_scrollback_cur = vgacon_scrollback_cnt; + vgacon_scrollback.restore = 1; + vgacon_scrollback.cur = vgacon_scrollback.cnt; } } @@ -239,41 +242,41 @@ static void vgacon_scrolldelta(struct vc_data *c, int lines) return; } - if (!vgacon_scrollback) + if (!vgacon_scrollback.data) return; - if (!vgacon_scrollback_save) { + if (!vgacon_scrollback.save) { vgacon_cursor(c, CM_ERASE); vgacon_save_screen(c); - vgacon_scrollback_save = 1; + vgacon_scrollback.save = 1; } - vgacon_scrollback_restore = 0; - start = vgacon_scrollback_cur + lines; + vgacon_scrollback.restore = 0; + start = vgacon_scrollback.cur + lines; end = start + abs(lines); if (start < 0) start = 0; - if (start > vgacon_scrollback_cnt) - start = vgacon_scrollback_cnt; + if (start > vgacon_scrollback.cnt) + start = vgacon_scrollback.cnt; if (end < 0) end = 0; - if (end > vgacon_scrollback_cnt) - end = vgacon_scrollback_cnt; + if (end > vgacon_scrollback.cnt) + end = vgacon_scrollback.cnt; - vgacon_scrollback_cur = start; + vgacon_scrollback.cur = start; count = end - start; - soff = vgacon_scrollback_tail - ((vgacon_scrollback_cnt - end) * + soff = vgacon_scrollback.tail - ((vgacon_scrollback.cnt - end) * c->vc_size_row); soff -= count * c->vc_size_row; if (soff < 0) - soff += vgacon_scrollback_size; + soff += vgacon_scrollback.size; - count = vgacon_scrollback_cnt - start; + count = vgacon_scrollback.cnt - start; if (count > c->vc_rows) count = c->vc_rows; @@ -287,13 +290,13 @@ static void vgacon_scrolldelta(struct vc_data *c, int lines) count *= c->vc_size_row; /* how much memory to end of buffer left? */ - copysize = min(count, vgacon_scrollback_size - soff); - scr_memcpyw(d, vgacon_scrollback + soff, copysize); + copysize = min(count, vgacon_scrollback.size - soff); + scr_memcpyw(d, vgacon_scrollback.data + soff, copysize); d += copysize; count -= copysize; if (count) { - scr_memcpyw(d, vgacon_scrollback, count); + scr_memcpyw(d, vgacon_scrollback.data, count); d += count; } -- cgit v1.2.3-59-g8ed1b From bcd375f7f71f7106c97516bf5395149954ef8810 Mon Sep 17 00:00:00 2001 From: Manuel Schölling Date: Fri, 13 Jan 2017 21:07:56 +0100 Subject: console: Add callback to flush scrollback buffer to consw struct MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This new callback is in preparation for persistent scrollback buffer support for VGA consoles. With a single scrollback buffer for all consoles, we could flush the buffer just by invocating consw->con_switch(). But when each VGA console has its own scrollback buffer, we need a new callback to tell the video console driver which buffer to flush. Signed-off-by: Manuel Schölling Reviewed-by: Andrey Utkin Tested-by: Andrey Utkin Tested-by: Adam Borowski Signed-off-by: Greg Kroah-Hartman --- drivers/tty/vt/vt.c | 9 +++++++++ drivers/video/console/vgacon.c | 24 +++++++++++++++++++++++- include/linux/console.h | 4 ++++ 3 files changed, 36 insertions(+), 1 deletion(-) diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c index 4c10a9df3b91..9d3ce505e7ab 100644 --- a/drivers/tty/vt/vt.c +++ b/drivers/tty/vt/vt.c @@ -625,6 +625,14 @@ static void save_screen(struct vc_data *vc) vc->vc_sw->con_save_screen(vc); } +static void flush_scrollback(struct vc_data *vc) +{ + WARN_CONSOLE_UNLOCKED(); + + if (vc->vc_sw->con_flush_scrollback) + vc->vc_sw->con_flush_scrollback(vc); +} + /* * Redrawing of screen */ @@ -1171,6 +1179,7 @@ static void csi_J(struct vc_data *vc, int vpar) case 3: /* erase scroll-back buffer (and whole display) */ scr_memsetw(vc->vc_screenbuf, vc->vc_video_erase_char, vc->vc_screenbuf_size); + flush_scrollback(vc); set_origin(vc); if (con_is_visible(vc)) update_screen(vc); diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c index 48b97648d4af..9a7c2bbc5326 100644 --- a/drivers/video/console/vgacon.c +++ b/drivers/video/console/vgacon.c @@ -173,6 +173,16 @@ static struct vgacon_scrollback_info { int restore; } vgacon_scrollback; +static void vgacon_scrollback_reset(size_t reset_size) +{ + if (vgacon_scrollback.data && reset_size > 0) + memset(vgacon_scrollback.data, 0, reset_size); + + vgacon_scrollback.cnt = 0; + vgacon_scrollback.tail = 0; + vgacon_scrollback.cur = 0; +} + static void vgacon_scrollback_init(int pitch) { int rows = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024/pitch; @@ -305,6 +315,14 @@ static void vgacon_scrolldelta(struct vc_data *c, int lines) } else vgacon_cursor(c, CM_MOVE); } + +static void vgacon_flush_scrollback(struct vc_data *c) +{ + size_t size = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024; + + if (c->vc_num == fg_console) + vgacon_scrollback_reset(size); +} #else #define vgacon_scrollback_startup(...) do { } while (0) #define vgacon_scrollback_init(...) do { } while (0) @@ -322,6 +340,10 @@ static void vgacon_scrolldelta(struct vc_data *c, int lines) vga_vram_size); vga_set_mem_top(c); } + +static void vgacon_flush_scrollback(struct vc_data *c) +{ +} #endif /* CONFIG_VGACON_SOFT_SCROLLBACK */ static const char *vgacon_startup(void) @@ -1329,7 +1351,6 @@ static bool vgacon_scroll(struct vc_data *c, unsigned int t, unsigned int b, return true; } - /* * The console `switch' structure for the VGA based console */ @@ -1362,6 +1383,7 @@ const struct consw vga_con = { .con_save_screen = vgacon_save_screen, .con_build_attr = vgacon_build_attr, .con_invert_region = vgacon_invert_region, + .con_flush_scrollback = vgacon_flush_scrollback, }; EXPORT_SYMBOL(vga_con); diff --git a/include/linux/console.h b/include/linux/console.h index 9c26c6685587..5949d1855589 100644 --- a/include/linux/console.h +++ b/include/linux/console.h @@ -72,6 +72,10 @@ struct consw { void (*con_invert_region)(struct vc_data *, u16 *, int); u16 *(*con_screen_pos)(struct vc_data *, int); unsigned long (*con_getxy)(struct vc_data *, unsigned long, int *, int *); + /* + * Flush the video console driver's scrollback buffer + */ + void (*con_flush_scrollback)(struct vc_data *); /* * Prepare the console for the debugger. This includes, but is not * limited to, unblanking the console, loading an appropriate -- cgit v1.2.3-59-g8ed1b From aabd31c421ddc730edf6d89c4ed3885e4fca5e30 Mon Sep 17 00:00:00 2001 From: Manuel Schölling Date: Fri, 13 Jan 2017 21:07:57 +0100 Subject: console: Add persistent scrollback buffers for all VGA consoles MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a scrollback buffers for each VGA console. The benefit is that the scrollback history is not flushed when switching between consoles but is persistent. The buffers are allocated on demand when a new console is opened. This breaks tools like clear_console that rely on flushing the scrollback history by switching back and forth between consoles which is why this feature is disabled by default. Use the escape sequence \e[3J instead for flushing the buffer. Signed-off-by: Manuel Schölling Reviewed-by: Andrey Utkin Tested-by: Andrey Utkin Tested-by: Adam Borowski Signed-off-by: Greg Kroah-Hartman --- drivers/video/console/Kconfig | 25 +++++++- drivers/video/console/vgacon.c | 142 ++++++++++++++++++++++++++--------------- 2 files changed, 111 insertions(+), 56 deletions(-) diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig index c3f1fb9ee820..f500e58f7636 100644 --- a/drivers/video/console/Kconfig +++ b/drivers/video/console/Kconfig @@ -43,9 +43,28 @@ config VGACON_SOFT_SCROLLBACK_SIZE range 1 1024 default "64" help - Enter the amount of System RAM to allocate for the scrollback - buffer. Each 64KB will give you approximately 16 80x25 - screenfuls of scrollback buffer + Enter the amount of System RAM to allocate for scrollback + buffers of VGA consoles. Each 64KB will give you approximately + 16 80x25 screenfuls of scrollback buffer. + +config VGACON_SOFT_SCROLLBACK_PERSISTENT + bool "Persistent Scrollback History for each console" + depends on VGACON_SOFT_SCROLLBACK + default n + help + Say Y here if the scrollback history should persist when switching + between consoles. Otherwise, the scrollback history will be flushed + each time the console is switched. + + This feature might break your tool of choice to flush the scrollback + buffer, e.g. clear(1) will work fine but Debian's clear_console(1) + will be broken, which might cause security issues. + You can use the escape sequence \e[3J instead if this feature is + activated. + + Note that a buffer of VGACON_SOFT_SCROLLBACK_SIZE is taken for each + created tty device. + So if you use a RAM-constrained system, say N here. config MDA_CONSOLE depends on !M68K && !PARISC && ISA diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c index 9a7c2bbc5326..ca23d222e029 100644 --- a/drivers/video/console/vgacon.c +++ b/drivers/video/console/vgacon.c @@ -162,7 +162,7 @@ static inline void vga_set_mem_top(struct vc_data *c) #ifdef CONFIG_VGACON_SOFT_SCROLLBACK /* software scrollback */ -static struct vgacon_scrollback_info { +struct vgacon_scrollback_info { void *data; int tail; int size; @@ -171,74 +171,110 @@ static struct vgacon_scrollback_info { int cur; int save; int restore; -} vgacon_scrollback; +}; + +static struct vgacon_scrollback_info *vgacon_scrollback_cur; +#ifdef CONFIG_VGACON_SOFT_SCROLLBACK_PERSISTENT +static struct vgacon_scrollback_info vgacon_scrollbacks[MAX_NR_CONSOLES]; +#else +static struct vgacon_scrollback_info vgacon_scrollbacks[1]; +#endif -static void vgacon_scrollback_reset(size_t reset_size) +static void vgacon_scrollback_reset(int vc_num, size_t reset_size) { - if (vgacon_scrollback.data && reset_size > 0) - memset(vgacon_scrollback.data, 0, reset_size); + struct vgacon_scrollback_info *scrollback = &vgacon_scrollbacks[vc_num]; + + if (scrollback->data && reset_size > 0) + memset(scrollback->data, 0, reset_size); - vgacon_scrollback.cnt = 0; - vgacon_scrollback.tail = 0; - vgacon_scrollback.cur = 0; + scrollback->cnt = 0; + scrollback->tail = 0; + scrollback->cur = 0; } -static void vgacon_scrollback_init(int pitch) +static void vgacon_scrollback_init(int vc_num) { - int rows = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024/pitch; - - if (vgacon_scrollback.data) { - vgacon_scrollback.cnt = 0; - vgacon_scrollback.tail = 0; - vgacon_scrollback.cur = 0; - vgacon_scrollback.rows = rows - 1; - vgacon_scrollback.size = rows * pitch; + int pitch = vga_video_num_columns * 2; + size_t size = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024; + int rows = size / pitch; + void *data; + + data = kmalloc_array(CONFIG_VGACON_SOFT_SCROLLBACK_SIZE, 1024, + GFP_NOWAIT); + + vgacon_scrollbacks[vc_num].data = data; + vgacon_scrollback_cur = &vgacon_scrollbacks[vc_num]; + + vgacon_scrollback_cur->rows = rows - 1; + vgacon_scrollback_cur->size = rows * pitch; + + vgacon_scrollback_reset(vc_num, size); +} + +static void vgacon_scrollback_switch(int vc_num) +{ +#ifndef CONFIG_VGACON_SOFT_SCROLLBACK_PERSISTENT + vc_num = 0; +#endif + + if (!vgacon_scrollbacks[vc_num].data) { + vgacon_scrollback_init(vc_num); + } else { +#ifdef CONFIG_VGACON_SOFT_SCROLLBACK_PERSISTENT + vgacon_scrollback_cur = &vgacon_scrollbacks[vc_num]; +#else + size_t size = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024; + + vgacon_scrollback_reset(vc_num, size); +#endif } } static void vgacon_scrollback_startup(void) { - vgacon_scrollback.data = kcalloc(CONFIG_VGACON_SOFT_SCROLLBACK_SIZE, - 1024, GFP_NOWAIT); - vgacon_scrollback_init(vga_video_num_columns * 2); + vgacon_scrollback_cur = &vgacon_scrollbacks[0]; + vgacon_scrollback_init(0); } static void vgacon_scrollback_update(struct vc_data *c, int t, int count) { void *p; - if (!vgacon_scrollback.size || c->vc_num != fg_console) + if (!vgacon_scrollback_cur->data || !vgacon_scrollback_cur->size || + c->vc_num != fg_console) return; p = (void *) (c->vc_origin + t * c->vc_size_row); while (count--) { - scr_memcpyw(vgacon_scrollback.data + vgacon_scrollback.tail, + scr_memcpyw(vgacon_scrollback_cur->data + + vgacon_scrollback_cur->tail, p, c->vc_size_row); - vgacon_scrollback.cnt++; + + vgacon_scrollback_cur->cnt++; p += c->vc_size_row; - vgacon_scrollback.tail += c->vc_size_row; + vgacon_scrollback_cur->tail += c->vc_size_row; - if (vgacon_scrollback.tail >= vgacon_scrollback.size) - vgacon_scrollback.tail = 0; + if (vgacon_scrollback_cur->tail >= vgacon_scrollback_cur->size) + vgacon_scrollback_cur->tail = 0; - if (vgacon_scrollback.cnt > vgacon_scrollback.rows) - vgacon_scrollback.cnt = vgacon_scrollback.rows; + if (vgacon_scrollback_cur->cnt > vgacon_scrollback_cur->rows) + vgacon_scrollback_cur->cnt = vgacon_scrollback_cur->rows; - vgacon_scrollback.cur = vgacon_scrollback.cnt; + vgacon_scrollback_cur->cur = vgacon_scrollback_cur->cnt; } } static void vgacon_restore_screen(struct vc_data *c) { - vgacon_scrollback.save = 0; + vgacon_scrollback_cur->save = 0; - if (!vga_is_gfx && !vgacon_scrollback.restore) { + if (!vga_is_gfx && !vgacon_scrollback_cur->restore) { scr_memcpyw((u16 *) c->vc_origin, (u16 *) c->vc_screenbuf, c->vc_screenbuf_size > vga_vram_size ? vga_vram_size : c->vc_screenbuf_size); - vgacon_scrollback.restore = 1; - vgacon_scrollback.cur = vgacon_scrollback.cnt; + vgacon_scrollback_cur->restore = 1; + vgacon_scrollback_cur->cur = vgacon_scrollback_cur->cnt; } } @@ -252,41 +288,41 @@ static void vgacon_scrolldelta(struct vc_data *c, int lines) return; } - if (!vgacon_scrollback.data) + if (!vgacon_scrollback_cur->data) return; - if (!vgacon_scrollback.save) { + if (!vgacon_scrollback_cur->save) { vgacon_cursor(c, CM_ERASE); vgacon_save_screen(c); - vgacon_scrollback.save = 1; + vgacon_scrollback_cur->save = 1; } - vgacon_scrollback.restore = 0; - start = vgacon_scrollback.cur + lines; + vgacon_scrollback_cur->restore = 0; + start = vgacon_scrollback_cur->cur + lines; end = start + abs(lines); if (start < 0) start = 0; - if (start > vgacon_scrollback.cnt) - start = vgacon_scrollback.cnt; + if (start > vgacon_scrollback_cur->cnt) + start = vgacon_scrollback_cur->cnt; if (end < 0) end = 0; - if (end > vgacon_scrollback.cnt) - end = vgacon_scrollback.cnt; + if (end > vgacon_scrollback_cur->cnt) + end = vgacon_scrollback_cur->cnt; - vgacon_scrollback.cur = start; + vgacon_scrollback_cur->cur = start; count = end - start; - soff = vgacon_scrollback.tail - ((vgacon_scrollback.cnt - end) * - c->vc_size_row); + soff = vgacon_scrollback_cur->tail - + ((vgacon_scrollback_cur->cnt - end) * c->vc_size_row); soff -= count * c->vc_size_row; if (soff < 0) - soff += vgacon_scrollback.size; + soff += vgacon_scrollback_cur->size; - count = vgacon_scrollback.cnt - start; + count = vgacon_scrollback_cur->cnt - start; if (count > c->vc_rows) count = c->vc_rows; @@ -300,13 +336,13 @@ static void vgacon_scrolldelta(struct vc_data *c, int lines) count *= c->vc_size_row; /* how much memory to end of buffer left? */ - copysize = min(count, vgacon_scrollback.size - soff); - scr_memcpyw(d, vgacon_scrollback.data + soff, copysize); + copysize = min(count, vgacon_scrollback_cur->size - soff); + scr_memcpyw(d, vgacon_scrollback_cur->data + soff, copysize); d += copysize; count -= copysize; if (count) { - scr_memcpyw(d, vgacon_scrollback.data, count); + scr_memcpyw(d, vgacon_scrollback_cur->data, count); d += count; } @@ -320,13 +356,13 @@ static void vgacon_flush_scrollback(struct vc_data *c) { size_t size = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024; - if (c->vc_num == fg_console) - vgacon_scrollback_reset(size); + vgacon_scrollback_reset(c->vc_num, size); } #else #define vgacon_scrollback_startup(...) do { } while (0) #define vgacon_scrollback_init(...) do { } while (0) #define vgacon_scrollback_update(...) do { } while (0) +#define vgacon_scrollback_switch(...) do { } while (0) static void vgacon_restore_screen(struct vc_data *c) { @@ -805,7 +841,7 @@ static int vgacon_switch(struct vc_data *c) vgacon_doresize(c, c->vc_cols, c->vc_rows); } - vgacon_scrollback_init(c->vc_size_row); + vgacon_scrollback_switch(c->vc_num); return 0; /* Redrawing not needed */ } -- cgit v1.2.3-59-g8ed1b From 1a336c934623b011c289a298aff3b7fdefb3f876 Mon Sep 17 00:00:00 2001 From: Manuel Schölling Date: Fri, 13 Jan 2017 21:07:58 +0100 Subject: console: Make persistent scrollback a boot parameter MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The impact of the persistent scrollback feature on the code size is rather small, so the config option is removed. The feature stays disabled by default and can be enabled by using the boot command line parameter 'vgacon.scrollback_persistent=1' or by setting VGACON_SOFT_SCROLLBACK_PERSISTENT_ENABLE_BY_DEFAULT=y. Signed-off-by: Manuel Schölling Suggested-by: Bartlomiej Zolnierkiewicz Signed-off-by: Greg Kroah-Hartman --- drivers/video/console/Kconfig | 12 +++++++----- drivers/video/console/vgacon.c | 25 ++++++++++++------------- 2 files changed, 19 insertions(+), 18 deletions(-) diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig index f500e58f7636..5b71bd905a60 100644 --- a/drivers/video/console/Kconfig +++ b/drivers/video/console/Kconfig @@ -47,14 +47,16 @@ config VGACON_SOFT_SCROLLBACK_SIZE buffers of VGA consoles. Each 64KB will give you approximately 16 80x25 screenfuls of scrollback buffer. -config VGACON_SOFT_SCROLLBACK_PERSISTENT - bool "Persistent Scrollback History for each console" +config VGACON_SOFT_SCROLLBACK_PERSISTENT_ENABLE_BY_DEFAULT + bool "Persistent Scrollback History for each console by default" depends on VGACON_SOFT_SCROLLBACK default n help - Say Y here if the scrollback history should persist when switching - between consoles. Otherwise, the scrollback history will be flushed - each time the console is switched. + Say Y here if the scrollback history should persist by default when + switching between consoles. Otherwise, the scrollback history will be + flushed each time the console is switched. This feature can also be + enabled using the boot command line parameter + 'vgacon.scrollback_persistent=1'. This feature might break your tool of choice to flush the scrollback buffer, e.g. clear(1) will work fine but Debian's clear_console(1) diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c index ca23d222e029..dc06cb6a15dc 100644 --- a/drivers/video/console/vgacon.c +++ b/drivers/video/console/vgacon.c @@ -174,11 +174,11 @@ struct vgacon_scrollback_info { }; static struct vgacon_scrollback_info *vgacon_scrollback_cur; -#ifdef CONFIG_VGACON_SOFT_SCROLLBACK_PERSISTENT static struct vgacon_scrollback_info vgacon_scrollbacks[MAX_NR_CONSOLES]; -#else -static struct vgacon_scrollback_info vgacon_scrollbacks[1]; -#endif +static bool scrollback_persistent = \ + IS_ENABLED(CONFIG_VGACON_SOFT_SCROLLBACK_PERSISTENT_ENABLE_BY_DEFAULT); +module_param_named(scrollback_persistent, scrollback_persistent, bool, 0000); +MODULE_PARM_DESC(scrollback_persistent, "Enable persistent scrollback for all vga consoles"); static void vgacon_scrollback_reset(int vc_num, size_t reset_size) { @@ -213,20 +213,19 @@ static void vgacon_scrollback_init(int vc_num) static void vgacon_scrollback_switch(int vc_num) { -#ifndef CONFIG_VGACON_SOFT_SCROLLBACK_PERSISTENT - vc_num = 0; -#endif + if (!scrollback_persistent) + vc_num = 0; if (!vgacon_scrollbacks[vc_num].data) { vgacon_scrollback_init(vc_num); } else { -#ifdef CONFIG_VGACON_SOFT_SCROLLBACK_PERSISTENT - vgacon_scrollback_cur = &vgacon_scrollbacks[vc_num]; -#else - size_t size = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024; + if (scrollback_persistent) { + vgacon_scrollback_cur = &vgacon_scrollbacks[vc_num]; + } else { + size_t size = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024; - vgacon_scrollback_reset(vc_num, size); -#endif + vgacon_scrollback_reset(vc_num, size); + } } } -- cgit v1.2.3-59-g8ed1b From 2331e06865047a0c4ff3fb838716210e7a296a4d Mon Sep 17 00:00:00 2001 From: Bhumika Goyal Date: Wed, 25 Jan 2017 23:18:52 +0530 Subject: tty: serial: constify uart_ops structures Declare uart_ops structures as const as they are only stored in the ops field of an uart_port structure. This field is of type const, so uart_ops structures having this property can be made const too. File size details before and after patching. First line of every .o file shows the file size before patching and second line shows the size after patching. text data bss dec hex filename 2977 456 64 3497 da9 drivers/tty/serial/amba-pl010.o 3169 272 64 3505 db1 drivers/tty/serial/amba-pl010.o 3109 456 0 3565 ded drivers/tty/serial/efm32-uart.o 3301 272 0 3573 df5 drivers/tty/serial/efm32-uart.o 10668 753 1 11422 2c9e drivers/tty/serial/icom.o 10860 561 1 11422 2c9e drivers/tty/serial/icom.o 23904 408 8 24320 5f00 drivers/tty/serial/ioc3_serial.o 24088 224 8 24320 5f00 drivers/tty/serial/ioc3_serial.o 10516 560 4 11080 2b48 drivers/tty/serial/ioc4_serial.o 10709 368 4 11081 2b49 drivers/tty/serial/ioc4_serial.o 7853 648 1216 9717 25f5 drivers/tty/serial/mpsc.o 8037 456 1216 9709 25ed drivers/tty/serial/mpsc.o 10248 456 0 10704 29d0 drivers/tty/serial/omap-serial.o 10440 272 0 10712 29d8 drivers/tty/serial/omap-serial.o 8122 532 1984 10638 298e drivers/tty/serial/pmac_zilog.o 8306 340 1984 10630 2986 drivers/tty/serial/pmac_zilog.o 3808 456 0 4264 10a8 drivers/tty/serial/pxa.o 4000 264 0 4264 10a8 drivers/tty/serial/pxa.o 21781 3864 0 25645 642d drivers/tty/serial/serial-tegra.o 22037 3608 0 25645 642d drivers/tty/serial/serial-tegra.o 2481 456 96 3033 bd9 drivers/tty/serial/sprd_serial.o 2673 272 96 3041 be1 drivers/tty/serial/sprd_serial.o 5534 300 512 6346 18ca drivers/tty/serial/vr41xx_siu.o 5630 204 512 6346 18ca drivers/tty/serial/vr41xx_siu.o 6730 1576 128 8434 20f2 drivers/tty/serial/vt8500_serial.o 6986 1320 128 8434 20f2 drivers/tty/serial/vt8500_serial.o Cross compiled for mips architecture. 3005 488 0 3493 da5 drivers/tty/serial/pnx8xxx_uart.o 3189 304 0 3493 da5 drivers/tty/serial/pnx8xxx_uart.o 4272 196 1056 5524 1594 drivers/tty/serial/dz.o 4368 100 1056 5524 1594 drivers/tty/serial/dz.o 6551 144 16 6711 1a37 drivers/tty/serial/ip22zilog.o 6647 48 16 6711 1a37 drivers/tty/serial/ip22zilog.o 9612 428 1520 11560 2d28 drivers/tty/serial/serial_txx9.o 9708 332 1520 11560 2d28 drivers/tty/serial/serial_txx9.o 4156 296 16 4468 1174 drivers/tty/serial/ar933x_uart.o 4252 200 16 4468 1174 drivers/tty/serial/ar933x_uart.o Cross compiled for arm archiecture. 11716 1780 44 13540 34e4 drivers/tty/serial/sirfsoc_uart.o 11808 1688 44 13540 34e4 drivers/tty/serial/sirfsoc_uart.o 13352 596 56 14004 36b4 drivers/tty/serial/amba-pl011.o 13444 504 56 14004 36b4 drivers/tty/serial/amba-pl011.o Cross compiled for sparc architecture. 4664 528 32 5224 1468 drivers/tty/serial/sunhv.o 4848 344 32 5224 1468 drivers/tty/serial/sunhv.o 8080 332 28 8440 20f8 drivers/tty/serial/sunzilog.o 8184 228 28 8440 20f8 drivers/tty/serial/sunzilog.o Cross compiled for ia64 architecture. 10226 549 472 11247 2bef drivers/tty/serial/sn_console.o 10414 365 472 11251 2bf3 drivers/tty/serial/sn_console.o The files drivers/tty/serial/zs.o, drivers/tty/serial/lpc32xx_hs.o and drivers/tty/serial/lantiq.o did not compile. Signed-off-by: Bhumika Goyal Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/amba-pl010.c | 2 +- drivers/tty/serial/amba-pl011.c | 2 +- drivers/tty/serial/ar933x_uart.c | 2 +- drivers/tty/serial/dz.c | 2 +- drivers/tty/serial/efm32-uart.c | 2 +- drivers/tty/serial/icom.c | 2 +- drivers/tty/serial/ioc3_serial.c | 2 +- drivers/tty/serial/ioc4_serial.c | 2 +- drivers/tty/serial/ip22zilog.c | 2 +- drivers/tty/serial/lantiq.c | 2 +- drivers/tty/serial/lpc32xx_hs.c | 2 +- drivers/tty/serial/mpsc.c | 2 +- drivers/tty/serial/omap-serial.c | 2 +- drivers/tty/serial/pmac_zilog.c | 2 +- drivers/tty/serial/pnx8xxx_uart.c | 2 +- drivers/tty/serial/pxa.c | 2 +- drivers/tty/serial/serial-tegra.c | 2 +- drivers/tty/serial/serial_txx9.c | 2 +- drivers/tty/serial/sirfsoc_uart.c | 2 +- drivers/tty/serial/sn_console.c | 2 +- drivers/tty/serial/sprd_serial.c | 2 +- drivers/tty/serial/sunhv.c | 2 +- drivers/tty/serial/sunzilog.c | 2 +- drivers/tty/serial/vr41xx_siu.c | 2 +- drivers/tty/serial/vt8500_serial.c | 2 +- drivers/tty/serial/zs.c | 2 +- 26 files changed, 26 insertions(+), 26 deletions(-) diff --git a/drivers/tty/serial/amba-pl010.c b/drivers/tty/serial/amba-pl010.c index 5d41d5b92619..f2f251075109 100644 --- a/drivers/tty/serial/amba-pl010.c +++ b/drivers/tty/serial/amba-pl010.c @@ -554,7 +554,7 @@ static int pl010_verify_port(struct uart_port *port, struct serial_struct *ser) return ret; } -static struct uart_ops amba_pl010_pops = { +static const struct uart_ops amba_pl010_pops = { .tx_empty = pl010_tx_empty, .set_mctrl = pl010_set_mctrl, .get_mctrl = pl010_get_mctrl, diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c index 812347245d3f..963c2e5feedd 100644 --- a/drivers/tty/serial/amba-pl011.c +++ b/drivers/tty/serial/amba-pl011.c @@ -2114,7 +2114,7 @@ static int pl011_verify_port(struct uart_port *port, struct serial_struct *ser) return ret; } -static struct uart_ops amba_pl011_pops = { +static const struct uart_ops amba_pl011_pops = { .tx_empty = pl011_tx_empty, .set_mctrl = pl011_set_mctrl, .get_mctrl = pl011_get_mctrl, diff --git a/drivers/tty/serial/ar933x_uart.c b/drivers/tty/serial/ar933x_uart.c index 73137f4aac20..decc7f3c1ab2 100644 --- a/drivers/tty/serial/ar933x_uart.c +++ b/drivers/tty/serial/ar933x_uart.c @@ -493,7 +493,7 @@ static int ar933x_uart_verify_port(struct uart_port *port, return 0; } -static struct uart_ops ar933x_uart_ops = { +static const struct uart_ops ar933x_uart_ops = { .tx_empty = ar933x_uart_tx_empty, .set_mctrl = ar933x_uart_set_mctrl, .get_mctrl = ar933x_uart_get_mctrl, diff --git a/drivers/tty/serial/dz.c b/drivers/tty/serial/dz.c index c121f16a973f..ff465ff43577 100644 --- a/drivers/tty/serial/dz.c +++ b/drivers/tty/serial/dz.c @@ -739,7 +739,7 @@ static int dz_verify_port(struct uart_port *uport, struct serial_struct *ser) return ret; } -static struct uart_ops dz_ops = { +static const struct uart_ops dz_ops = { .tx_empty = dz_tx_empty, .get_mctrl = dz_get_mctrl, .set_mctrl = dz_set_mctrl, diff --git a/drivers/tty/serial/efm32-uart.c b/drivers/tty/serial/efm32-uart.c index 195acc868763..ebd8569f9ad5 100644 --- a/drivers/tty/serial/efm32-uart.c +++ b/drivers/tty/serial/efm32-uart.c @@ -487,7 +487,7 @@ static int efm32_uart_verify_port(struct uart_port *port, return ret; } -static struct uart_ops efm32_uart_pops = { +static const struct uart_ops efm32_uart_pops = { .tx_empty = efm32_uart_tx_empty, .set_mctrl = efm32_uart_set_mctrl, .get_mctrl = efm32_uart_get_mctrl, diff --git a/drivers/tty/serial/icom.c b/drivers/tty/serial/icom.c index d83783cfbade..fe92d74f4ea5 100644 --- a/drivers/tty/serial/icom.c +++ b/drivers/tty/serial/icom.c @@ -1286,7 +1286,7 @@ static void icom_config_port(struct uart_port *port, int flags) port->type = PORT_ICOM; } -static struct uart_ops icom_ops = { +static const struct uart_ops icom_ops = { .tx_empty = icom_tx_empty, .set_mctrl = icom_set_mctrl, .get_mctrl = icom_get_mctrl, diff --git a/drivers/tty/serial/ioc3_serial.c b/drivers/tty/serial/ioc3_serial.c index 27b5fefac171..2a61dd6b4009 100644 --- a/drivers/tty/serial/ioc3_serial.c +++ b/drivers/tty/serial/ioc3_serial.c @@ -1873,7 +1873,7 @@ static int ic3_request_port(struct uart_port *port) } /* Associate the uart functions above - given to serial core */ -static struct uart_ops ioc3_ops = { +static const struct uart_ops ioc3_ops = { .tx_empty = ic3_tx_empty, .set_mctrl = ic3_set_mctrl, .get_mctrl = ic3_get_mctrl, diff --git a/drivers/tty/serial/ioc4_serial.c b/drivers/tty/serial/ioc4_serial.c index 3be051abb2a2..6ad26f802b51 100644 --- a/drivers/tty/serial/ioc4_serial.c +++ b/drivers/tty/serial/ioc4_serial.c @@ -2596,7 +2596,7 @@ static int ic4_request_port(struct uart_port *port) /* Associate the uart functions above - given to serial core */ -static struct uart_ops ioc4_ops = { +static const struct uart_ops ioc4_ops = { .tx_empty = ic4_tx_empty, .set_mctrl = ic4_set_mctrl, .get_mctrl = ic4_get_mctrl, diff --git a/drivers/tty/serial/ip22zilog.c b/drivers/tty/serial/ip22zilog.c index 991e6dce916e..7ddddb4c3844 100644 --- a/drivers/tty/serial/ip22zilog.c +++ b/drivers/tty/serial/ip22zilog.c @@ -930,7 +930,7 @@ static int ip22zilog_verify_port(struct uart_port *port, struct serial_struct *s return -EINVAL; } -static struct uart_ops ip22zilog_pops = { +static const struct uart_ops ip22zilog_pops = { .tx_empty = ip22zilog_tx_empty, .set_mctrl = ip22zilog_set_mctrl, .get_mctrl = ip22zilog_get_mctrl, diff --git a/drivers/tty/serial/lantiq.c b/drivers/tty/serial/lantiq.c index 5961bb47b8e5..22df94f107e5 100644 --- a/drivers/tty/serial/lantiq.c +++ b/drivers/tty/serial/lantiq.c @@ -557,7 +557,7 @@ lqasc_verify_port(struct uart_port *port, return ret; } -static struct uart_ops lqasc_pops = { +static const struct uart_ops lqasc_pops = { .tx_empty = lqasc_tx_empty, .set_mctrl = lqasc_set_mctrl, .get_mctrl = lqasc_get_mctrl, diff --git a/drivers/tty/serial/lpc32xx_hs.c b/drivers/tty/serial/lpc32xx_hs.c index 7eb04ae71cc8..cea57ff32c33 100644 --- a/drivers/tty/serial/lpc32xx_hs.c +++ b/drivers/tty/serial/lpc32xx_hs.c @@ -645,7 +645,7 @@ static int serial_lpc32xx_verify_port(struct uart_port *port, return ret; } -static struct uart_ops serial_lpc32xx_pops = { +static const struct uart_ops serial_lpc32xx_pops = { .tx_empty = serial_lpc32xx_tx_empty, .set_mctrl = serial_lpc32xx_set_mctrl, .get_mctrl = serial_lpc32xx_get_mctrl, diff --git a/drivers/tty/serial/mpsc.c b/drivers/tty/serial/mpsc.c index 4a3021bcc859..1a60a2063e75 100644 --- a/drivers/tty/serial/mpsc.c +++ b/drivers/tty/serial/mpsc.c @@ -1670,7 +1670,7 @@ static void mpsc_put_poll_char(struct uart_port *port, } #endif -static struct uart_ops mpsc_pops = { +static const struct uart_ops mpsc_pops = { .tx_empty = mpsc_tx_empty, .set_mctrl = mpsc_set_mctrl, .get_mctrl = mpsc_get_mctrl, diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c index 3bbc4b5b6245..6c6f82ad8d5c 100644 --- a/drivers/tty/serial/omap-serial.c +++ b/drivers/tty/serial/omap-serial.c @@ -1450,7 +1450,7 @@ serial_omap_config_rs485(struct uart_port *port, struct serial_rs485 *rs485) return 0; } -static struct uart_ops serial_omap_pops = { +static const struct uart_ops serial_omap_pops = { .tx_empty = serial_omap_tx_empty, .set_mctrl = serial_omap_set_mctrl, .get_mctrl = serial_omap_get_mctrl, diff --git a/drivers/tty/serial/pmac_zilog.c b/drivers/tty/serial/pmac_zilog.c index b24b0556f5a8..0da52947e59e 100644 --- a/drivers/tty/serial/pmac_zilog.c +++ b/drivers/tty/serial/pmac_zilog.c @@ -1379,7 +1379,7 @@ static void pmz_poll_put_char(struct uart_port *port, unsigned char c) #endif /* CONFIG_CONSOLE_POLL */ -static struct uart_ops pmz_pops = { +static const struct uart_ops pmz_pops = { .tx_empty = pmz_tx_empty, .set_mctrl = pmz_set_mctrl, .get_mctrl = pmz_get_mctrl, diff --git a/drivers/tty/serial/pnx8xxx_uart.c b/drivers/tty/serial/pnx8xxx_uart.c index 7a3bb9cf1f2e..dab2668d3879 100644 --- a/drivers/tty/serial/pnx8xxx_uart.c +++ b/drivers/tty/serial/pnx8xxx_uart.c @@ -631,7 +631,7 @@ pnx8xxx_verify_port(struct uart_port *port, struct serial_struct *ser) return ret; } -static struct uart_ops pnx8xxx_pops = { +static const struct uart_ops pnx8xxx_pops = { .tx_empty = pnx8xxx_tx_empty, .set_mctrl = pnx8xxx_set_mctrl, .get_mctrl = pnx8xxx_get_mctrl, diff --git a/drivers/tty/serial/pxa.c b/drivers/tty/serial/pxa.c index 75952811c0da..905631df1f8b 100644 --- a/drivers/tty/serial/pxa.c +++ b/drivers/tty/serial/pxa.c @@ -762,7 +762,7 @@ static struct console serial_pxa_console = { #define PXA_CONSOLE NULL #endif -static struct uart_ops serial_pxa_pops = { +static const struct uart_ops serial_pxa_pops = { .tx_empty = serial_pxa_tx_empty, .set_mctrl = serial_pxa_set_mctrl, .get_mctrl = serial_pxa_get_mctrl, diff --git a/drivers/tty/serial/serial-tegra.c b/drivers/tty/serial/serial-tegra.c index 731ac35acb31..d92a150c8733 100644 --- a/drivers/tty/serial/serial-tegra.c +++ b/drivers/tty/serial/serial-tegra.c @@ -1191,7 +1191,7 @@ static const char *tegra_uart_type(struct uart_port *u) return TEGRA_UART_TYPE; } -static struct uart_ops tegra_uart_ops = { +static const struct uart_ops tegra_uart_ops = { .tx_empty = tegra_uart_tx_empty, .set_mctrl = tegra_uart_set_mctrl, .get_mctrl = tegra_uart_get_mctrl, diff --git a/drivers/tty/serial/serial_txx9.c b/drivers/tty/serial/serial_txx9.c index f80312eed4fd..f80fead6c5fc 100644 --- a/drivers/tty/serial/serial_txx9.c +++ b/drivers/tty/serial/serial_txx9.c @@ -845,7 +845,7 @@ serial_txx9_type(struct uart_port *port) return "txx9"; } -static struct uart_ops serial_txx9_pops = { +static const struct uart_ops serial_txx9_pops = { .tx_empty = serial_txx9_tx_empty, .set_mctrl = serial_txx9_set_mctrl, .get_mctrl = serial_txx9_get_mctrl, diff --git a/drivers/tty/serial/sirfsoc_uart.c b/drivers/tty/serial/sirfsoc_uart.c index b186c9c4f850..e03282d92b59 100644 --- a/drivers/tty/serial/sirfsoc_uart.c +++ b/drivers/tty/serial/sirfsoc_uart.c @@ -1061,7 +1061,7 @@ static void sirfsoc_uart_config_port(struct uart_port *port, int flags) } } -static struct uart_ops sirfsoc_uart_ops = { +static const struct uart_ops sirfsoc_uart_ops = { .tx_empty = sirfsoc_uart_tx_empty, .get_mctrl = sirfsoc_uart_get_mctrl, .set_mctrl = sirfsoc_uart_set_mctrl, diff --git a/drivers/tty/serial/sn_console.c b/drivers/tty/serial/sn_console.c index d4692d888e9d..9e0e6586c698 100644 --- a/drivers/tty/serial/sn_console.c +++ b/drivers/tty/serial/sn_console.c @@ -380,7 +380,7 @@ static void snp_config_port(struct uart_port *port, int flags) /* Associate the uart functions above - given to serial core */ -static struct uart_ops sn_console_ops = { +static const struct uart_ops sn_console_ops = { .tx_empty = snp_tx_empty, .set_mctrl = snp_set_mctrl, .get_mctrl = snp_get_mctrl, diff --git a/drivers/tty/serial/sprd_serial.c b/drivers/tty/serial/sprd_serial.c index 699447aa8b43..d98e3dc4838e 100644 --- a/drivers/tty/serial/sprd_serial.c +++ b/drivers/tty/serial/sprd_serial.c @@ -498,7 +498,7 @@ static int sprd_verify_port(struct uart_port *port, return 0; } -static struct uart_ops serial_sprd_ops = { +static const struct uart_ops serial_sprd_ops = { .tx_empty = sprd_tx_empty, .get_mctrl = sprd_get_mctrl, .set_mctrl = sprd_set_mctrl, diff --git a/drivers/tty/serial/sunhv.c b/drivers/tty/serial/sunhv.c index 99ef5c6e4766..73abd89c0108 100644 --- a/drivers/tty/serial/sunhv.c +++ b/drivers/tty/serial/sunhv.c @@ -370,7 +370,7 @@ static int sunhv_verify_port(struct uart_port *port, struct serial_struct *ser) return -EINVAL; } -static struct uart_ops sunhv_pops = { +static const struct uart_ops sunhv_pops = { .tx_empty = sunhv_tx_empty, .set_mctrl = sunhv_set_mctrl, .get_mctrl = sunhv_get_mctrl, diff --git a/drivers/tty/serial/sunzilog.c b/drivers/tty/serial/sunzilog.c index 8b6ace341029..252cea49c068 100644 --- a/drivers/tty/serial/sunzilog.c +++ b/drivers/tty/serial/sunzilog.c @@ -1046,7 +1046,7 @@ static void sunzilog_put_poll_char(struct uart_port *port, } #endif /* CONFIG_CONSOLE_POLL */ -static struct uart_ops sunzilog_pops = { +static const struct uart_ops sunzilog_pops = { .tx_empty = sunzilog_tx_empty, .set_mctrl = sunzilog_set_mctrl, .get_mctrl = sunzilog_get_mctrl, diff --git a/drivers/tty/serial/vr41xx_siu.c b/drivers/tty/serial/vr41xx_siu.c index 485de53c5d75..439057e8107a 100644 --- a/drivers/tty/serial/vr41xx_siu.c +++ b/drivers/tty/serial/vr41xx_siu.c @@ -681,7 +681,7 @@ static int siu_verify_port(struct uart_port *port, struct serial_struct *serial) return 0; } -static struct uart_ops siu_uart_ops = { +static const struct uart_ops siu_uart_ops = { .tx_empty = siu_tx_empty, .set_mctrl = siu_set_mctrl, .get_mctrl = siu_get_mctrl, diff --git a/drivers/tty/serial/vt8500_serial.c b/drivers/tty/serial/vt8500_serial.c index 6b85adce0ac9..435a6f3260be 100644 --- a/drivers/tty/serial/vt8500_serial.c +++ b/drivers/tty/serial/vt8500_serial.c @@ -592,7 +592,7 @@ static void vt8500_put_poll_char(struct uart_port *port, unsigned char c) } #endif -static struct uart_ops vt8500_uart_pops = { +static const struct uart_ops vt8500_uart_pops = { .tx_empty = vt8500_tx_empty, .set_mctrl = vt8500_set_mctrl, .get_mctrl = vt8500_get_mctrl, diff --git a/drivers/tty/serial/zs.c b/drivers/tty/serial/zs.c index eeefd76a30da..d32bd499d684 100644 --- a/drivers/tty/serial/zs.c +++ b/drivers/tty/serial/zs.c @@ -1045,7 +1045,7 @@ static int zs_verify_port(struct uart_port *uport, struct serial_struct *ser) } -static struct uart_ops zs_ops = { +static const struct uart_ops zs_ops = { .tx_empty = zs_tx_empty, .set_mctrl = zs_set_mctrl, .get_mctrl = zs_get_mctrl, -- cgit v1.2.3-59-g8ed1b From 54b12c48f0c603f25bac3c7c58a02cee65610171 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 25 Jan 2017 15:55:49 +0100 Subject: serial: sh-sci: Reformat sci_parse_dt() for git diff As the function header of sci_parse_dt() is split in an unusual way, "git diff" gets confused when changes to the body of the function are made, and attributes them to the wrong function. Reformat the function header to fix this. Signed-off-by: Geert Uytterhoeven Reviewed-by: Simon Horman Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/sh-sci.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index a18f4cb8e1fb..d7535b47bf10 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -2810,8 +2810,8 @@ static const struct of_device_id of_sci_match[] = { }; MODULE_DEVICE_TABLE(of, of_sci_match); -static struct plat_sci_port * -sci_parse_dt(struct platform_device *pdev, unsigned int *dev_id) +static struct plat_sci_port *sci_parse_dt(struct platform_device *pdev, + unsigned int *dev_id) { struct device_node *np = pdev->dev.of_node; const struct of_device_id *match; -- cgit v1.2.3-59-g8ed1b From aa42db44f6705334c6130103492484ea3c7199b3 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Wed, 25 Jan 2017 23:19:01 +0100 Subject: 8250: of: remove remnants of generic of_serial driver During build testing, I ran into a warning in a driver that I had written myself at some point: drivers/tty/serial/8250/8250_of.c: In function 'of_platform_serial_probe': drivers/tty/serial/8250/8250_of.c:233:1: error: the frame size of 1200 bytes is larger than 1152 bytes [-Werror=frame-larger-than=] This is harmless by itself, but it shows two other problems in the driver: - It still tries to be generic enough to handle all kinds of serial ports, where in reality the driver has been 8250-only for a while, and every other uart has its own DT support - As a result of that generalization, we keep two copies of 'struct uart_port' on the stack during probe(). This is completely unnessary. Removing the last code dealing with unsupported port_type values solves both problems nicely, and reduces the stack size. Signed-off-by: Arnd Bergmann Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_of.c | 93 ++++++++++----------------------------- 1 file changed, 24 insertions(+), 69 deletions(-) diff --git a/drivers/tty/serial/8250/8250_of.c b/drivers/tty/serial/8250/8250_of.c index 52812524abfb..1cbadafc6889 100644 --- a/drivers/tty/serial/8250/8250_of.c +++ b/drivers/tty/serial/8250/8250_of.c @@ -172,7 +172,8 @@ static int of_platform_serial_probe(struct platform_device *ofdev) { const struct of_device_id *match; struct of_serial_info *info; - struct uart_port port; + struct uart_8250_port port8250; + u32 tx_threshold; int port_type; int ret; @@ -188,41 +189,24 @@ static int of_platform_serial_probe(struct platform_device *ofdev) return -ENOMEM; port_type = (unsigned long)match->data; - ret = of_platform_serial_setup(ofdev, port_type, &port, info); + memset(&port8250, 0, sizeof(port8250)); + ret = of_platform_serial_setup(ofdev, port_type, &port8250.port, info); if (ret) goto out; - switch (port_type) { - case PORT_8250 ... PORT_MAX_8250: - { - u32 tx_threshold; - struct uart_8250_port port8250; - memset(&port8250, 0, sizeof(port8250)); - port8250.port = port; + if (port8250.port.fifosize) + port8250.capabilities = UART_CAP_FIFO; - if (port.fifosize) - port8250.capabilities = UART_CAP_FIFO; + /* Check for TX FIFO threshold & set tx_loadsz */ + if ((of_property_read_u32(ofdev->dev.of_node, "tx-threshold", + &tx_threshold) == 0) && + (tx_threshold < port8250.port.fifosize)) + port8250.tx_loadsz = port8250.port.fifosize - tx_threshold; - /* Check for TX FIFO threshold & set tx_loadsz */ - if ((of_property_read_u32(ofdev->dev.of_node, "tx-threshold", - &tx_threshold) == 0) && - (tx_threshold < port.fifosize)) - port8250.tx_loadsz = port.fifosize - tx_threshold; + if (of_property_read_bool(ofdev->dev.of_node, "auto-flow-control")) + port8250.capabilities |= UART_CAP_AFE; - if (of_property_read_bool(ofdev->dev.of_node, - "auto-flow-control")) - port8250.capabilities |= UART_CAP_AFE; - - ret = serial8250_register_8250_port(&port8250); - break; - } - default: - /* need to add code for these */ - case PORT_UNKNOWN: - dev_info(&ofdev->dev, "Unknown serial port found, ignored\n"); - ret = -ENODEV; - break; - } + ret = serial8250_register_8250_port(&port8250); if (ret < 0) goto out; @@ -232,7 +216,7 @@ static int of_platform_serial_probe(struct platform_device *ofdev) return 0; out: kfree(info); - irq_dispose_mapping(port.irq); + irq_dispose_mapping(port8250.port.irq); return ret; } @@ -242,14 +226,8 @@ out: static int of_platform_serial_remove(struct platform_device *ofdev) { struct of_serial_info *info = platform_get_drvdata(ofdev); - switch (info->type) { - case PORT_8250 ... PORT_MAX_8250: - serial8250_unregister_port(info->line); - break; - default: - /* need to add code for these */ - break; - } + + serial8250_unregister_port(info->line); if (info->clk) clk_disable_unprepare(info->clk); @@ -258,18 +236,23 @@ static int of_platform_serial_remove(struct platform_device *ofdev) } #ifdef CONFIG_PM_SLEEP -static void of_serial_suspend_8250(struct of_serial_info *info) +static int of_serial_suspend(struct device *dev) { + struct of_serial_info *info = dev_get_drvdata(dev); struct uart_8250_port *port8250 = serial8250_get_port(info->line); struct uart_port *port = &port8250->port; serial8250_suspend_port(info->line); + if (info->clk && (!uart_console(port) || console_suspend_enabled)) clk_disable_unprepare(info->clk); + + return 0; } -static void of_serial_resume_8250(struct of_serial_info *info) +static int of_serial_resume(struct device *dev) { + struct of_serial_info *info = dev_get_drvdata(dev); struct uart_8250_port *port8250 = serial8250_get_port(info->line); struct uart_port *port = &port8250->port; @@ -277,34 +260,6 @@ static void of_serial_resume_8250(struct of_serial_info *info) clk_prepare_enable(info->clk); serial8250_resume_port(info->line); -} - -static int of_serial_suspend(struct device *dev) -{ - struct of_serial_info *info = dev_get_drvdata(dev); - - switch (info->type) { - case PORT_8250 ... PORT_MAX_8250: - of_serial_suspend_8250(info); - break; - default: - break; - } - - return 0; -} - -static int of_serial_resume(struct device *dev) -{ - struct of_serial_info *info = dev_get_drvdata(dev); - - switch (info->type) { - case PORT_8250 ... PORT_MAX_8250: - of_serial_resume_8250(info); - break; - default: - break; - } return 0; } -- cgit v1.2.3-59-g8ed1b From 1a613626d2895f4f6b95a3b0a6413e52e00b5f95 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Mon, 30 Jan 2017 09:12:11 -0200 Subject: serial: imx: Fix the RTS GPIO polarity in RS485 mode On a board that needs to drive RTS GPIO high in order to enable the transmission of a RS485 transceiver the following description is passed in the devide tree: &uart4 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_uart4>; rts-gpios = <&gpio6 2 GPIO_ACTIVE_HIGH>; status = "okay"; }; and userspace configures the uart port as follows: /* enable RS485 mode: */ rs485conf.flags |= SER_RS485_ENABLED; /* set logical level for RTS pin equal to 1 when sending: */ rs485conf.flags |= SER_RS485_RTS_ON_SEND; /* set logical level for RTS pin equal to 0 after sending: */ rs485conf.flags &= ~(SER_RS485_RTS_AFTER_SEND); However the RTS GPIO polarity observed in the oscilloscope is inverted. When the SER_RS485_RTS_ON_SEND flag is set the imx_port_rts_active() function should be called and following the same logic when SER_RS485_RTS_AFTER_SEND flag is cleared the imx_port_rts_inactive() should be called. Do such logic change so that RS485 communication in half duplex can work successfully when the RTS GPIO pin is passed via device tree. Signed-off-by: Fabio Estevam Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/imx.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c index 33fcc84e756b..29dd57c51706 100644 --- a/drivers/tty/serial/imx.c +++ b/drivers/tty/serial/imx.c @@ -377,9 +377,9 @@ static void imx_stop_tx(struct uart_port *port) readl(port->membase + USR2) & USR2_TXDC) { temp = readl(port->membase + UCR2); if (port->rs485.flags & SER_RS485_RTS_AFTER_SEND) - imx_port_rts_inactive(sport, &temp); - else imx_port_rts_active(sport, &temp); + else + imx_port_rts_inactive(sport, &temp); temp |= UCR2_RXEN; writel(temp, port->membase + UCR2); @@ -585,9 +585,9 @@ static void imx_start_tx(struct uart_port *port) if (port->rs485.flags & SER_RS485_ENABLED) { temp = readl(port->membase + UCR2); if (port->rs485.flags & SER_RS485_RTS_ON_SEND) - imx_port_rts_inactive(sport, &temp); - else imx_port_rts_active(sport, &temp); + else + imx_port_rts_inactive(sport, &temp); if (!(port->rs485.flags & SER_RS485_RX_DURING_TX)) temp &= ~UCR2_RXEN; writel(temp, port->membase + UCR2); @@ -1477,9 +1477,9 @@ imx_set_termios(struct uart_port *port, struct ktermios *termios, */ if (port->rs485.flags & SER_RS485_RTS_AFTER_SEND) - imx_port_rts_inactive(sport, &ucr2); - else imx_port_rts_active(sport, &ucr2); + else + imx_port_rts_inactive(sport, &ucr2); } else { imx_port_rts_auto(sport, &ucr2); } @@ -1489,9 +1489,9 @@ imx_set_termios(struct uart_port *port, struct ktermios *termios, } else if (port->rs485.flags & SER_RS485_ENABLED) { /* disable transmitter */ if (port->rs485.flags & SER_RS485_RTS_AFTER_SEND) - imx_port_rts_inactive(sport, &ucr2); - else imx_port_rts_active(sport, &ucr2); + else + imx_port_rts_inactive(sport, &ucr2); } @@ -1733,9 +1733,9 @@ static int imx_rs485_config(struct uart_port *port, /* disable transmitter */ temp = readl(sport->port.membase + UCR2); if (rs485conf->flags & SER_RS485_RTS_AFTER_SEND) - imx_port_rts_inactive(sport, &temp); - else imx_port_rts_active(sport, &temp); + else + imx_port_rts_inactive(sport, &temp); writel(temp, sport->port.membase + UCR2); } -- cgit v1.2.3-59-g8ed1b From bc2be239feef9ac9fc8ad17adf7c03b353f6546f Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Mon, 30 Jan 2017 09:12:12 -0200 Subject: serial: imx: Fix the CTS_B polarity in RS485 mode When userspace passes the SER_RS485_RTS_ON_SEND flag it means that the CTS_B pin should go to logic level high before the transmission begins. CTS_B goes to logic level high when both CTSC and CTS bits are cleared. When userspace passes the SER_RS485_RTS_AFTER_SEND flag it means that the CTS_B pin should go to logic level low after the transmission finishes. CTS_B goes to logic level low when CTSC bit is cleared and CTS bit is set. So fix the CTS_B polarity logic. Signed-off-by: Fabio Estevam Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/imx.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c index 29dd57c51706..e3e152cbc75e 100644 --- a/drivers/tty/serial/imx.c +++ b/drivers/tty/serial/imx.c @@ -336,15 +336,15 @@ static void imx_port_ucrs_restore(struct uart_port *port, static void imx_port_rts_active(struct imx_port *sport, unsigned long *ucr2) { - *ucr2 &= ~UCR2_CTSC; - *ucr2 |= UCR2_CTS; + *ucr2 &= ~(UCR2_CTSC | UCR2_CTS); mctrl_gpio_set(sport->gpios, sport->port.mctrl | TIOCM_RTS); } static void imx_port_rts_inactive(struct imx_port *sport, unsigned long *ucr2) { - *ucr2 &= ~(UCR2_CTSC | UCR2_CTS); + *ucr2 &= ~UCR2_CTSC; + *ucr2 |= UCR2_CTS; mctrl_gpio_set(sport->gpios, sport->port.mctrl & ~TIOCM_RTS); } -- cgit v1.2.3-59-g8ed1b From d0aeaa83f0b0f7a92615bbdd6b1f96812f7dcfd2 Mon Sep 17 00:00:00 2001 From: Sudip Mukherjee Date: Mon, 30 Jan 2017 22:28:21 +0000 Subject: serial: exar: split out the exar code from 8250_pci Add the serial driver for the Exar chips. And also register the platform device for the GPIO provided by the Exar chips. Reviewed-by: Andy Shevchenko Signed-off-by: Sudip Mukherjee Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_exar.c | 396 ++++++++++++++++++++++++++++++++++++ drivers/tty/serial/8250/Kconfig | 4 + drivers/tty/serial/8250/Makefile | 1 + 3 files changed, 401 insertions(+) create mode 100644 drivers/tty/serial/8250/8250_exar.c diff --git a/drivers/tty/serial/8250/8250_exar.c b/drivers/tty/serial/8250/8250_exar.c new file mode 100644 index 000000000000..e6b44a75a5e0 --- /dev/null +++ b/drivers/tty/serial/8250/8250_exar.c @@ -0,0 +1,396 @@ +/* + * Probe module for 8250/16550-type Exar chips PCI serial ports. + * + * Based on drivers/tty/serial/8250/8250_pci.c, + * + * Copyright (C) 2017 Sudip Mukherjee, All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "8250.h" + +#define PCI_DEVICE_ID_COMMTECH_4224PCIE 0x0020 +#define PCI_DEVICE_ID_COMMTECH_4228PCIE 0x0021 +#define PCI_DEVICE_ID_COMMTECH_4222PCIE 0x0022 +#define PCI_DEVICE_ID_EXAR_XR17V4358 0x4358 +#define PCI_DEVICE_ID_EXAR_XR17V8358 0x8358 + +#define UART_EXAR_MPIOINT_7_0 0x8f /* MPIOINT[7:0] */ +#define UART_EXAR_MPIOLVL_7_0 0x90 /* MPIOLVL[7:0] */ +#define UART_EXAR_MPIO3T_7_0 0x91 /* MPIO3T[7:0] */ +#define UART_EXAR_MPIOINV_7_0 0x92 /* MPIOINV[7:0] */ +#define UART_EXAR_MPIOSEL_7_0 0x93 /* MPIOSEL[7:0] */ +#define UART_EXAR_MPIOOD_7_0 0x94 /* MPIOOD[7:0] */ +#define UART_EXAR_MPIOINT_15_8 0x95 /* MPIOINT[15:8] */ +#define UART_EXAR_MPIOLVL_15_8 0x96 /* MPIOLVL[15:8] */ +#define UART_EXAR_MPIO3T_15_8 0x97 /* MPIO3T[15:8] */ +#define UART_EXAR_MPIOINV_15_8 0x98 /* MPIOINV[15:8] */ +#define UART_EXAR_MPIOSEL_15_8 0x99 /* MPIOSEL[15:8] */ +#define UART_EXAR_MPIOOD_15_8 0x9a /* MPIOOD[15:8] */ + +struct exar8250; + +/** + * struct exar8250_board - board information + * @num_ports: number of serial ports + * @reg_shift: describes UART register mapping in PCI memory + */ +struct exar8250_board { + unsigned int num_ports; + unsigned int reg_shift; + bool has_slave; + int (*setup)(struct exar8250 *, struct pci_dev *, + struct uart_8250_port *, int); + void (*exit)(struct pci_dev *pcidev); +}; + +struct exar8250 { + unsigned int nr; + struct exar8250_board *board; + int line[0]; +}; + +static int default_setup(struct exar8250 *priv, struct pci_dev *pcidev, + int idx, unsigned int offset, + struct uart_8250_port *port) +{ + const struct exar8250_board *board = priv->board; + unsigned int bar = 0; + + port->port.iotype = UPIO_MEM; + port->port.mapbase = pci_resource_start(pcidev, bar) + offset; + port->port.membase = pcim_iomap_table(pcidev)[bar] + offset; + port->port.regshift = board->reg_shift; + + return 0; +} + +static int +pci_connect_tech_setup(struct exar8250 *priv, struct pci_dev *pcidev, + struct uart_8250_port *port, int idx) +{ + unsigned int offset = idx * 0x200; + unsigned int baud = 1843200; + + port->port.uartclk = baud * 16; + return default_setup(priv, pcidev, idx, offset, port); +} + +static int +pci_xr17c154_setup(struct exar8250 *priv, struct pci_dev *pcidev, + struct uart_8250_port *port, int idx) +{ + unsigned int offset = idx * 0x200; + unsigned int baud = 921600; + + port->port.uartclk = baud * 16; + return default_setup(priv, pcidev, idx, offset, port); +} + +static void setup_gpio(u8 __iomem *p) +{ + writeb(0x00, p + UART_EXAR_MPIOINT_7_0); + writeb(0x00, p + UART_EXAR_MPIOLVL_7_0); + writeb(0x00, p + UART_EXAR_MPIO3T_7_0); + writeb(0x00, p + UART_EXAR_MPIOINV_7_0); + writeb(0x00, p + UART_EXAR_MPIOSEL_7_0); + writeb(0x00, p + UART_EXAR_MPIOOD_7_0); + writeb(0x00, p + UART_EXAR_MPIOINT_15_8); + writeb(0x00, p + UART_EXAR_MPIOLVL_15_8); + writeb(0x00, p + UART_EXAR_MPIO3T_15_8); + writeb(0x00, p + UART_EXAR_MPIOINV_15_8); + writeb(0x00, p + UART_EXAR_MPIOSEL_15_8); + writeb(0x00, p + UART_EXAR_MPIOOD_15_8); +} + +static void * +xr17v35x_register_gpio(struct pci_dev *pcidev) +{ + struct platform_device *pdev; + + pdev = platform_device_alloc("gpio_exar", PLATFORM_DEVID_AUTO); + if (!pdev) + return NULL; + + platform_set_drvdata(pdev, pcidev); + if (platform_device_add(pdev) < 0) { + platform_device_put(pdev); + return NULL; + } + + return pdev; +} + +static int +pci_xr17v35x_setup(struct exar8250 *priv, struct pci_dev *pcidev, + struct uart_8250_port *port, int idx) +{ + const struct exar8250_board *board = priv->board; + unsigned int offset = idx * 0x400; + unsigned int baud = 7812500; + u8 __iomem *p; + int ret; + + port->port.uartclk = baud * 16; + /* + * Setup the uart clock for the devices on expansion slot to + * half the clock speed of the main chip (which is 125MHz) + */ + if (board->has_slave && idx >= 8) + port->port.uartclk /= 2; + + p = pci_ioremap_bar(pcidev, 0); + if (!p) + return -ENOMEM; + + /* Setup Multipurpose Input/Output pins. */ + if (idx == 0) + setup_gpio(p); + + writeb(0x00, p + UART_EXAR_8XMODE); + writeb(UART_FCTR_EXAR_TRGD, p + UART_EXAR_FCTR); + writeb(128, p + UART_EXAR_TXTRG); + writeb(128, p + UART_EXAR_RXTRG); + iounmap(p); + + ret = default_setup(priv, pcidev, idx, offset, port); + if (ret) + return ret; + + if (idx == 0) + port->port.private_data = + xr17v35x_register_gpio(pcidev); + + return 0; +} + +static void pci_xr17v35x_exit(struct pci_dev *pcidev) +{ + struct exar8250 *priv = pci_get_drvdata(pcidev); + struct uart_8250_port *port = serial8250_get_port(priv->line[0]); + struct platform_device *pdev = port->port.private_data; + + platform_device_unregister(pdev); + port->port.private_data = NULL; +} + +static int +exar_pci_probe(struct pci_dev *pcidev, const struct pci_device_id *ent) +{ + unsigned int nr_ports, i, bar = 0, maxnr; + struct exar8250_board *board; + struct uart_8250_port uart; + struct exar8250 *priv; + int rc; + + board = (struct exar8250_board *)ent->driver_data; + if (!board) + return -EINVAL; + + rc = pcim_enable_device(pcidev); + if (rc) + return rc; + + maxnr = pci_resource_len(pcidev, bar) >> (board->reg_shift + 3); + + nr_ports = board->num_ports ? board->num_ports : pcidev->device & 0x0f; + + priv = devm_kzalloc(&pcidev->dev, sizeof(*priv) + + sizeof(unsigned int) * nr_ports, + GFP_KERNEL); + if (!priv) + return -ENOMEM; + + priv->board = board; + + memset(&uart, 0, sizeof(uart)); + uart.port.flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF | UPF_SHARE_IRQ + | UPF_EXAR_EFR; + uart.port.irq = pcidev->irq; + uart.port.dev = &pcidev->dev; + + for (i = 0; i < nr_ports && i < maxnr; i++) { + rc = board->setup(priv, pcidev, &uart, i); + if (rc) { + dev_err(&pcidev->dev, "Failed to setup port %u\n", i); + break; + } + + dev_dbg(&pcidev->dev, "Setup PCI port: port %lx, irq %d, type %d\n", + uart.port.iobase, uart.port.irq, uart.port.iotype); + + priv->line[i] = serial8250_register_8250_port(&uart); + if (priv->line[i] < 0) { + dev_err(&pcidev->dev, + "Couldn't register serial port %lx, irq %d, type %d, error %d\n", + uart.port.iobase, uart.port.irq, + uart.port.iotype, priv->line[i]); + break; + } + } + priv->nr = i; + pci_set_drvdata(pcidev, priv); + return 0; +} + +static void exar_pci_remove(struct pci_dev *pcidev) +{ + struct exar8250 *priv = pci_get_drvdata(pcidev); + unsigned int i; + + for (i = 0; i < priv->nr; i++) + serial8250_unregister_port(priv->line[i]); + + if (priv->board->exit) + priv->board->exit(pcidev); +} + +static int __maybe_unused exar_suspend(struct device *dev) +{ + struct pci_dev *pcidev = to_pci_dev(dev); + struct exar8250 *priv = pci_get_drvdata(pcidev); + unsigned int i; + + for (i = 0; i < priv->nr; i++) + if (priv->line[i] >= 0) + serial8250_suspend_port(priv->line[i]); + + /* Ensure that every init quirk is properly torn down */ + if (priv->board->exit) + priv->board->exit(pcidev); + + return 0; +} + +static int __maybe_unused exar_resume(struct device *dev) +{ + struct pci_dev *pcidev = to_pci_dev(dev); + struct exar8250 *priv = pci_get_drvdata(pcidev); + unsigned int i; + + for (i = 0; i < priv->nr; i++) + if (priv->line[i] >= 0) + serial8250_resume_port(priv->line[i]); + + return 0; +} + +static SIMPLE_DEV_PM_OPS(exar_pci_pm, exar_suspend, exar_resume); + +static const struct exar8250_board pbn_connect = { + .setup = pci_connect_tech_setup, +}; + +static const struct exar8250_board pbn_exar_ibm_saturn = { + .num_ports = 1, + .setup = pci_xr17c154_setup, +}; + +static const struct exar8250_board pbn_exar_XR17C15x = { + .setup = pci_xr17c154_setup, +}; + +static const struct exar8250_board pbn_exar_XR17V35x = { + .setup = pci_xr17v35x_setup, + .exit = pci_xr17v35x_exit, +}; + +static const struct exar8250_board pbn_exar_XR17V4358 = { + .num_ports = 12, + .has_slave = true, + .setup = pci_xr17v35x_setup, + .exit = pci_xr17v35x_exit, +}; + +static const struct exar8250_board pbn_exar_XR17V8358 = { + .num_ports = 16, + .has_slave = true, + .setup = pci_xr17v35x_setup, + .exit = pci_xr17v35x_exit, +}; + +#define CONNECT_DEVICE(devid, sdevid, bd) { \ + PCI_DEVICE_SUB( \ + PCI_VENDOR_ID_EXAR, \ + PCI_DEVICE_ID_EXAR_##devid, \ + PCI_SUBVENDOR_ID_CONNECT_TECH, \ + PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_##sdevid), 0, 0, \ + (kernel_ulong_t)&bd \ + } + +#define EXAR_DEVICE(vend, devid, bd) { \ + PCI_VDEVICE(vend, PCI_DEVICE_ID_##devid), (kernel_ulong_t)&bd \ + } + +#define IBM_DEVICE(devid, sdevid, bd) { \ + PCI_DEVICE_SUB( \ + PCI_VENDOR_ID_EXAR, \ + PCI_DEVICE_ID_EXAR_##devid, \ + PCI_VENDOR_ID_IBM, \ + PCI_SUBDEVICE_ID_IBM_##sdevid), 0, 0, \ + (kernel_ulong_t)&bd \ + } + +static struct pci_device_id exar_pci_tbl[] = { + CONNECT_DEVICE(XR17C152, UART_2_232, pbn_connect), + CONNECT_DEVICE(XR17C154, UART_4_232, pbn_connect), + CONNECT_DEVICE(XR17C158, UART_8_232, pbn_connect), + CONNECT_DEVICE(XR17C152, UART_1_1, pbn_connect), + CONNECT_DEVICE(XR17C154, UART_2_2, pbn_connect), + CONNECT_DEVICE(XR17C158, UART_4_4, pbn_connect), + CONNECT_DEVICE(XR17C152, UART_2, pbn_connect), + CONNECT_DEVICE(XR17C154, UART_4, pbn_connect), + CONNECT_DEVICE(XR17C158, UART_8, pbn_connect), + CONNECT_DEVICE(XR17C152, UART_2_485, pbn_connect), + CONNECT_DEVICE(XR17C154, UART_4_485, pbn_connect), + CONNECT_DEVICE(XR17C158, UART_8_485, pbn_connect), + + IBM_DEVICE(XR17C152, SATURN_SERIAL_ONE_PORT, pbn_exar_ibm_saturn), + + /* Exar Corp. XR17C15[248] Dual/Quad/Octal UART */ + EXAR_DEVICE(EXAR, EXAR_XR17C152, pbn_exar_XR17C15x), + EXAR_DEVICE(EXAR, EXAR_XR17C154, pbn_exar_XR17C15x), + EXAR_DEVICE(EXAR, EXAR_XR17C158, pbn_exar_XR17C15x), + + /* Exar Corp. XR17V[48]35[248] Dual/Quad/Octal/Hexa PCIe UARTs */ + EXAR_DEVICE(EXAR, EXAR_XR17V352, pbn_exar_XR17V35x), + EXAR_DEVICE(EXAR, EXAR_XR17V354, pbn_exar_XR17V35x), + EXAR_DEVICE(EXAR, EXAR_XR17V358, pbn_exar_XR17V35x), + EXAR_DEVICE(EXAR, EXAR_XR17V4358, pbn_exar_XR17V4358), + EXAR_DEVICE(EXAR, EXAR_XR17V8358, pbn_exar_XR17V8358), + EXAR_DEVICE(COMMTECH, COMMTECH_4222PCIE, pbn_exar_XR17V35x), + EXAR_DEVICE(COMMTECH, COMMTECH_4224PCIE, pbn_exar_XR17V35x), + EXAR_DEVICE(COMMTECH, COMMTECH_4228PCIE, pbn_exar_XR17V35x), + { 0, } +}; +MODULE_DEVICE_TABLE(pci, exar_pci_tbl); + +static struct pci_driver exar_pci_driver = { + .name = "exar_serial", + .probe = exar_pci_probe, + .remove = exar_pci_remove, + .driver = { + .pm = &exar_pci_pm, + }, + .id_table = exar_pci_tbl, +}; +module_pci_driver(exar_pci_driver); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Exar Serial Dricer"); +MODULE_AUTHOR("Sudip Mukherjee "); diff --git a/drivers/tty/serial/8250/Kconfig b/drivers/tty/serial/8250/Kconfig index c0bf996a826e..2573dedd6b2d 100644 --- a/drivers/tty/serial/8250/Kconfig +++ b/drivers/tty/serial/8250/Kconfig @@ -127,6 +127,10 @@ config SERIAL_8250_PCI Note that serial ports on NetMos 9835 Multi-I/O cards are handled by the parport_serial driver, enabled with CONFIG_PARPORT_SERIAL. +config SERIAL_8250_EXAR + tristate "8250/16550 PCI device support" + depends on SERIAL_8250_PCI + config SERIAL_8250_HP300 tristate depends on SERIAL_8250 && HP300 diff --git a/drivers/tty/serial/8250/Makefile b/drivers/tty/serial/8250/Makefile index 850e721877a9..2f30f9ecdb1b 100644 --- a/drivers/tty/serial/8250/Makefile +++ b/drivers/tty/serial/8250/Makefile @@ -10,6 +10,7 @@ obj-$(CONFIG_SERIAL_8250) += 8250.o 8250_base.o 8250_base-$(CONFIG_SERIAL_8250_FINTEK) += 8250_fintek.o obj-$(CONFIG_SERIAL_8250_GSC) += 8250_gsc.o obj-$(CONFIG_SERIAL_8250_PCI) += 8250_pci.o +obj-$(CONFIG_SERIAL_8250_EXAR) += 8250_exar.o obj-$(CONFIG_SERIAL_8250_HP300) += 8250_hp300.o obj-$(CONFIG_SERIAL_8250_CS) += serial_cs.o obj-$(CONFIG_SERIAL_8250_ACORN) += 8250_acorn.o -- cgit v1.2.3-59-g8ed1b From 5d1a2388edee77930c8b542cf8be0c92342dbeb4 Mon Sep 17 00:00:00 2001 From: Sudip Mukherjee Date: Mon, 30 Jan 2017 22:28:22 +0000 Subject: serial: 8250_pci: remove exar code Remove the Exar specific codes from 8250_pci and blacklist those chips so that the new Exar serial driver binds to the devices. Reviewed-by: Andy Shevchenko Signed-off-by: Sudip Mukherjee Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_pci.c | 336 +------------------------------------ drivers/tty/serial/8250/Kconfig | 1 + 2 files changed, 4 insertions(+), 333 deletions(-) diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c index f7ee4e0760e5..3eb638c35ba1 100644 --- a/drivers/tty/serial/8250/8250_pci.c +++ b/drivers/tty/serial/8250/8250_pci.c @@ -1610,9 +1610,6 @@ static int pci_eg20t_init(struct pci_dev *dev) #endif } -#define PCI_DEVICE_ID_EXAR_XR17V4358 0x4358 -#define PCI_DEVICE_ID_EXAR_XR17V8358 0x8358 - #define UART_EXAR_MPIOINT_7_0 0x8f /* MPIOINT[7:0] */ #define UART_EXAR_MPIOLVL_7_0 0x90 /* MPIOLVL[7:0] */ #define UART_EXAR_MPIO3T_7_0 0x91 /* MPIO3T[7:0] */ @@ -1625,71 +1622,6 @@ static int pci_eg20t_init(struct pci_dev *dev) #define UART_EXAR_MPIOINV_15_8 0x98 /* MPIOINV[15:8] */ #define UART_EXAR_MPIOSEL_15_8 0x99 /* MPIOSEL[15:8] */ #define UART_EXAR_MPIOOD_15_8 0x9a /* MPIOOD[15:8] */ - -static int -pci_xr17c154_setup(struct serial_private *priv, - const struct pciserial_board *board, - struct uart_8250_port *port, int idx) -{ - port->port.flags |= UPF_EXAR_EFR; - return pci_default_setup(priv, board, port, idx); -} - -static inline int -xr17v35x_has_slave(struct serial_private *priv) -{ - const int dev_id = priv->dev->device; - - return ((dev_id == PCI_DEVICE_ID_EXAR_XR17V4358) || - (dev_id == PCI_DEVICE_ID_EXAR_XR17V8358)); -} - -static int -pci_xr17v35x_setup(struct serial_private *priv, - const struct pciserial_board *board, - struct uart_8250_port *port, int idx) -{ - u8 __iomem *p; - - p = pci_ioremap_bar(priv->dev, 0); - if (p == NULL) - return -ENOMEM; - - port->port.flags |= UPF_EXAR_EFR; - - /* - * Setup the uart clock for the devices on expansion slot to - * half the clock speed of the main chip (which is 125MHz) - */ - if (xr17v35x_has_slave(priv) && idx >= 8) - port->port.uartclk = (7812500 * 16 / 2); - - /* - * Setup Multipurpose Input/Output pins. - */ - if (idx == 0) { - writeb(0x00, p + UART_EXAR_MPIOINT_7_0); - writeb(0x00, p + UART_EXAR_MPIOLVL_7_0); - writeb(0x00, p + UART_EXAR_MPIO3T_7_0); - writeb(0x00, p + UART_EXAR_MPIOINV_7_0); - writeb(0x00, p + UART_EXAR_MPIOSEL_7_0); - writeb(0x00, p + UART_EXAR_MPIOOD_7_0); - writeb(0x00, p + UART_EXAR_MPIOINT_15_8); - writeb(0x00, p + UART_EXAR_MPIOLVL_15_8); - writeb(0x00, p + UART_EXAR_MPIO3T_15_8); - writeb(0x00, p + UART_EXAR_MPIOINV_15_8); - writeb(0x00, p + UART_EXAR_MPIOSEL_15_8); - writeb(0x00, p + UART_EXAR_MPIOOD_15_8); - } - writeb(0x00, p + UART_EXAR_8XMODE); - writeb(UART_FCTR_EXAR_TRGD, p + UART_EXAR_FCTR); - writeb(128, p + UART_EXAR_TXTRG); - writeb(128, p + UART_EXAR_RXTRG); - iounmap(p); - - return pci_default_setup(priv, board, port, idx); -} - #define PCI_DEVICE_ID_COMMTECH_4222PCI335 0x0004 #define PCI_DEVICE_ID_COMMTECH_4224PCI335 0x0002 #define PCI_DEVICE_ID_COMMTECH_2324PCI335 0x000a @@ -1814,9 +1746,6 @@ pci_wch_ch38x_setup(struct serial_private *priv, #define PCI_VENDOR_ID_AGESTAR 0x5372 #define PCI_DEVICE_ID_AGESTAR_9375 0x6872 #define PCI_VENDOR_ID_ASIX 0x9710 -#define PCI_DEVICE_ID_COMMTECH_4224PCIE 0x0020 -#define PCI_DEVICE_ID_COMMTECH_4228PCIE 0x0021 -#define PCI_DEVICE_ID_COMMTECH_4222PCIE 0x0022 #define PCI_DEVICE_ID_BROADCOM_TRUMANAGE 0x160a #define PCI_DEVICE_ID_AMCC_ADDIDATA_APCI7800 0x818e @@ -2277,65 +2206,6 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = { .init = pci_timedia_init, .setup = pci_timedia_setup, }, - /* - * Exar cards - */ - { - .vendor = PCI_VENDOR_ID_EXAR, - .device = PCI_DEVICE_ID_EXAR_XR17C152, - .subvendor = PCI_ANY_ID, - .subdevice = PCI_ANY_ID, - .setup = pci_xr17c154_setup, - }, - { - .vendor = PCI_VENDOR_ID_EXAR, - .device = PCI_DEVICE_ID_EXAR_XR17C154, - .subvendor = PCI_ANY_ID, - .subdevice = PCI_ANY_ID, - .setup = pci_xr17c154_setup, - }, - { - .vendor = PCI_VENDOR_ID_EXAR, - .device = PCI_DEVICE_ID_EXAR_XR17C158, - .subvendor = PCI_ANY_ID, - .subdevice = PCI_ANY_ID, - .setup = pci_xr17c154_setup, - }, - { - .vendor = PCI_VENDOR_ID_EXAR, - .device = PCI_DEVICE_ID_EXAR_XR17V352, - .subvendor = PCI_ANY_ID, - .subdevice = PCI_ANY_ID, - .setup = pci_xr17v35x_setup, - }, - { - .vendor = PCI_VENDOR_ID_EXAR, - .device = PCI_DEVICE_ID_EXAR_XR17V354, - .subvendor = PCI_ANY_ID, - .subdevice = PCI_ANY_ID, - .setup = pci_xr17v35x_setup, - }, - { - .vendor = PCI_VENDOR_ID_EXAR, - .device = PCI_DEVICE_ID_EXAR_XR17V358, - .subvendor = PCI_ANY_ID, - .subdevice = PCI_ANY_ID, - .setup = pci_xr17v35x_setup, - }, - { - .vendor = PCI_VENDOR_ID_EXAR, - .device = PCI_DEVICE_ID_EXAR_XR17V4358, - .subvendor = PCI_ANY_ID, - .subdevice = PCI_ANY_ID, - .setup = pci_xr17v35x_setup, - }, - { - .vendor = PCI_VENDOR_ID_EXAR, - .device = PCI_DEVICE_ID_EXAR_XR17V8358, - .subvendor = PCI_ANY_ID, - .subdevice = PCI_ANY_ID, - .setup = pci_xr17v35x_setup, - }, /* * Xircom cards */ @@ -2592,27 +2462,6 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = { .subdevice = PCI_ANY_ID, .setup = pci_fastcom335_setup, }, - { - .vendor = PCI_VENDOR_ID_COMMTECH, - .device = PCI_DEVICE_ID_COMMTECH_4222PCIE, - .subvendor = PCI_ANY_ID, - .subdevice = PCI_ANY_ID, - .setup = pci_xr17v35x_setup, - }, - { - .vendor = PCI_VENDOR_ID_COMMTECH, - .device = PCI_DEVICE_ID_COMMTECH_4224PCIE, - .subvendor = PCI_ANY_ID, - .subdevice = PCI_ANY_ID, - .setup = pci_xr17v35x_setup, - }, - { - .vendor = PCI_VENDOR_ID_COMMTECH, - .device = PCI_DEVICE_ID_COMMTECH_4228PCIE, - .subvendor = PCI_ANY_ID, - .subdevice = PCI_ANY_ID, - .setup = pci_xr17v35x_setup, - }, /* * Broadcom TruManage (NetXtreme) */ @@ -2825,15 +2674,6 @@ enum pci_board_num_t { pbn_computone_6, pbn_computone_8, pbn_sbsxrsio, - pbn_exar_XR17C152, - pbn_exar_XR17C154, - pbn_exar_XR17C158, - pbn_exar_XR17V352, - pbn_exar_XR17V354, - pbn_exar_XR17V358, - pbn_exar_XR17V4358, - pbn_exar_XR17V8358, - pbn_exar_ibm_saturn, pbn_pasemi_1682M, pbn_ni8430_2, pbn_ni8430_4, @@ -3473,76 +3313,6 @@ static struct pciserial_board pci_boards[] = { .uart_offset = 256, .reg_shift = 4, }, - /* - * Exar Corp. XR17C15[248] Dual/Quad/Octal UART - * Only basic 16550A support. - * XR17C15[24] are not tested, but they should work. - */ - [pbn_exar_XR17C152] = { - .flags = FL_BASE0, - .num_ports = 2, - .base_baud = 921600, - .uart_offset = 0x200, - }, - [pbn_exar_XR17C154] = { - .flags = FL_BASE0, - .num_ports = 4, - .base_baud = 921600, - .uart_offset = 0x200, - }, - [pbn_exar_XR17C158] = { - .flags = FL_BASE0, - .num_ports = 8, - .base_baud = 921600, - .uart_offset = 0x200, - }, - [pbn_exar_XR17V352] = { - .flags = FL_BASE0, - .num_ports = 2, - .base_baud = 7812500, - .uart_offset = 0x400, - .reg_shift = 0, - .first_offset = 0, - }, - [pbn_exar_XR17V354] = { - .flags = FL_BASE0, - .num_ports = 4, - .base_baud = 7812500, - .uart_offset = 0x400, - .reg_shift = 0, - .first_offset = 0, - }, - [pbn_exar_XR17V358] = { - .flags = FL_BASE0, - .num_ports = 8, - .base_baud = 7812500, - .uart_offset = 0x400, - .reg_shift = 0, - .first_offset = 0, - }, - [pbn_exar_XR17V4358] = { - .flags = FL_BASE0, - .num_ports = 12, - .base_baud = 7812500, - .uart_offset = 0x400, - .reg_shift = 0, - .first_offset = 0, - }, - [pbn_exar_XR17V8358] = { - .flags = FL_BASE0, - .num_ports = 16, - .base_baud = 7812500, - .uart_offset = 0x400, - .reg_shift = 0, - .first_offset = 0, - }, - [pbn_exar_ibm_saturn] = { - .flags = FL_BASE0, - .num_ports = 1, - .base_baud = 921600, - .uart_offset = 0x200, - }, - /* * PA Semi PWRficient PA6T-1682M on-chip UART */ @@ -3739,6 +3509,9 @@ static const struct pci_device_id blacklist[] = { { PCI_VDEVICE(INTEL, 0x228c), }, { PCI_VDEVICE(INTEL, 0x9ce3), }, { PCI_VDEVICE(INTEL, 0x9ce4), }, + + /* Exar devices */ + { PCI_VDEVICE(EXAR, PCI_ANY_ID), }, }; /* @@ -4164,58 +3937,6 @@ static struct pci_device_id serial_pci_tbl[] = { PCI_VENDOR_ID_AFAVLAB, PCI_SUBDEVICE_ID_AFAVLAB_P061, 0, 0, pbn_b0_4_1152000 }, - { PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C152, - PCI_SUBVENDOR_ID_CONNECT_TECH, - PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_2_232, 0, 0, - pbn_b0_2_1843200_200 }, - { PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C154, - PCI_SUBVENDOR_ID_CONNECT_TECH, - PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_4_232, 0, 0, - pbn_b0_4_1843200_200 }, - { PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C158, - PCI_SUBVENDOR_ID_CONNECT_TECH, - PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_8_232, 0, 0, - pbn_b0_8_1843200_200 }, - { PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C152, - PCI_SUBVENDOR_ID_CONNECT_TECH, - PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_1_1, 0, 0, - pbn_b0_2_1843200_200 }, - { PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C154, - PCI_SUBVENDOR_ID_CONNECT_TECH, - PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_2_2, 0, 0, - pbn_b0_4_1843200_200 }, - { PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C158, - PCI_SUBVENDOR_ID_CONNECT_TECH, - PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_4_4, 0, 0, - pbn_b0_8_1843200_200 }, - { PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C152, - PCI_SUBVENDOR_ID_CONNECT_TECH, - PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_2, 0, 0, - pbn_b0_2_1843200_200 }, - { PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C154, - PCI_SUBVENDOR_ID_CONNECT_TECH, - PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_4, 0, 0, - pbn_b0_4_1843200_200 }, - { PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C158, - PCI_SUBVENDOR_ID_CONNECT_TECH, - PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_8, 0, 0, - pbn_b0_8_1843200_200 }, - { PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C152, - PCI_SUBVENDOR_ID_CONNECT_TECH, - PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_2_485, 0, 0, - pbn_b0_2_1843200_200 }, - { PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C154, - PCI_SUBVENDOR_ID_CONNECT_TECH, - PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_4_485, 0, 0, - pbn_b0_4_1843200_200 }, - { PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C158, - PCI_SUBVENDOR_ID_CONNECT_TECH, - PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_8_485, 0, 0, - pbn_b0_8_1843200_200 }, - { PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C152, - PCI_VENDOR_ID_IBM, PCI_SUBDEVICE_ID_IBM_SATURN_SERIAL_ONE_PORT, - 0, 0, pbn_exar_ibm_saturn }, - { PCI_VENDOR_ID_SEALEVEL, PCI_DEVICE_ID_SEALEVEL_U530, PCI_ANY_ID, PCI_ANY_ID, 0, 0, pbn_b2_bt_1_115200 }, @@ -4943,45 +4664,6 @@ static struct pci_device_id serial_pci_tbl[] = { { PCI_VENDOR_ID_DCI, PCI_DEVICE_ID_DCI_PCCOM8, PCI_ANY_ID, PCI_ANY_ID, 0, 0, pbn_b3_8_115200 }, - - /* - * Exar Corp. XR17C15[248] Dual/Quad/Octal UART - */ - { PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C152, - PCI_ANY_ID, PCI_ANY_ID, - 0, - 0, pbn_exar_XR17C152 }, - { PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C154, - PCI_ANY_ID, PCI_ANY_ID, - 0, - 0, pbn_exar_XR17C154 }, - { PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C158, - PCI_ANY_ID, PCI_ANY_ID, - 0, - 0, pbn_exar_XR17C158 }, - /* - * Exar Corp. XR17V[48]35[248] Dual/Quad/Octal/Hexa PCIe UARTs - */ - { PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17V352, - PCI_ANY_ID, PCI_ANY_ID, - 0, - 0, pbn_exar_XR17V352 }, - { PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17V354, - PCI_ANY_ID, PCI_ANY_ID, - 0, - 0, pbn_exar_XR17V354 }, - { PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17V358, - PCI_ANY_ID, PCI_ANY_ID, - 0, - 0, pbn_exar_XR17V358 }, - { PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17V4358, - PCI_ANY_ID, PCI_ANY_ID, - 0, - 0, pbn_exar_XR17V4358 }, - { PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17V8358, - PCI_ANY_ID, PCI_ANY_ID, - 0, - 0, pbn_exar_XR17V8358 }, /* * Pericom PI7C9X795[1248] Uno/Dual/Quad/Octal UART */ @@ -5576,18 +5258,6 @@ static struct pci_device_id serial_pci_tbl[] = { PCI_ANY_ID, PCI_ANY_ID, 0, 0, pbn_b0_8_1152000_200 }, - { PCI_VENDOR_ID_COMMTECH, PCI_DEVICE_ID_COMMTECH_4222PCIE, - PCI_ANY_ID, PCI_ANY_ID, - 0, - 0, pbn_exar_XR17V352 }, - { PCI_VENDOR_ID_COMMTECH, PCI_DEVICE_ID_COMMTECH_4224PCIE, - PCI_ANY_ID, PCI_ANY_ID, - 0, - 0, pbn_exar_XR17V354 }, - { PCI_VENDOR_ID_COMMTECH, PCI_DEVICE_ID_COMMTECH_4228PCIE, - PCI_ANY_ID, PCI_ANY_ID, - 0, - 0, pbn_exar_XR17V358 }, /* Fintek PCI serial cards */ { PCI_DEVICE(0x1c29, 0x1104), .driver_data = pbn_fintek_4 }, diff --git a/drivers/tty/serial/8250/Kconfig b/drivers/tty/serial/8250/Kconfig index 2573dedd6b2d..a65fb8197aec 100644 --- a/drivers/tty/serial/8250/Kconfig +++ b/drivers/tty/serial/8250/Kconfig @@ -130,6 +130,7 @@ config SERIAL_8250_PCI config SERIAL_8250_EXAR tristate "8250/16550 PCI device support" depends on SERIAL_8250_PCI + default SERIAL_8250 config SERIAL_8250_HP300 tristate -- cgit v1.2.3-59-g8ed1b From a8a1781b87266a1b006e2223581facd0517e555b Mon Sep 17 00:00:00 2001 From: 남영민 Date: Wed, 1 Feb 2017 19:25:46 +0900 Subject: serial: samsung: enable clock before accessing interrupt mask resister Ensure that the uart clock is enabled prior to writing to the interrupt mask register in s3c24xx_serial_resume_noirq function. Without enabing the uart clock, the uart register cannot be accessed. Signed-off-by: Youngmin Nam Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/samsung.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/tty/serial/samsung.c b/drivers/tty/serial/samsung.c index a9b309ba24a4..b4f86c219db1 100644 --- a/drivers/tty/serial/samsung.c +++ b/drivers/tty/serial/samsung.c @@ -1916,6 +1916,7 @@ static int s3c24xx_serial_resume(struct device *dev) static int s3c24xx_serial_resume_noirq(struct device *dev) { struct uart_port *port = s3c24xx_dev_to_port(dev); + struct s3c24xx_uart_port *ourport = to_ourport(port); if (port) { /* restore IRQ mask */ @@ -1925,7 +1926,9 @@ static int s3c24xx_serial_resume_noirq(struct device *dev) uintm &= ~S3C64XX_UINTM_TXD_MSK; if (rx_enabled(port)) uintm &= ~S3C64XX_UINTM_RXD_MSK; + clk_prepare_enable(ourport->clk); wr_regl(port, S3C64XX_UINTM, uintm); + clk_disable_unprepare(ourport->clk); } } -- cgit v1.2.3-59-g8ed1b From aea9a80ba98a0c9b4de88850260e9fbdcc98360b Mon Sep 17 00:00:00 2001 From: Sudeep Holla Date: Wed, 1 Feb 2017 15:46:38 +0000 Subject: tty: serial: pl011: add ttyAMA for matching pl011 console Commit c7cef0a84912 ("console: Add extensible console matching") added match() method to struct console which allows the console to perform console command line matching instead of (or in addition to) default console matching (ie., by fixed name and index). Commit ad1696f6f09d ("ACPI: parse SPCR and enable matching console") introduced support for SPCR as matching console. Commit 10879ae5f12e ("serial: pl011: add console matching function") added the match method for pl011 console which checks for the console string to be "pl011" Now on a platform which has both SPCR in the ACPI tables and ttyAMA in the command line, the ttyAMA is chosen as "selected console" but it doesn't pass the matching console method which results in CON_CONSDEV not being set on the "selected console". As a result of that, the bootconsole(SPCR in the above case) is not unregistered and all the beginning boot messages are seen twice. This patch adds "ttyAMA" so that it's considered to match pl011 console. Fixes: 10879ae5f12e ("serial: pl011: add console matching function") Cc: Russell King Cc: Greg Kroah-Hartman Cc: Jiri Slaby Cc: Peter Hurley Cc: Aleksey Makarov Signed-off-by: Sudeep Holla Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/amba-pl011.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c index 963c2e5feedd..533b18d4a587 100644 --- a/drivers/tty/serial/amba-pl011.c +++ b/drivers/tty/serial/amba-pl011.c @@ -2340,7 +2340,7 @@ static int __init pl011_console_match(struct console *co, char *name, int idx, resource_size_t addr; int i; - if (strcmp(name, "pl011") != 0) + if (strcmp(name, "pl011") != 0 || strcmp(name, "ttyAMA") != 0) return -ENODEV; if (uart_parse_earlycon(options, &iotype, &addr, &options)) -- cgit v1.2.3-59-g8ed1b From 0832a462029538bab8dead15d12fa63f201a675a Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Wed, 1 Feb 2017 15:20:12 -0800 Subject: tty: serial: cpm_uart: make use of for_each_node_by_type() Instead of open-coding loop with of_find_node_by_type(), let's use canned macro. Signed-off-by: Dmitry Torokhov Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/cpm_uart/cpm_uart_core.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/drivers/tty/serial/cpm_uart/cpm_uart_core.c b/drivers/tty/serial/cpm_uart/cpm_uart_core.c index d3e3d42c0c12..f6bcc19c99d5 100644 --- a/drivers/tty/serial/cpm_uart/cpm_uart_core.c +++ b/drivers/tty/serial/cpm_uart/cpm_uart_core.c @@ -1302,7 +1302,7 @@ static int __init cpm_uart_console_setup(struct console *co, char *options) struct uart_cpm_port *pinfo; struct uart_port *port; - struct device_node *np = NULL; + struct device_node *np; int i = 0; if (co->index >= UART_NR) { @@ -1311,17 +1311,19 @@ static int __init cpm_uart_console_setup(struct console *co, char *options) return -ENODEV; } - do { - np = of_find_node_by_type(np, "serial"); - if (!np) - return -ENODEV; - + for_each_node_by_type(np, "serial") { if (!of_device_is_compatible(np, "fsl,cpm1-smc-uart") && !of_device_is_compatible(np, "fsl,cpm1-scc-uart") && !of_device_is_compatible(np, "fsl,cpm2-smc-uart") && !of_device_is_compatible(np, "fsl,cpm2-scc-uart")) - i--; - } while (i++ != co->index); + continue; + + if (i++ == co->index) + break; + } + + if (!np) + return -ENODEV; pinfo = &cpm_uart_ports[co->index]; -- cgit v1.2.3-59-g8ed1b From 54e14ae2f3e82b327853e40afa9382a984a56742 Mon Sep 17 00:00:00 2001 From: Ulrich Hecht Date: Thu, 2 Feb 2017 18:10:14 +0100 Subject: serial: sh-sci: add FIFO trigger bits Defines the bits controlling FIFO thresholds, adds the additional HSCIF registers to the register map. Signed-off-by: Ulrich Hecht Reviewed-by: Geert Uytterhoeven Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/sh-sci.c | 2 ++ drivers/tty/serial/sh-sci.h | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index d7535b47bf10..5044a5e5d340 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -373,6 +373,8 @@ static const struct sci_port_params sci_port_params[SCIx_NR_REGTYPES] = { [HSSRR] = { 0x40, 16 }, [SCDL] = { 0x30, 16 }, [SCCKS] = { 0x34, 16 }, + [HSRTRGR] = { 0x54, 16 }, + [HSTTRGR] = { 0x58, 16 }, }, .fifosize = 128, .overrun_reg = SCLSR, diff --git a/drivers/tty/serial/sh-sci.h b/drivers/tty/serial/sh-sci.h index 08073f0db732..30b6d67867e7 100644 --- a/drivers/tty/serial/sh-sci.h +++ b/drivers/tty/serial/sh-sci.h @@ -29,6 +29,8 @@ enum { SCPDR, /* Serial Port Data Register */ SCDL, /* BRG Frequency Division Register */ SCCKS, /* BRG Clock Select Register */ + HSRTRGR, /* Rx FIFO Data Count Trigger Register */ + HSTTRGR, /* Tx FIFO Data Count Trigger Register */ SCIx_NR_REGS, }; @@ -99,6 +101,10 @@ enum { #define SCIF_BREAK_CLEAR (u32)(~(SCIF_PER | SCIF_FER | SCIF_BRK)) /* SCFCR (FIFO Control Register) */ +#define SCFCR_RTRG1 BIT(7) /* Receive FIFO Data Count Trigger */ +#define SCFCR_RTRG0 BIT(6) +#define SCFCR_TTRG1 BIT(5) /* Transmit FIFO Data Count Trigger */ +#define SCFCR_TTRG0 BIT(4) #define SCFCR_MCE BIT(3) /* Modem Control Enable */ #define SCFCR_TFRST BIT(2) /* Transmit FIFO Data Register Reset */ #define SCFCR_RFRST BIT(1) /* Receive FIFO Data Register Reset */ -- cgit v1.2.3-59-g8ed1b From 88641c79c501735efe3b638ccad57ec077ed47f7 Mon Sep 17 00:00:00 2001 From: Ulrich Hecht Date: Thu, 2 Feb 2017 18:10:15 +0100 Subject: serial: sh-sci: consider DR (data ready) bit adequately To allow operation with a higher RX FIFO interrupt threshold in PIO mode, it is necessary to consider the DR bit ("FIFO not full, but no data received for 1.5 frames") as an indicator that data can be read. Otherwise the driver will let data rot in the FIFO until the threshold is reached. Signed-off-by: Ulrich Hecht Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/sh-sci.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/serial/sh-sci.h b/drivers/tty/serial/sh-sci.h index 30b6d67867e7..971b2ab088d8 100644 --- a/drivers/tty/serial/sh-sci.h +++ b/drivers/tty/serial/sh-sci.h @@ -151,7 +151,7 @@ enum { #define SCCKS_XIN BIT(14) /* SC_CLK uses bus clock (1) or SCIF_CLK (0) */ #define SCxSR_TEND(port) (((port)->type == PORT_SCI) ? SCI_TEND : SCIF_TEND) -#define SCxSR_RDxF(port) (((port)->type == PORT_SCI) ? SCI_RDRF : SCIF_RDF) +#define SCxSR_RDxF(port) (((port)->type == PORT_SCI) ? SCI_RDRF : SCIF_DR | SCIF_RDF) #define SCxSR_TDxE(port) (((port)->type == PORT_SCI) ? SCI_TDRE : SCIF_TDFE) #define SCxSR_FER(port) (((port)->type == PORT_SCI) ? SCI_FER : SCIF_FER) #define SCxSR_PER(port) (((port)->type == PORT_SCI) ? SCI_PER : SCIF_PER) -- cgit v1.2.3-59-g8ed1b From a380ed461f66d1b843cf13380a43a5fe790b8430 Mon Sep 17 00:00:00 2001 From: Ulrich Hecht Date: Thu, 2 Feb 2017 18:10:16 +0100 Subject: serial: sh-sci: implement FIFO threshold register setting Sets the closest match for a desired RX trigger level. Signed-off-by: Ulrich Hecht Reviewed-by: Geert Uytterhoeven Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/sh-sci.c | 59 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index 5044a5e5d340..050d028cf2a1 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -974,6 +974,65 @@ static int sci_handle_breaks(struct uart_port *port) return copied; } +static int scif_set_rtrg(struct uart_port *port, int rx_trig) +{ + unsigned int bits; + + if (rx_trig < 1) + rx_trig = 1; + if (rx_trig >= port->fifosize) + rx_trig = port->fifosize; + + /* HSCIF can be set to an arbitrary level. */ + if (sci_getreg(port, HSRTRGR)->size) { + serial_port_out(port, HSRTRGR, rx_trig); + return rx_trig; + } + + switch (port->type) { + case PORT_SCIF: + if (rx_trig < 4) { + bits = 0; + rx_trig = 1; + } else if (rx_trig < 8) { + bits = SCFCR_RTRG0; + rx_trig = 4; + } else if (rx_trig < 14) { + bits = SCFCR_RTRG1; + rx_trig = 8; + } else { + bits = SCFCR_RTRG0 | SCFCR_RTRG1; + rx_trig = 14; + } + break; + case PORT_SCIFA: + case PORT_SCIFB: + if (rx_trig < 16) { + bits = 0; + rx_trig = 1; + } else if (rx_trig < 32) { + bits = SCFCR_RTRG0; + rx_trig = 16; + } else if (rx_trig < 48) { + bits = SCFCR_RTRG1; + rx_trig = 32; + } else { + bits = SCFCR_RTRG0 | SCFCR_RTRG1; + rx_trig = 48; + } + break; + default: + WARN(1, "unknown FIFO configuration"); + return 1; + } + + serial_port_out(port, SCFCR, + (serial_port_in(port, SCFCR) & + ~(SCFCR_RTRG1 | SCFCR_RTRG0)) | bits); + + return rx_trig; +} + #ifdef CONFIG_SERIAL_SH_SCI_DMA static void sci_dma_tx_complete(void *arg) { -- cgit v1.2.3-59-g8ed1b From c3485ee0d560b182e1e0f67d67246718739f0782 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Thu, 2 Feb 2017 13:48:05 -0600 Subject: tty_port: Add port client functions Introduce a client (upward direction) operations struct for tty_port clients. Initially supported operations are for receiving data and write wake-up. This will allow for having clients other than an ldisc. Convert the calls to the ldisc to use the client ops as the default operations. Signed-off-by: Rob Herring Reviewed-By: Sebastian Reichel Tested-By: Sebastian Reichel Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_buffer.c | 17 +++-------------- drivers/tty/tty_port.c | 46 ++++++++++++++++++++++++++++++++++++++++------ include/linux/tty.h | 9 ++++++++- 3 files changed, 51 insertions(+), 21 deletions(-) diff --git a/drivers/tty/tty_buffer.c b/drivers/tty/tty_buffer.c index f4dc3e296dd5..4e7a4e9dcf4d 100644 --- a/drivers/tty/tty_buffer.c +++ b/drivers/tty/tty_buffer.c @@ -437,7 +437,7 @@ int tty_ldisc_receive_buf(struct tty_ldisc *ld, const unsigned char *p, EXPORT_SYMBOL_GPL(tty_ldisc_receive_buf); static int -receive_buf(struct tty_ldisc *ld, struct tty_buffer *head, int count) +receive_buf(struct tty_port *port, struct tty_buffer *head, int count) { unsigned char *p = char_buf_ptr(head, head->read); char *f = NULL; @@ -445,7 +445,7 @@ receive_buf(struct tty_ldisc *ld, struct tty_buffer *head, int count) if (~head->flags & TTYB_NORMAL) f = flag_buf_ptr(head, head->read); - return tty_ldisc_receive_buf(ld, p, f, count); + return port->client_ops->receive_buf(port, p, f, count); } /** @@ -465,16 +465,6 @@ static void flush_to_ldisc(struct work_struct *work) { struct tty_port *port = container_of(work, struct tty_port, buf.work); struct tty_bufhead *buf = &port->buf; - struct tty_struct *tty; - struct tty_ldisc *disc; - - tty = READ_ONCE(port->itty); - if (tty == NULL) - return; - - disc = tty_ldisc_ref(tty); - if (disc == NULL) - return; mutex_lock(&buf->lock); @@ -504,7 +494,7 @@ static void flush_to_ldisc(struct work_struct *work) continue; } - count = receive_buf(disc, head, count); + count = receive_buf(port, head, count); if (!count) break; head->read += count; @@ -512,7 +502,6 @@ static void flush_to_ldisc(struct work_struct *work) mutex_unlock(&buf->lock); - tty_ldisc_deref(disc); } /** diff --git a/drivers/tty/tty_port.c b/drivers/tty/tty_port.c index 1d8804843103..8d9886b06037 100644 --- a/drivers/tty/tty_port.c +++ b/drivers/tty/tty_port.c @@ -17,6 +17,44 @@ #include #include +static int tty_port_default_receive_buf(struct tty_port *port, + const unsigned char *p, + const unsigned char *f, size_t count) +{ + int ret; + struct tty_struct *tty; + struct tty_ldisc *disc; + + tty = READ_ONCE(port->itty); + if (!tty) + return 0; + + disc = tty_ldisc_ref(tty); + if (!disc) + return 0; + + ret = tty_ldisc_receive_buf(disc, p, (char *)f, count); + + tty_ldisc_deref(disc); + + return ret; +} + +static void tty_port_default_wakeup(struct tty_port *port) +{ + struct tty_struct *tty = tty_port_tty_get(port); + + if (tty) { + tty_wakeup(tty); + tty_kref_put(tty); + } +} + +static const struct tty_port_client_operations default_client_ops = { + .receive_buf = tty_port_default_receive_buf, + .write_wakeup = tty_port_default_wakeup, +}; + void tty_port_init(struct tty_port *port) { memset(port, 0, sizeof(*port)); @@ -28,6 +66,7 @@ void tty_port_init(struct tty_port *port) spin_lock_init(&port->lock); port->close_delay = (50 * HZ) / 100; port->closing_wait = (3000 * HZ) / 100; + port->client_ops = &default_client_ops; kref_init(&port->kref); } EXPORT_SYMBOL(tty_port_init); @@ -272,12 +311,7 @@ EXPORT_SYMBOL_GPL(tty_port_tty_hangup); */ void tty_port_tty_wakeup(struct tty_port *port) { - struct tty_struct *tty = tty_port_tty_get(port); - - if (tty) { - tty_wakeup(tty); - tty_kref_put(tty); - } + port->client_ops->write_wakeup(port); } EXPORT_SYMBOL_GPL(tty_port_tty_wakeup); diff --git a/include/linux/tty.h b/include/linux/tty.h index 21c0fabfed60..1017e904c0a3 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -217,12 +217,18 @@ struct tty_port_operations { /* Called on the final put of a port */ void (*destruct)(struct tty_port *port); }; - + +struct tty_port_client_operations { + int (*receive_buf)(struct tty_port *port, const unsigned char *, const unsigned char *, size_t); + void (*write_wakeup)(struct tty_port *port); +}; + struct tty_port { struct tty_bufhead buf; /* Locked internally */ struct tty_struct *tty; /* Back pointer */ struct tty_struct *itty; /* internal back ptr */ const struct tty_port_operations *ops; /* Port operations */ + const struct tty_port_client_operations *client_ops; /* Port client operations */ spinlock_t lock; /* Lock protecting tty field */ int blocked_open; /* Waiting to open */ int count; /* Usage count */ @@ -241,6 +247,7 @@ struct tty_port { based drain is needed else set to size of fifo */ struct kref kref; /* Ref counter */ + void *client_data; }; /* tty_port::iflags bits -- use atomic bit ops */ -- cgit v1.2.3-59-g8ed1b From c1c98dadb2de5d9645bdd142536ca81ca28361f7 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Thu, 2 Feb 2017 13:48:06 -0600 Subject: dt/bindings: Add a serial/UART attached device binding Add a common binding for describing serial/UART attached devices. Common examples are Bluetooth, WiFi, NFC and GPS devices. Serial attached devices are represented as child nodes of a UART node. This may need to be extended for more complex devices with multiple interfaces, but for the simple cases a child node is sufficient. Tested-By: Sebastian Reichel Signed-off-by: Rob Herring Signed-off-by: Greg Kroah-Hartman --- .../devicetree/bindings/serial/slave-device.txt | 36 ++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 Documentation/devicetree/bindings/serial/slave-device.txt diff --git a/Documentation/devicetree/bindings/serial/slave-device.txt b/Documentation/devicetree/bindings/serial/slave-device.txt new file mode 100644 index 000000000000..f66037928f5f --- /dev/null +++ b/Documentation/devicetree/bindings/serial/slave-device.txt @@ -0,0 +1,36 @@ +Serial Slave Device DT binding + +This documents the binding structure and common properties for serial +attached devices. Common examples include Bluetooth, WiFi, NFC and GPS +devices. + +Serial attached devices shall be a child node of the host UART device the +slave device is attached to. It is expected that the attached device is +the only child node of the UART device. The slave device node name shall +reflect the generic type of device for the node. + +Required Properties: + +- compatible : A string reflecting the vendor and specific device the node + represents. + +Optional Properties: + +- max-speed : The maximum baud rate the device operates at. This should + only be present if the maximum is less than the slave device + can support. For example, a particular board has some signal + quality issue or the host processor can't support higher + baud rates. + +Example: + +serial@1234 { + compatible = "ns16550a"; + interrupts = <1>; + + bluetooth { + compatible = "brcm,bcm43341-bt"; + interrupt-parent = <&gpio>; + interrupts = <10>; + }; +}; -- cgit v1.2.3-59-g8ed1b From cd6484e1830be260abfba80a9c7d8f65531126d6 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Thu, 2 Feb 2017 13:48:07 -0600 Subject: serdev: Introduce new bus for serial attached devices The serdev bus is designed for devices such as Bluetooth, WiFi, GPS and NFC connected to UARTs on host processors. Tradionally these have been handled with tty line disciplines, rfkill, and userspace glue such as hciattach. This approach has many drawbacks since it doesn't fit into the Linux driver model. Handling of sideband signals, power control and firmware loading are the main issues. This creates a serdev bus with controllers (i.e. host serial ports) and attached devices. Typically, these are point to point connections, but some devices have muxing protocols or a h/w mux is conceivable. Any muxing is not yet supported with the serdev bus. Signed-off-by: Rob Herring Reviewed-By: Sebastian Reichel Tested-By: Sebastian Reichel Signed-off-by: Greg Kroah-Hartman --- MAINTAINERS | 8 + drivers/char/Kconfig | 1 + drivers/tty/Makefile | 1 + drivers/tty/serdev/Kconfig | 8 + drivers/tty/serdev/Makefile | 3 + drivers/tty/serdev/core.c | 421 ++++++++++++++++++++++++++++++++++++++++++++ include/linux/serdev.h | 241 +++++++++++++++++++++++++ 7 files changed, 683 insertions(+) create mode 100644 drivers/tty/serdev/Kconfig create mode 100644 drivers/tty/serdev/Makefile create mode 100644 drivers/tty/serdev/core.c create mode 100644 include/linux/serdev.h diff --git a/MAINTAINERS b/MAINTAINERS index c36976d3bd1a..90db2b5d418c 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -10831,6 +10831,14 @@ S: Maintained F: Documentation/devicetree/bindings/serial/ F: drivers/tty/serial/ +SERIAL DEVICE BUS +M: Rob Herring +L: linux-serial@vger.kernel.org +S: Maintained +F: Documentation/devicetree/bindings/serial/slave-device.txt +F: drivers/tty/serdev/ +F: include/linux/serdev.h + SERIAL IR RECEIVER M: Sean Young L: linux-media@vger.kernel.org diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig index fde005ef9d36..db8f74bbaf3e 100644 --- a/drivers/char/Kconfig +++ b/drivers/char/Kconfig @@ -46,6 +46,7 @@ config SGI_MBCS say Y or M here, otherwise say N. source "drivers/tty/serial/Kconfig" +source "drivers/tty/serdev/Kconfig" config TTY_PRINTK tristate "TTY driver to output user messages via printk" diff --git a/drivers/tty/Makefile b/drivers/tty/Makefile index 5817e2397463..b95bed92da9f 100644 --- a/drivers/tty/Makefile +++ b/drivers/tty/Makefile @@ -13,6 +13,7 @@ obj-$(CONFIG_R3964) += n_r3964.o obj-y += vt/ obj-$(CONFIG_HVC_DRIVER) += hvc/ obj-y += serial/ +obj-$(CONFIG_SERIAL_DEV_BUS) += serdev/ # tty drivers obj-$(CONFIG_AMIGA_BUILTIN_SERIAL) += amiserial.o diff --git a/drivers/tty/serdev/Kconfig b/drivers/tty/serdev/Kconfig new file mode 100644 index 000000000000..3b6ecd187bef --- /dev/null +++ b/drivers/tty/serdev/Kconfig @@ -0,0 +1,8 @@ +# +# Serial bus device driver configuration +# +menuconfig SERIAL_DEV_BUS + tristate "Serial device bus" + help + Core support for devices connected via a serial port. + diff --git a/drivers/tty/serdev/Makefile b/drivers/tty/serdev/Makefile new file mode 100644 index 000000000000..01a9b62183f4 --- /dev/null +++ b/drivers/tty/serdev/Makefile @@ -0,0 +1,3 @@ +serdev-objs := core.o + +obj-$(CONFIG_SERIAL_DEV_BUS) += serdev.o diff --git a/drivers/tty/serdev/core.c b/drivers/tty/serdev/core.c new file mode 100644 index 000000000000..f4c6c90add78 --- /dev/null +++ b/drivers/tty/serdev/core.c @@ -0,0 +1,421 @@ +/* + * Copyright (C) 2016-2017 Linaro Ltd., Rob Herring + * + * Based on drivers/spmi/spmi.c: + * Copyright (c) 2012-2015, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +static bool is_registered; +static DEFINE_IDA(ctrl_ida); + +static void serdev_device_release(struct device *dev) +{ + struct serdev_device *serdev = to_serdev_device(dev); + kfree(serdev); +} + +static const struct device_type serdev_device_type = { + .release = serdev_device_release, +}; + +static void serdev_ctrl_release(struct device *dev) +{ + struct serdev_controller *ctrl = to_serdev_controller(dev); + ida_simple_remove(&ctrl_ida, ctrl->nr); + kfree(ctrl); +} + +static const struct device_type serdev_ctrl_type = { + .release = serdev_ctrl_release, +}; + +static int serdev_device_match(struct device *dev, struct device_driver *drv) +{ + /* TODO: ACPI and platform matching */ + return of_driver_match_device(dev, drv); +} + +static int serdev_uevent(struct device *dev, struct kobj_uevent_env *env) +{ + /* TODO: ACPI and platform modalias */ + return of_device_uevent_modalias(dev, env); +} + +/** + * serdev_device_add() - add a device previously constructed via serdev_device_alloc() + * @serdev: serdev_device to be added + */ +int serdev_device_add(struct serdev_device *serdev) +{ + struct device *parent = serdev->dev.parent; + int err; + + dev_set_name(&serdev->dev, "%s-%d", dev_name(parent), serdev->nr); + + err = device_add(&serdev->dev); + if (err < 0) { + dev_err(&serdev->dev, "Can't add %s, status %d\n", + dev_name(&serdev->dev), err); + goto err_device_add; + } + + dev_dbg(&serdev->dev, "device %s registered\n", dev_name(&serdev->dev)); + +err_device_add: + return err; +} +EXPORT_SYMBOL_GPL(serdev_device_add); + +/** + * serdev_device_remove(): remove an serdev device + * @serdev: serdev_device to be removed + */ +void serdev_device_remove(struct serdev_device *serdev) +{ + device_unregister(&serdev->dev); +} +EXPORT_SYMBOL_GPL(serdev_device_remove); + +int serdev_device_open(struct serdev_device *serdev) +{ + struct serdev_controller *ctrl = serdev->ctrl; + + if (!ctrl || !ctrl->ops->open) + return -EINVAL; + + return ctrl->ops->open(ctrl); +} +EXPORT_SYMBOL_GPL(serdev_device_open); + +void serdev_device_close(struct serdev_device *serdev) +{ + struct serdev_controller *ctrl = serdev->ctrl; + + if (!ctrl || !ctrl->ops->close) + return; + + ctrl->ops->close(ctrl); +} +EXPORT_SYMBOL_GPL(serdev_device_close); + +int serdev_device_write_buf(struct serdev_device *serdev, + const unsigned char *buf, size_t count) +{ + struct serdev_controller *ctrl = serdev->ctrl; + + if (!ctrl || !ctrl->ops->write_buf) + return -EINVAL; + + return ctrl->ops->write_buf(ctrl, buf, count); +} +EXPORT_SYMBOL_GPL(serdev_device_write_buf); + +void serdev_device_write_flush(struct serdev_device *serdev) +{ + struct serdev_controller *ctrl = serdev->ctrl; + + if (!ctrl || !ctrl->ops->write_flush) + return; + + ctrl->ops->write_flush(ctrl); +} +EXPORT_SYMBOL_GPL(serdev_device_write_flush); + +int serdev_device_write_room(struct serdev_device *serdev) +{ + struct serdev_controller *ctrl = serdev->ctrl; + + if (!ctrl || !ctrl->ops->write_room) + return 0; + + return serdev->ctrl->ops->write_room(ctrl); +} +EXPORT_SYMBOL_GPL(serdev_device_write_room); + +unsigned int serdev_device_set_baudrate(struct serdev_device *serdev, unsigned int speed) +{ + struct serdev_controller *ctrl = serdev->ctrl; + + if (!ctrl || !ctrl->ops->set_baudrate) + return 0; + + return ctrl->ops->set_baudrate(ctrl, speed); + +} +EXPORT_SYMBOL_GPL(serdev_device_set_baudrate); + +void serdev_device_set_flow_control(struct serdev_device *serdev, bool enable) +{ + struct serdev_controller *ctrl = serdev->ctrl; + + if (!ctrl || !ctrl->ops->set_flow_control) + return; + + ctrl->ops->set_flow_control(ctrl, enable); +} +EXPORT_SYMBOL_GPL(serdev_device_set_flow_control); + +static int serdev_drv_probe(struct device *dev) +{ + const struct serdev_device_driver *sdrv = to_serdev_device_driver(dev->driver); + + return sdrv->probe(to_serdev_device(dev)); +} + +static int serdev_drv_remove(struct device *dev) +{ + const struct serdev_device_driver *sdrv = to_serdev_device_driver(dev->driver); + + sdrv->remove(to_serdev_device(dev)); + return 0; +} + +static ssize_t modalias_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + ssize_t len = of_device_get_modalias(dev, buf, PAGE_SIZE - 2); + buf[len] = '\n'; + buf[len+1] = 0; + return len+1; +} + +static struct device_attribute serdev_device_attrs[] = { + __ATTR_RO(modalias), + __ATTR_NULL +}; + +static struct bus_type serdev_bus_type = { + .name = "serial", + .match = serdev_device_match, + .probe = serdev_drv_probe, + .remove = serdev_drv_remove, + .uevent = serdev_uevent, + .dev_attrs = serdev_device_attrs, +}; + +/** + * serdev_controller_alloc() - Allocate a new serdev device + * @ctrl: associated controller + * + * Caller is responsible for either calling serdev_device_add() to add the + * newly allocated controller, or calling serdev_device_put() to discard it. + */ +struct serdev_device *serdev_device_alloc(struct serdev_controller *ctrl) +{ + struct serdev_device *serdev; + + serdev = kzalloc(sizeof(*serdev), GFP_KERNEL); + if (!serdev) + return NULL; + + serdev->ctrl = ctrl; + ctrl->serdev = serdev; + device_initialize(&serdev->dev); + serdev->dev.parent = &ctrl->dev; + serdev->dev.bus = &serdev_bus_type; + serdev->dev.type = &serdev_device_type; + return serdev; +} +EXPORT_SYMBOL_GPL(serdev_device_alloc); + +/** + * serdev_controller_alloc() - Allocate a new serdev controller + * @parent: parent device + * @size: size of private data + * + * Caller is responsible for either calling serdev_controller_add() to add the + * newly allocated controller, or calling serdev_controller_put() to discard it. + * The allocated private data region may be accessed via + * serdev_controller_get_drvdata() + */ +struct serdev_controller *serdev_controller_alloc(struct device *parent, + size_t size) +{ + struct serdev_controller *ctrl; + int id; + + if (WARN_ON(!parent)) + return NULL; + + ctrl = kzalloc(sizeof(*ctrl) + size, GFP_KERNEL); + if (!ctrl) + return NULL; + + device_initialize(&ctrl->dev); + ctrl->dev.type = &serdev_ctrl_type; + ctrl->dev.bus = &serdev_bus_type; + ctrl->dev.parent = parent; + ctrl->dev.of_node = parent->of_node; + serdev_controller_set_drvdata(ctrl, &ctrl[1]); + + id = ida_simple_get(&ctrl_ida, 0, 0, GFP_KERNEL); + if (id < 0) { + dev_err(parent, + "unable to allocate serdev controller identifier.\n"); + serdev_controller_put(ctrl); + return NULL; + } + + ctrl->nr = id; + dev_set_name(&ctrl->dev, "serial%d", id); + + dev_dbg(&ctrl->dev, "allocated controller 0x%p id %d\n", ctrl, id); + return ctrl; +} +EXPORT_SYMBOL_GPL(serdev_controller_alloc); + +static int of_serdev_register_devices(struct serdev_controller *ctrl) +{ + struct device_node *node; + struct serdev_device *serdev = NULL; + int err; + bool found = false; + + for_each_available_child_of_node(ctrl->dev.of_node, node) { + if (!of_get_property(node, "compatible", NULL)) + continue; + + dev_dbg(&ctrl->dev, "adding child %s\n", node->full_name); + + serdev = serdev_device_alloc(ctrl); + if (!serdev) + continue; + + serdev->dev.of_node = node; + + err = serdev_device_add(serdev); + if (err) { + dev_err(&serdev->dev, + "failure adding device. status %d\n", err); + serdev_device_put(serdev); + } else + found = true; + } + if (!found) + return -ENODEV; + + return 0; +} + +/** + * serdev_controller_add() - Add an serdev controller + * @ctrl: controller to be registered. + * + * Register a controller previously allocated via serdev_controller_alloc() with + * the serdev core. + */ +int serdev_controller_add(struct serdev_controller *ctrl) +{ + int ret; + + /* Can't register until after driver model init */ + if (WARN_ON(!is_registered)) + return -EAGAIN; + + ret = device_add(&ctrl->dev); + if (ret) + return ret; + + ret = of_serdev_register_devices(ctrl); + if (ret) + goto out_dev_del; + + dev_dbg(&ctrl->dev, "serdev%d registered: dev:%p\n", + ctrl->nr, &ctrl->dev); + return 0; + +out_dev_del: + device_del(&ctrl->dev); + return ret; +}; +EXPORT_SYMBOL_GPL(serdev_controller_add); + +/* Remove a device associated with a controller */ +static int serdev_remove_device(struct device *dev, void *data) +{ + struct serdev_device *serdev = to_serdev_device(dev); + if (dev->type == &serdev_device_type) + serdev_device_remove(serdev); + return 0; +} + +/** + * serdev_controller_remove(): remove an serdev controller + * @ctrl: controller to remove + * + * Remove a serdev controller. Caller is responsible for calling + * serdev_controller_put() to discard the allocated controller. + */ +void serdev_controller_remove(struct serdev_controller *ctrl) +{ + int dummy; + + if (!ctrl) + return; + + dummy = device_for_each_child(&ctrl->dev, NULL, + serdev_remove_device); + device_del(&ctrl->dev); +} +EXPORT_SYMBOL_GPL(serdev_controller_remove); + +/** + * serdev_driver_register() - Register client driver with serdev core + * @sdrv: client driver to be associated with client-device. + * + * This API will register the client driver with the serdev framework. + * It is typically called from the driver's module-init function. + */ +int __serdev_device_driver_register(struct serdev_device_driver *sdrv, struct module *owner) +{ + sdrv->driver.bus = &serdev_bus_type; + sdrv->driver.owner = owner; + + /* force drivers to async probe so I/O is possible in probe */ + sdrv->driver.probe_type = PROBE_PREFER_ASYNCHRONOUS; + + return driver_register(&sdrv->driver); +} +EXPORT_SYMBOL_GPL(__serdev_device_driver_register); + +static void __exit serdev_exit(void) +{ + bus_unregister(&serdev_bus_type); +} +module_exit(serdev_exit); + +static int __init serdev_init(void) +{ + int ret; + + ret = bus_register(&serdev_bus_type); + if (ret) + return ret; + + is_registered = true; + return 0; +} +/* Must be before serial drivers register */ +postcore_initcall(serdev_init); + +MODULE_AUTHOR("Rob Herring "); +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("Serial attached device bus"); diff --git a/include/linux/serdev.h b/include/linux/serdev.h new file mode 100644 index 000000000000..3ac26c1a8aab --- /dev/null +++ b/include/linux/serdev.h @@ -0,0 +1,241 @@ +/* + * Copyright (C) 2016-2017 Linaro Ltd., Rob Herring + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#ifndef _LINUX_SERDEV_H +#define _LINUX_SERDEV_H + +#include +#include + +struct serdev_controller; +struct serdev_device; + +/* + * serdev device structures + */ + +/** + * struct serdev_device_ops - Callback operations for a serdev device + * @receive_buf: Function called with data received from device. + * @write_wakeup: Function called when ready to transmit more data. + */ +struct serdev_device_ops { + int (*receive_buf)(struct serdev_device *, const unsigned char *, size_t); + void (*write_wakeup)(struct serdev_device *); +}; + +/** + * struct serdev_device - Basic representation of an serdev device + * @dev: Driver model representation of the device. + * @nr: Device number on serdev bus. + * @ctrl: serdev controller managing this device. + * @ops: Device operations. + */ +struct serdev_device { + struct device dev; + int nr; + struct serdev_controller *ctrl; + const struct serdev_device_ops *ops; +}; + +static inline struct serdev_device *to_serdev_device(struct device *d) +{ + return container_of(d, struct serdev_device, dev); +} + +/** + * struct serdev_device_driver - serdev slave device driver + * @driver: serdev device drivers should initialize name field of this + * structure. + * @probe: binds this driver to a serdev device. + * @remove: unbinds this driver from the serdev device. + */ +struct serdev_device_driver { + struct device_driver driver; + int (*probe)(struct serdev_device *); + void (*remove)(struct serdev_device *); +}; + +static inline struct serdev_device_driver *to_serdev_device_driver(struct device_driver *d) +{ + return container_of(d, struct serdev_device_driver, driver); +} + +/* + * serdev controller structures + */ +struct serdev_controller_ops { + int (*write_buf)(struct serdev_controller *, const unsigned char *, size_t); + void (*write_flush)(struct serdev_controller *); + int (*write_room)(struct serdev_controller *); + int (*open)(struct serdev_controller *); + void (*close)(struct serdev_controller *); + void (*set_flow_control)(struct serdev_controller *, bool); + unsigned int (*set_baudrate)(struct serdev_controller *, unsigned int); +}; + +/** + * struct serdev_controller - interface to the serdev controller + * @dev: Driver model representation of the device. + * @nr: number identifier for this controller/bus. + * @serdev: Pointer to slave device for this controller. + * @ops: Controller operations. + */ +struct serdev_controller { + struct device dev; + unsigned int nr; + struct serdev_device *serdev; + const struct serdev_controller_ops *ops; +}; + +static inline struct serdev_controller *to_serdev_controller(struct device *d) +{ + return container_of(d, struct serdev_controller, dev); +} + +static inline void *serdev_device_get_drvdata(const struct serdev_device *serdev) +{ + return dev_get_drvdata(&serdev->dev); +} + +static inline void serdev_device_set_drvdata(struct serdev_device *serdev, void *data) +{ + dev_set_drvdata(&serdev->dev, data); +} + +/** + * serdev_device_put() - decrement serdev device refcount + * @serdev serdev device. + */ +static inline void serdev_device_put(struct serdev_device *serdev) +{ + if (serdev) + put_device(&serdev->dev); +} + +static inline void serdev_device_set_client_ops(struct serdev_device *serdev, + const struct serdev_device_ops *ops) +{ + serdev->ops = ops; +} + +static inline +void *serdev_controller_get_drvdata(const struct serdev_controller *ctrl) +{ + return ctrl ? dev_get_drvdata(&ctrl->dev) : NULL; +} + +static inline void serdev_controller_set_drvdata(struct serdev_controller *ctrl, + void *data) +{ + dev_set_drvdata(&ctrl->dev, data); +} + +/** + * serdev_controller_put() - decrement controller refcount + * @ctrl serdev controller. + */ +static inline void serdev_controller_put(struct serdev_controller *ctrl) +{ + if (ctrl) + put_device(&ctrl->dev); +} + +struct serdev_device *serdev_device_alloc(struct serdev_controller *); +int serdev_device_add(struct serdev_device *); +void serdev_device_remove(struct serdev_device *); + +struct serdev_controller *serdev_controller_alloc(struct device *, size_t); +int serdev_controller_add(struct serdev_controller *); +void serdev_controller_remove(struct serdev_controller *); + +static inline void serdev_controller_write_wakeup(struct serdev_controller *ctrl) +{ + struct serdev_device *serdev = ctrl->serdev; + + if (!serdev || !serdev->ops->write_wakeup) + return; + + serdev->ops->write_wakeup(ctrl->serdev); +} + +static inline int serdev_controller_receive_buf(struct serdev_controller *ctrl, + const unsigned char *data, + size_t count) +{ + struct serdev_device *serdev = ctrl->serdev; + + if (!serdev || !serdev->ops->receive_buf) + return -EINVAL; + + return serdev->ops->receive_buf(ctrl->serdev, data, count); +} + +#if IS_ENABLED(CONFIG_SERIAL_DEV_BUS) + +int serdev_device_open(struct serdev_device *); +void serdev_device_close(struct serdev_device *); +unsigned int serdev_device_set_baudrate(struct serdev_device *, unsigned int); +void serdev_device_set_flow_control(struct serdev_device *, bool); +int serdev_device_write_buf(struct serdev_device *, const unsigned char *, size_t); +void serdev_device_write_flush(struct serdev_device *); +int serdev_device_write_room(struct serdev_device *); + +/* + * serdev device driver functions + */ +int __serdev_device_driver_register(struct serdev_device_driver *, struct module *); +#define serdev_device_driver_register(sdrv) \ + __serdev_device_driver_register(sdrv, THIS_MODULE) + +/** + * serdev_device_driver_unregister() - unregister an serdev client driver + * @sdrv: the driver to unregister + */ +static inline void serdev_device_driver_unregister(struct serdev_device_driver *sdrv) +{ + if (sdrv) + driver_unregister(&sdrv->driver); +} + +#define module_serdev_device_driver(__serdev_device_driver) \ + module_driver(__serdev_device_driver, serdev_device_driver_register, \ + serdev_device_driver_unregister) + +#else + +static inline int serdev_device_open(struct serdev_device *sdev) +{ + return -ENODEV; +} +static inline void serdev_device_close(struct serdev_device *sdev) {} +static inline unsigned int serdev_device_set_baudrate(struct serdev_device *sdev, unsigned int baudrate) +{ + return 0; +} +static inline void serdev_device_set_flow_control(struct serdev_device *sdev, bool enable) {} +static inline int serdev_device_write_buf(struct serdev_device *sdev, const unsigned char *buf, size_t count) +{ + return -ENODEV; +} +static inline void serdev_device_write_flush(struct serdev_device *sdev) {} +static inline int serdev_device_write_room(struct serdev_device *sdev) +{ + return 0; +} + +#define serdev_device_driver_register(x) +#define serdev_device_driver_unregister(x) + +#endif /* CONFIG_SERIAL_DEV_BUS */ + +#endif /*_LINUX_SERDEV_H */ -- cgit v1.2.3-59-g8ed1b From bed35c6dfa6a36233c3e1238a40dc1ae67955898 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Thu, 2 Feb 2017 13:48:08 -0600 Subject: serdev: add a tty port controller driver Add a serdev controller driver for tty ports. The controller is registered with serdev when tty ports are registered with the TTY core. As the TTY core is built-in only, this has the side effect of making serdev built-in as well. Signed-off-by: Rob Herring Reviewed-By: Sebastian Reichel Tested-By: Sebastian Reichel Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serdev/Kconfig | 8 ++ drivers/tty/serdev/Makefile | 2 + drivers/tty/serdev/serdev-ttyport.c | 224 ++++++++++++++++++++++++++++++++++++ include/linux/serdev.h | 21 ++++ 4 files changed, 255 insertions(+) create mode 100644 drivers/tty/serdev/serdev-ttyport.c diff --git a/drivers/tty/serdev/Kconfig b/drivers/tty/serdev/Kconfig index 3b6ecd187bef..cdc6b820cf93 100644 --- a/drivers/tty/serdev/Kconfig +++ b/drivers/tty/serdev/Kconfig @@ -6,3 +6,11 @@ menuconfig SERIAL_DEV_BUS help Core support for devices connected via a serial port. +if SERIAL_DEV_BUS + +config SERIAL_DEV_CTRL_TTYPORT + bool "Serial device TTY port controller" + depends on TTY + depends on SERIAL_DEV_BUS != m + +endif diff --git a/drivers/tty/serdev/Makefile b/drivers/tty/serdev/Makefile index 01a9b62183f4..0cbdb9444d9d 100644 --- a/drivers/tty/serdev/Makefile +++ b/drivers/tty/serdev/Makefile @@ -1,3 +1,5 @@ serdev-objs := core.o obj-$(CONFIG_SERIAL_DEV_BUS) += serdev.o + +obj-$(CONFIG_SERIAL_DEV_CTRL_TTYPORT) += serdev-ttyport.o diff --git a/drivers/tty/serdev/serdev-ttyport.c b/drivers/tty/serdev/serdev-ttyport.c new file mode 100644 index 000000000000..683320b81a2b --- /dev/null +++ b/drivers/tty/serdev/serdev-ttyport.c @@ -0,0 +1,224 @@ +/* + * Copyright (C) 2016-2017 Linaro Ltd., Rob Herring + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#include +#include +#include +#include + +#define SERPORT_ACTIVE 1 + +struct serport { + struct tty_port *port; + struct tty_struct *tty; + struct tty_driver *tty_drv; + int tty_idx; + unsigned long flags; +}; + +/* + * Callback functions from the tty port. + */ + +static int ttyport_receive_buf(struct tty_port *port, const unsigned char *cp, + const unsigned char *fp, size_t count) +{ + struct serdev_controller *ctrl = port->client_data; + struct serport *serport = serdev_controller_get_drvdata(ctrl); + + if (!test_bit(SERPORT_ACTIVE, &serport->flags)) + return 0; + + return serdev_controller_receive_buf(ctrl, cp, count); +} + +static void ttyport_write_wakeup(struct tty_port *port) +{ + struct serdev_controller *ctrl = port->client_data; + struct serport *serport = serdev_controller_get_drvdata(ctrl); + + if (!test_and_clear_bit(TTY_DO_WRITE_WAKEUP, &port->tty->flags)) + return; + + if (test_bit(SERPORT_ACTIVE, &serport->flags)) + serdev_controller_write_wakeup(ctrl); +} + +static const struct tty_port_client_operations client_ops = { + .receive_buf = ttyport_receive_buf, + .write_wakeup = ttyport_write_wakeup, +}; + +/* + * Callback functions from the serdev core. + */ + +static int ttyport_write_buf(struct serdev_controller *ctrl, const unsigned char *data, size_t len) +{ + struct serport *serport = serdev_controller_get_drvdata(ctrl); + struct tty_struct *tty = serport->tty; + + if (!test_bit(SERPORT_ACTIVE, &serport->flags)) + return 0; + + set_bit(TTY_DO_WRITE_WAKEUP, &tty->flags); + return tty->ops->write(serport->tty, data, len); +} + +static void ttyport_write_flush(struct serdev_controller *ctrl) +{ + struct serport *serport = serdev_controller_get_drvdata(ctrl); + struct tty_struct *tty = serport->tty; + + tty_driver_flush_buffer(tty); +} + +static int ttyport_write_room(struct serdev_controller *ctrl) +{ + struct serport *serport = serdev_controller_get_drvdata(ctrl); + struct tty_struct *tty = serport->tty; + + return tty_write_room(tty); +} + +static int ttyport_open(struct serdev_controller *ctrl) +{ + struct serport *serport = serdev_controller_get_drvdata(ctrl); + struct tty_struct *tty; + struct ktermios ktermios; + + tty = tty_init_dev(serport->tty_drv, serport->tty_idx); + serport->tty = tty; + + serport->port->client_ops = &client_ops; + serport->port->client_data = ctrl; + + if (tty->ops->open) + tty->ops->open(serport->tty, NULL); + else + tty_port_open(serport->port, tty, NULL); + + /* Bring the UART into a known 8 bits no parity hw fc state */ + ktermios = tty->termios; + ktermios.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | + INLCR | IGNCR | ICRNL | IXON); + ktermios.c_oflag &= ~OPOST; + ktermios.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN); + ktermios.c_cflag &= ~(CSIZE | PARENB); + ktermios.c_cflag |= CS8; + ktermios.c_cflag |= CRTSCTS; + tty_set_termios(tty, &ktermios); + + set_bit(SERPORT_ACTIVE, &serport->flags); + + tty_unlock(serport->tty); + return 0; +} + +static void ttyport_close(struct serdev_controller *ctrl) +{ + struct serport *serport = serdev_controller_get_drvdata(ctrl); + struct tty_struct *tty = serport->tty; + + clear_bit(SERPORT_ACTIVE, &serport->flags); + + if (tty->ops->close) + tty->ops->close(tty, NULL); + + tty_release_struct(tty, serport->tty_idx); +} + +static unsigned int ttyport_set_baudrate(struct serdev_controller *ctrl, unsigned int speed) +{ + struct serport *serport = serdev_controller_get_drvdata(ctrl); + struct tty_struct *tty = serport->tty; + struct ktermios ktermios = tty->termios; + + ktermios.c_cflag &= ~CBAUD; + tty_termios_encode_baud_rate(&ktermios, speed, speed); + + /* tty_set_termios() return not checked as it is always 0 */ + tty_set_termios(tty, &ktermios); + return speed; +} + +static void ttyport_set_flow_control(struct serdev_controller *ctrl, bool enable) +{ + struct serport *serport = serdev_controller_get_drvdata(ctrl); + struct tty_struct *tty = serport->tty; + struct ktermios ktermios = tty->termios; + + if (enable) + ktermios.c_cflag |= CRTSCTS; + else + ktermios.c_cflag &= ~CRTSCTS; + + tty_set_termios(tty, &ktermios); +} + +static const struct serdev_controller_ops ctrl_ops = { + .write_buf = ttyport_write_buf, + .write_flush = ttyport_write_flush, + .write_room = ttyport_write_room, + .open = ttyport_open, + .close = ttyport_close, + .set_flow_control = ttyport_set_flow_control, + .set_baudrate = ttyport_set_baudrate, +}; + +struct device *serdev_tty_port_register(struct tty_port *port, + struct device *parent, + struct tty_driver *drv, int idx) +{ + struct serdev_controller *ctrl; + struct serport *serport; + int ret; + + if (!port || !drv || !parent) + return ERR_PTR(-ENODEV); + + ctrl = serdev_controller_alloc(parent, sizeof(struct serport)); + if (!ctrl) + return ERR_PTR(-ENOMEM); + serport = serdev_controller_get_drvdata(ctrl); + + serport->port = port; + serport->tty_idx = idx; + serport->tty_drv = drv; + + ctrl->ops = &ctrl_ops; + + ret = serdev_controller_add(ctrl); + if (ret) + goto err_controller_put; + + dev_info(&ctrl->dev, "tty port %s%d registered\n", drv->name, idx); + return &ctrl->dev; + +err_controller_put: + serdev_controller_put(ctrl); + return ERR_PTR(ret); +} + +void serdev_tty_port_unregister(struct tty_port *port) +{ + struct serdev_controller *ctrl = port->client_data; + struct serport *serport = serdev_controller_get_drvdata(ctrl); + + if (!serport) + return; + + serdev_controller_remove(ctrl); + port->client_ops = NULL; + port->client_data = NULL; + serdev_controller_put(ctrl); +} diff --git a/include/linux/serdev.h b/include/linux/serdev.h index 3ac26c1a8aab..9519da6253a8 100644 --- a/include/linux/serdev.h +++ b/include/linux/serdev.h @@ -238,4 +238,25 @@ static inline int serdev_device_write_room(struct serdev_device *sdev) #endif /* CONFIG_SERIAL_DEV_BUS */ +/* + * serdev hooks into TTY core + */ +struct tty_port; +struct tty_driver; + +#ifdef CONFIG_SERIAL_DEV_CTRL_TTYPORT +struct device *serdev_tty_port_register(struct tty_port *port, + struct device *parent, + struct tty_driver *drv, int idx); +void serdev_tty_port_unregister(struct tty_port *port); +#else +static inline struct device *serdev_tty_port_register(struct tty_port *port, + struct device *parent, + struct tty_driver *drv, int idx) +{ + return ERR_PTR(-ENODEV); +} +static inline void serdev_tty_port_unregister(struct tty_port *port) {} +#endif /* CONFIG_SERIAL_DEV_CTRL_TTYPORT */ + #endif /*_LINUX_SERDEV_H */ -- cgit v1.2.3-59-g8ed1b From 8ee3fde047589dc9c201251f07d0ca1dc776feca Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Thu, 2 Feb 2017 13:48:09 -0600 Subject: tty_port: register tty ports with serdev bus Register a serdev controller with the serdev bus when a tty_port is registered. This creates the serdev controller and create's serdev devices for any DT child nodes of the tty_port's parent (i.e. the UART device). Signed-off-by: Rob Herring Reviewed-By: Sebastian Reichel Tested-By: Sebastian Reichel Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_port.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/tty/tty_port.c b/drivers/tty/tty_port.c index 8d9886b06037..5cd3cd932293 100644 --- a/drivers/tty/tty_port.c +++ b/drivers/tty/tty_port.c @@ -16,6 +16,7 @@ #include #include #include +#include static int tty_port_default_receive_buf(struct tty_port *port, const unsigned char *p, @@ -128,7 +129,15 @@ struct device *tty_port_register_device_attr(struct tty_port *port, struct device *device, void *drvdata, const struct attribute_group **attr_grp) { + struct device *dev; + tty_port_link_device(port, driver, index); + + dev = serdev_tty_port_register(port, device, driver, index); + if (PTR_ERR(dev) != -ENODEV) + /* Skip creating cdev if we registered a serdev device */ + return dev; + return tty_register_device_attr(driver, index, device, drvdata, attr_grp); } @@ -180,6 +189,9 @@ static void tty_port_destructor(struct kref *kref) /* check if last port ref was dropped before tty release */ if (WARN_ON(port->itty)) return; + + serdev_tty_port_unregister(port); + if (port->xmit_buf) free_page((unsigned long)port->xmit_buf); tty_port_destroy(port); -- cgit v1.2.3-59-g8ed1b From 18e8cf159177100e69d528293f8cf6875c0b1bca Mon Sep 17 00:00:00 2001 From: Ulrich Hecht Date: Fri, 3 Feb 2017 11:38:17 +0100 Subject: serial: sh-sci: increase RX FIFO trigger defaults for (H)SCIF Sets reasonable trigger defaults for the various SCIF variants. Also corrects the FIFO size for SH7705-style ports. Signed-off-by: Ulrich Hecht Reviewed-by: Geert Uytterhoeven Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/sh-sci.c | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index 050d028cf2a1..520e344a811d 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -148,6 +148,7 @@ struct sci_port { struct timer_list rx_timer; unsigned int rx_timeout; #endif + int rx_trigger; bool has_rtscts; bool autorts; @@ -450,7 +451,7 @@ static const struct sci_port_params sci_port_params[SCIx_NR_REGTYPES] = { [SCFCR] = { 0x18, 16 }, [SCFDR] = { 0x1c, 16 }, }, - .fifosize = 16, + .fifosize = 64, .overrun_reg = SCxSR, .overrun_mask = SCIFA_ORER, .sampling_rate_mask = SCI_SR(16), @@ -2062,6 +2063,7 @@ static void sci_reset(struct uart_port *port) { const struct plat_sci_reg *reg; unsigned int status; + struct sci_port *s = to_sci_port(port); do { status = serial_port_in(port, SCxSR); @@ -2081,6 +2083,9 @@ static void sci_reset(struct uart_port *port) status &= ~(SCLSR_TO | SCLSR_ORER); serial_port_out(port, SCLSR, status); } + + if (s->rx_trigger > 1) + scif_set_rtrg(port, s->rx_trigger); } static void sci_set_termios(struct uart_port *port, struct ktermios *termios, @@ -2615,6 +2620,28 @@ static int sci_init_single(struct platform_device *dev, if (unlikely(sci_port->params == NULL)) return -EINVAL; + switch (p->type) { + case PORT_SCIFB: + sci_port->rx_trigger = 48; + break; + case PORT_HSCIF: + sci_port->rx_trigger = 64; + break; + case PORT_SCIFA: + sci_port->rx_trigger = 32; + break; + case PORT_SCIF: + if (p->regtype == SCIx_SH7705_SCIF_REGTYPE) + /* RX triggering not implemented for this IP */ + sci_port->rx_trigger = 1; + else + sci_port->rx_trigger = 8; + break; + default: + sci_port->rx_trigger = 1; + break; + } + /* SCIFA on sh7723 and sh7724 need a custom sampling rate that doesn't * match the SoC datasheet, this should be investigated. Let platform * data override the sampling rate for now. -- cgit v1.2.3-59-g8ed1b From 039403765e5da3c6a4c2cc048c201bfad932033a Mon Sep 17 00:00:00 2001 From: Ulrich Hecht Date: Fri, 3 Feb 2017 11:38:18 +0100 Subject: serial: sh-sci: SCIFA/B RX FIFO software timeout Implements support for FIFO fill thresholds greater than one with software timeout. This mechanism is not possible (or at least not useful) on SCIF family hardware other than SCIFA and SCIFB because they do not support turning off the DR hardware timeout interrupt separately from the RI interrupt. Signed-off-by: Ulrich Hecht Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/sh-sci.c | 101 +++++++++++++++++++++++++++++--------------- 1 file changed, 68 insertions(+), 33 deletions(-) diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index 520e344a811d..4a165ed1bc3f 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -148,7 +148,10 @@ struct sci_port { struct timer_list rx_timer; unsigned int rx_timeout; #endif + unsigned int rx_frame; int rx_trigger; + struct timer_list rx_fifo_timer; + int rx_fifo_timeout; bool has_rtscts; bool autorts; @@ -1034,6 +1037,24 @@ static int scif_set_rtrg(struct uart_port *port, int rx_trig) return rx_trig; } +static int scif_rtrg_enabled(struct uart_port *port) +{ + if (sci_getreg(port, HSRTRGR)->size) + return serial_port_in(port, HSRTRGR) != 0; + else + return (serial_port_in(port, SCFCR) & + (SCFCR_RTRG0 | SCFCR_RTRG1)) != 0; +} + +static void rx_fifo_timer_fn(unsigned long arg) +{ + struct sci_port *s = (struct sci_port *)arg; + struct uart_port *port = &s->port; + + dev_dbg(port->dev, "Rx timed out\n"); + scif_set_rtrg(port, 1); +} + #ifdef CONFIG_SERIAL_SH_SCI_DMA static void sci_dma_tx_complete(void *arg) { @@ -1473,10 +1494,10 @@ static inline void sci_free_dma(struct uart_port *port) static irqreturn_t sci_rx_interrupt(int irq, void *ptr) { -#ifdef CONFIG_SERIAL_SH_SCI_DMA struct uart_port *port = ptr; struct sci_port *s = to_sci_port(port); +#ifdef CONFIG_SERIAL_SH_SCI_DMA if (s->chan_rx) { u16 scr = serial_port_in(port, SCSCR); u16 ssr = serial_port_in(port, SCxSR); @@ -1501,6 +1522,14 @@ static irqreturn_t sci_rx_interrupt(int irq, void *ptr) } #endif + if (s->rx_trigger > 1 && s->rx_fifo_timeout > 0) { + if (!scif_rtrg_enabled(port)) + scif_set_rtrg(port, s->rx_trigger); + + mod_timer(&s->rx_fifo_timer, jiffies + DIV_ROUND_UP( + s->rx_frame * s->rx_fifo_timeout, 1000)); + } + /* I think sci_receive_chars has to be called irrespective * of whether the I_IXOFF is set, otherwise, how is the interrupt * to be disabled? @@ -2084,14 +2113,21 @@ static void sci_reset(struct uart_port *port) serial_port_out(port, SCLSR, status); } - if (s->rx_trigger > 1) - scif_set_rtrg(port, s->rx_trigger); + if (s->rx_trigger > 1) { + if (s->rx_fifo_timeout) { + scif_set_rtrg(port, 1); + setup_timer(&s->rx_fifo_timer, rx_fifo_timer_fn, + (unsigned long)s); + } else { + scif_set_rtrg(port, s->rx_trigger); + } + } } static void sci_set_termios(struct uart_port *port, struct ktermios *termios, struct ktermios *old) { - unsigned int baud, smr_val = SCSMR_ASYNC, scr_val = 0, i; + unsigned int baud, smr_val = SCSMR_ASYNC, scr_val = 0, i, bits; unsigned int brr = 255, cks = 0, srr = 15, dl = 0, sccks = 0; unsigned int brr1 = 255, cks1 = 0, srr1 = 15, dl1 = 0; struct sci_port *s = to_sci_port(port); @@ -2287,7 +2323,6 @@ done: udelay(DIV_ROUND_UP(10 * 1000000, baud)); } -#ifdef CONFIG_SERIAL_SH_SCI_DMA /* * Calculate delay for 2 DMA buffers (4 FIFO). * See serial_core.c::uart_update_timeout(). @@ -2298,36 +2333,34 @@ done: * value obtained by this formula is too small. Therefore, if the value * is smaller than 20ms, use 20ms as the timeout value for DMA. */ - if (s->chan_rx) { - unsigned int bits; + /* byte size and parity */ + switch (termios->c_cflag & CSIZE) { + case CS5: + bits = 7; + break; + case CS6: + bits = 8; + break; + case CS7: + bits = 9; + break; + default: + bits = 10; + break; + } - /* byte size and parity */ - switch (termios->c_cflag & CSIZE) { - case CS5: - bits = 7; - break; - case CS6: - bits = 8; - break; - case CS7: - bits = 9; - break; - default: - bits = 10; - break; - } + if (termios->c_cflag & CSTOPB) + bits++; + if (termios->c_cflag & PARENB) + bits++; - if (termios->c_cflag & CSTOPB) - bits++; - if (termios->c_cflag & PARENB) - bits++; - s->rx_timeout = DIV_ROUND_UP((s->buf_len_rx * 2 * bits * HZ) / - (baud / 10), 10); - dev_dbg(port->dev, "DMA Rx t-out %ums, tty t-out %u jiffies\n", - s->rx_timeout * 1000 / HZ, port->timeout); - if (s->rx_timeout < msecs_to_jiffies(20)) - s->rx_timeout = msecs_to_jiffies(20); - } + s->rx_frame = (100 * bits * HZ) / (baud / 10); +#ifdef CONFIG_SERIAL_SH_SCI_DMA + s->rx_timeout = DIV_ROUND_UP(s->buf_len_rx * 2 * s->rx_frame, 1000); + dev_dbg(port->dev, "DMA Rx t-out %ums, tty t-out %u jiffies\n", + s->rx_timeout * 1000 / HZ, port->timeout); + if (s->rx_timeout < msecs_to_jiffies(20)) + s->rx_timeout = msecs_to_jiffies(20); #endif if ((termios->c_cflag & CREAD) != 0) @@ -2642,6 +2675,8 @@ static int sci_init_single(struct platform_device *dev, break; } + sci_port->rx_fifo_timeout = 0; + /* SCIFA on sh7723 and sh7724 need a custom sampling rate that doesn't * match the SoC datasheet, this should be investigated. Let platform * data override the sampling rate for now. -- cgit v1.2.3-59-g8ed1b From 5d23188a473da0b2fe6849ccf03578eebfead30e Mon Sep 17 00:00:00 2001 From: Ulrich Hecht Date: Fri, 3 Feb 2017 11:38:19 +0100 Subject: serial: sh-sci: make RX FIFO parameters tunable via sysfs Allows tuning of the RX FIFO fill threshold and timeout. (The latter is only applicable to SCIFA and SCIFB). Signed-off-by: Ulrich Hecht Reviewed-by: Geert Uytterhoeven Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/sh-sci.c | 87 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index 4a165ed1bc3f..f95a56ca936e 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -1055,6 +1055,66 @@ static void rx_fifo_timer_fn(unsigned long arg) scif_set_rtrg(port, 1); } +static ssize_t rx_trigger_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct uart_port *port = dev_get_drvdata(dev); + struct sci_port *sci = to_sci_port(port); + + return sprintf(buf, "%d\n", sci->rx_trigger); +} + +static ssize_t rx_trigger_store(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t count) +{ + struct uart_port *port = dev_get_drvdata(dev); + struct sci_port *sci = to_sci_port(port); + long r; + + if (kstrtol(buf, 0, &r) == -EINVAL) + return -EINVAL; + sci->rx_trigger = scif_set_rtrg(port, r); + scif_set_rtrg(port, 1); + return count; +} + +static DEVICE_ATTR(rx_fifo_trigger, 0644, rx_trigger_show, rx_trigger_store); + +static ssize_t rx_fifo_timeout_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct uart_port *port = dev_get_drvdata(dev); + struct sci_port *sci = to_sci_port(port); + + return sprintf(buf, "%d\n", sci->rx_fifo_timeout); +} + +static ssize_t rx_fifo_timeout_store(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t count) +{ + struct uart_port *port = dev_get_drvdata(dev); + struct sci_port *sci = to_sci_port(port); + long r; + + if (kstrtol(buf, 0, &r) == -EINVAL) + return -EINVAL; + sci->rx_fifo_timeout = r; + scif_set_rtrg(port, 1); + if (r > 0) + setup_timer(&sci->rx_fifo_timer, rx_fifo_timer_fn, + (unsigned long)sci); + return count; +} + +static DEVICE_ATTR(rx_fifo_timeout, 0644, rx_fifo_timeout_show, rx_fifo_timeout_store); + + #ifdef CONFIG_SERIAL_SH_SCI_DMA static void sci_dma_tx_complete(void *arg) { @@ -2886,6 +2946,15 @@ static int sci_remove(struct platform_device *dev) sci_cleanup_single(port); + if (port->port.fifosize > 1) { + sysfs_remove_file(&dev->dev.kobj, + &dev_attr_rx_fifo_trigger.attr); + } + if (port->port.type == PORT_SCIFA || port->port.type == PORT_SCIFB) { + sysfs_remove_file(&dev->dev.kobj, + &dev_attr_rx_fifo_timeout.attr); + } + return 0; } @@ -3051,6 +3120,24 @@ static int sci_probe(struct platform_device *dev) if (ret) return ret; + if (sp->port.fifosize > 1) { + ret = sysfs_create_file(&dev->dev.kobj, + &dev_attr_rx_fifo_trigger.attr); + if (ret) + return ret; + } + if (sp->port.type == PORT_SCIFA || sp->port.type == PORT_SCIFB) { + ret = sysfs_create_file(&dev->dev.kobj, + &dev_attr_rx_fifo_timeout.attr); + if (ret) { + if (sp->port.fifosize > 1) { + sysfs_remove_file(&dev->dev.kobj, + &dev_attr_rx_fifo_trigger.attr); + } + return ret; + } + } + #ifdef CONFIG_SH_STANDARD_BIOS sh_bios_gdb_detach(); #endif -- cgit v1.2.3-59-g8ed1b From 1c9c858e2ff8ae8024a3d75d2ed080063af43754 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 3 Feb 2017 20:25:00 +0000 Subject: serial: 8250_pci: Add MKS Tenta SCOM-0800 and SCOM-0801 cards The MKS Instruments SCOM-0800 and SCOM-0801 cards (originally by Tenta Technologies) are 3U CompactPCI serial cards with 4 and 8 serial ports, respectively. The first 4 ports are implemented by an OX16PCI954 chip, and the second 4 ports are implemented by an OX16C954 chip on a local bus, bridged by the second PCI function of the OX16PCI954. The ports are jumper-selectable as RS-232 and RS-422/485, and the UARTs use a non-standard oscillator frequency of 20 MHz (base_baud = 1250000). Signed-off-by: Ian Abbott Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_pci.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c index 3eb638c35ba1..0b63109d8750 100644 --- a/drivers/tty/serial/8250/8250_pci.c +++ b/drivers/tty/serial/8250/8250_pci.c @@ -2577,6 +2577,8 @@ enum pci_board_num_t { pbn_b0_4_1152000_200, pbn_b0_8_1152000_200, + pbn_b0_4_1250000, + pbn_b0_2_1843200, pbn_b0_4_1843200, @@ -2799,6 +2801,13 @@ static struct pciserial_board pci_boards[] = { .uart_offset = 0x200, }, + [pbn_b0_4_1250000] = { + .flags = FL_BASE0, + .num_ports = 4, + .base_baud = 1250000, + .uart_offset = 8, + }, + [pbn_b0_2_1843200] = { .flags = FL_BASE0, .num_ports = 2, @@ -5264,6 +5273,10 @@ static struct pci_device_id serial_pci_tbl[] = { { PCI_DEVICE(0x1c29, 0x1108), .driver_data = pbn_fintek_8 }, { PCI_DEVICE(0x1c29, 0x1112), .driver_data = pbn_fintek_12 }, + /* MKS Tenta SCOM-080x serial cards */ + { PCI_DEVICE(0x1601, 0x0800), .driver_data = pbn_b0_4_1250000 }, + { PCI_DEVICE(0x1601, 0xa801), .driver_data = pbn_b0_4_1250000 }, + /* * These entries match devices with class COMMUNICATION_SERIAL, * COMMUNICATION_MODEM or COMMUNICATION_MULTISERIAL -- cgit v1.2.3-59-g8ed1b From 5ab066e5465b2984a45e205f33896b2ec1620c37 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Fri, 3 Feb 2017 10:23:10 +0000 Subject: serial: st-asc: Ignore the parity error bit if 8-bit mode is enabled The datasheet states: "If the MODE field selects an 8-bit frame then this [parity error] bit is undefined. Software should ignore this bit when reading 8-bit frames." Acked-by: Peter Griffin Signed-off-by: Lee Jones Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/st-asc.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/drivers/tty/serial/st-asc.c b/drivers/tty/serial/st-asc.c index 379e5bd37df9..69e62326723d 100644 --- a/drivers/tty/serial/st-asc.c +++ b/drivers/tty/serial/st-asc.c @@ -287,9 +287,19 @@ static void asc_transmit_chars(struct uart_port *port) static void asc_receive_chars(struct uart_port *port) { struct tty_port *tport = &port->state->port; - unsigned long status; + unsigned long status, mode; unsigned long c = 0; char flag; + bool ignore_pe = false; + + /* + * Datasheet states: If the MODE field selects an 8-bit frame then + * this [parity error] bit is undefined. Software should ignore this + * bit when reading 8-bit frames. + */ + mode = asc_in(port, ASC_CTL) & ASC_CTL_MODE_MSK; + if (mode == ASC_CTL_MODE_8BIT || mode == ASC_CTL_MODE_8BIT_PAR) + ignore_pe = true; if (port->irq_wake) pm_wakeup_event(tport->tty->dev, 0); @@ -299,8 +309,8 @@ static void asc_receive_chars(struct uart_port *port) flag = TTY_NORMAL; port->icount.rx++; - if ((c & (ASC_RXBUF_FE | ASC_RXBUF_PE)) || - status & ASC_STA_OE) { + if (status & ASC_STA_OE || c & ASC_RXBUF_FE || + (c & ASC_RXBUF_PE && !ignore_pe)) { if (c & ASC_RXBUF_FE) { if (c == (ASC_RXBUF_FE | ASC_RXBUF_DUMMY_RX)) { -- cgit v1.2.3-59-g8ed1b From a4f6072fe45b2b4a6497c3760a53bba6694c520a Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Fri, 3 Feb 2017 10:23:11 +0000 Subject: serial: st-asc: Provide RTS functionality Until this point, it has not been possible for userland serial applications (e.g. stty) to toggle the UART RTS line. This can be useful with certain configurations. For example, when using a Mezzanine on a Linaro 96board, RTS line is used to take the on-board microcontroller in and out of reset. Acked-by: Peter Griffin Signed-off-by: Lee Jones Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/st-asc.c | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/drivers/tty/serial/st-asc.c b/drivers/tty/serial/st-asc.c index 69e62326723d..397df507579e 100644 --- a/drivers/tty/serial/st-asc.c +++ b/drivers/tty/serial/st-asc.c @@ -30,6 +30,7 @@ #include #include #include +#include #define DRIVER_NAME "st-asc" #define ASC_SERIAL_NAME "ttyAS" @@ -38,6 +39,7 @@ struct asc_port { struct uart_port port; + struct gpio_desc *rts; struct clk *clk; unsigned int hw_flow_control:1; unsigned int force_m1:1; @@ -391,12 +393,27 @@ static unsigned int asc_tx_empty(struct uart_port *port) static void asc_set_mctrl(struct uart_port *port, unsigned int mctrl) { + struct asc_port *ascport = to_asc_port(port); + /* - * This routine is used for seting signals of: DTR, DCD, CTS/RTS - * We use ASC's hardware for CTS/RTS, so don't need any for that. - * Some boards have DTR and DCD implemented using PIO pins, - * code to do this should be hooked in here. + * This routine is used for seting signals of: DTR, DCD, CTS and RTS. + * We use ASC's hardware for CTS/RTS when hardware flow-control is + * enabled, however if the RTS line is required for another purpose, + * commonly controlled using HUP from userspace, then we need to toggle + * it manually, using GPIO. + * + * Some boards also have DTR and DCD implemented using PIO pins, code to + * do this should be hooked in here. */ + + if (!ascport->rts) + return; + + /* If HW flow-control is enabled, we can't fiddle with the RTS line */ + if (asc_in(port, ASC_CTL) & ASC_CTL_CTSENABLE) + return; + + gpiod_set_value(ascport->rts, mctrl & TIOCM_RTS); } static unsigned int asc_get_mctrl(struct uart_port *port) @@ -726,6 +743,8 @@ static struct asc_port *asc_of_get_asc_port(struct platform_device *pdev) "st,hw-flow-control"); asc_ports[id].force_m1 = of_property_read_bool(np, "st,force_m1"); asc_ports[id].port.line = id; + asc_ports[id].rts = NULL; + return &asc_ports[id]; } -- cgit v1.2.3-59-g8ed1b From 6929cb00a5017633aa54c6a9071cc0abfd573b47 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Fri, 3 Feb 2017 10:23:12 +0000 Subject: serial: st-asc: Read in all Pinctrl states There are now 2 possible separate/different Pinctrl states which can be provided from platform data. One which encompasses the lines required for HW flow-control (CTS/RTS) and another which does not specify these lines, such that they can be used via GPIO mechanisms for manually toggling (i.e. from a request by `stty`). Acked-by: Peter Griffin Signed-off-by: Lee Jones Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/st-asc.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/drivers/tty/serial/st-asc.c b/drivers/tty/serial/st-asc.c index 397df507579e..105802099e47 100644 --- a/drivers/tty/serial/st-asc.c +++ b/drivers/tty/serial/st-asc.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -37,10 +38,16 @@ #define ASC_FIFO_SIZE 16 #define ASC_MAX_PORTS 8 +/* Pinctrl states */ +#define DEFAULT 0 +#define NO_HW_FLOWCTRL 1 + struct asc_port { struct uart_port port; struct gpio_desc *rts; struct clk *clk; + struct pinctrl *pinctrl; + struct pinctrl_state *states[2]; unsigned int hw_flow_control:1; unsigned int force_m1:1; }; @@ -694,6 +701,7 @@ static int asc_init_port(struct asc_port *ascport, { struct uart_port *port = &ascport->port; struct resource *res; + int ret; port->iotype = UPIO_MEM; port->flags = UPF_BOOT_AUTOCONF; @@ -720,6 +728,27 @@ static int asc_init_port(struct asc_port *ascport, WARN_ON(ascport->port.uartclk == 0); clk_disable_unprepare(ascport->clk); + ascport->pinctrl = devm_pinctrl_get(&pdev->dev); + if (IS_ERR(ascport->pinctrl)) { + ret = PTR_ERR(ascport->pinctrl); + dev_err(&pdev->dev, "Failed to get Pinctrl: %d\n", ret); + } + + ascport->states[DEFAULT] = + pinctrl_lookup_state(ascport->pinctrl, "default"); + if (IS_ERR(ascport->states[DEFAULT])) { + ret = PTR_ERR(ascport->states[DEFAULT]); + dev_err(&pdev->dev, + "Failed to look up Pinctrl state 'default': %d\n", ret); + return ret; + } + + /* "no-hw-flowctrl" state is optional */ + ascport->states[NO_HW_FLOWCTRL] = + pinctrl_lookup_state(ascport->pinctrl, "no-hw-flowctrl"); + if (IS_ERR(ascport->states[NO_HW_FLOWCTRL])) + ascport->states[NO_HW_FLOWCTRL] = NULL; + return 0; } -- cgit v1.2.3-59-g8ed1b From d7356256488c544b8fdc2c3a775ce069546d7933 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Fri, 3 Feb 2017 10:23:13 +0000 Subject: serial: st-asc: (De)Register GPIOD and swap Pinctrl profiles When hardware flow-control is disabled, manual toggling of the UART's reset line (RTS) using userland applications (e.g. stty) is not possible, since the ASC IP does not provide this functionality in the same was as some other IPs do. Thus, we have to do this manually. This patch ensures that when HW flow-control is disabled the RTS/CTS lines are free to be registered via the GPIO API. It also ensures any registered GPIO lines are unregistered when HW flow-control is requested, allowing the IP to control them automatically. Acked-by: Peter Griffin Signed-off-by: Lee Jones Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/st-asc.c | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/drivers/tty/serial/st-asc.c b/drivers/tty/serial/st-asc.c index 105802099e47..e521078572b5 100644 --- a/drivers/tty/serial/st-asc.c +++ b/drivers/tty/serial/st-asc.c @@ -513,6 +513,8 @@ static void asc_set_termios(struct uart_port *port, struct ktermios *termios, struct ktermios *old) { struct asc_port *ascport = to_asc_port(port); + struct device_node *np = port->dev->of_node; + struct gpio_desc *gpiod; unsigned int baud; u32 ctrl_val; tcflag_t cflag; @@ -556,9 +558,32 @@ static void asc_set_termios(struct uart_port *port, struct ktermios *termios, ctrl_val |= ASC_CTL_PARITYODD; /* hardware flow control */ - if ((cflag & CRTSCTS)) + if ((cflag & CRTSCTS)) { ctrl_val |= ASC_CTL_CTSENABLE; + /* If flow-control selected, stop handling RTS manually */ + if (ascport->rts) { + devm_gpiod_put(port->dev, ascport->rts); + ascport->rts = NULL; + + pinctrl_select_state(ascport->pinctrl, + ascport->states[DEFAULT]); + } + } else { + /* If flow-control disabled, it's safe to handle RTS manually */ + if (!ascport->rts && ascport->states[NO_HW_FLOWCTRL]) { + pinctrl_select_state(ascport->pinctrl, + ascport->states[NO_HW_FLOWCTRL]); + + gpiod = devm_get_gpiod_from_child(port->dev, "rts", + &np->fwnode); + if (!IS_ERR(gpiod)) { + gpiod_direction_output(gpiod, 0); + ascport->rts = gpiod; + } + } + } + if ((baud < 19200) && !ascport->force_m1) { asc_out(port, ASC_BAUDRATE, (port->uartclk / (16 * baud))); } else { -- cgit v1.2.3-59-g8ed1b From 233680a2b0da689719bf38e45d86c69e192e567c Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Fri, 3 Feb 2017 10:23:14 +0000 Subject: serial: st-asc: Use generic DT binding for announcing RTS/CTS lines The initial binding 'st,hw-flow-control' isn't used anywhere, in neither in upstream nor downstream kernels. It isn't even documented in dt-bindings, so we can safely assume it's safe to swap to the generic one. Acked-by: Peter Griffin Signed-off-by: Lee Jones Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/st-asc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/serial/st-asc.c b/drivers/tty/serial/st-asc.c index e521078572b5..bcf1d33e6ffe 100644 --- a/drivers/tty/serial/st-asc.c +++ b/drivers/tty/serial/st-asc.c @@ -794,7 +794,7 @@ static struct asc_port *asc_of_get_asc_port(struct platform_device *pdev) return NULL; asc_ports[id].hw_flow_control = of_property_read_bool(np, - "st,hw-flow-control"); + "uart-has-rtscts"); asc_ports[id].force_m1 = of_property_read_bool(np, "st,force_m1"); asc_ports[id].port.line = id; asc_ports[id].rts = NULL; -- cgit v1.2.3-59-g8ed1b From 8ab99f59f42d0e70a853a10120828ab66bd734b1 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Fri, 3 Feb 2017 10:23:15 +0000 Subject: dt-bindings: serial: Update 'uart-has-rtscts' description 'uart-has-rtscts' property and 'rts-gpios|cts-gpios' are normally mutually exclusive, however it is possible for some drivers to have a dynamic approach, meaning that both properties can be relevant. Acked-by: Peter Griffin Signed-off-by: Lee Jones Signed-off-by: Greg Kroah-Hartman --- Documentation/devicetree/bindings/serial/serial.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/serial/serial.txt b/Documentation/devicetree/bindings/serial/serial.txt index fd970f76a7b8..b542a0ecf06e 100644 --- a/Documentation/devicetree/bindings/serial/serial.txt +++ b/Documentation/devicetree/bindings/serial/serial.txt @@ -23,7 +23,8 @@ Optional properties: they are available for use (wired and enabled by pinmux configuration). This depends on both the UART hardware and the board wiring. Note that this property is mutually-exclusive with "cts-gpios" and - "rts-gpios" above. + "rts-gpios" above, unless support is provided to switch between modes + dynamically. Examples: -- cgit v1.2.3-59-g8ed1b From 105fc00bc388d2dff089f3330fc7d9b009c519dc Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Fri, 3 Feb 2017 10:23:16 +0000 Subject: ARM: dts: STiH410-b2260: Identify the UART RTS line When hardware flow-control is disabled, manual toggling of the UART's reset line (RTS) using userland applications (e.g. stty) is not possible, since the ASC IP does not provide this functionality in the same was as some other IPs do. Thus, we have to do this manually. This patch configures the UART RTS line as a GPIO for manipulation within the UART driver when HW flow-control is not enabled. Acked-by: Peter Griffin Signed-off-by: Lee Jones Signed-off-by: Greg Kroah-Hartman --- arch/arm/boot/dts/stih410-b2260.dts | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/boot/dts/stih410-b2260.dts b/arch/arm/boot/dts/stih410-b2260.dts index 06b0696cb6b8..fa16abac0e4d 100644 --- a/arch/arm/boot/dts/stih410-b2260.dts +++ b/arch/arm/boot/dts/stih410-b2260.dts @@ -63,6 +63,7 @@ uart0: serial@9830000 { label = "LS-UART0"; status = "okay"; + rts-gpios = <&pio17 3 GPIO_ACTIVE_LOW>; }; /* Low speed expansion connector */ -- cgit v1.2.3-59-g8ed1b From 34224a0c1941715b6e0f7daf7b146aca5815aabb Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Fri, 3 Feb 2017 10:23:17 +0000 Subject: ARM: dts: STiH407-pinctrl: Add Pinctrl group for HW flow-control Each serial port which supports HW flow-control should have 2 Pinctrl groups. One for when HW flow-control is in progress, where the IP will take over controlling the lines and another group which enables the lines to be toggled using GPIO mechanisms. Acked-by: Peter Griffin Signed-off-by: Lee Jones Signed-off-by: Greg Kroah-Hartman --- arch/arm/boot/dts/stih407-pinctrl.dtsi | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/arch/arm/boot/dts/stih407-pinctrl.dtsi b/arch/arm/boot/dts/stih407-pinctrl.dtsi index daab16b5ae64..bd1a82e8fffe 100644 --- a/arch/arm/boot/dts/stih407-pinctrl.dtsi +++ b/arch/arm/boot/dts/stih407-pinctrl.dtsi @@ -465,8 +465,16 @@ serial0 { pinctrl_serial0: serial0-0 { st,pins { - tx = <&pio17 0 ALT1 OUT>; - rx = <&pio17 1 ALT1 IN>; + tx = <&pio17 0 ALT1 OUT>; + rx = <&pio17 1 ALT1 IN>; + }; + }; + pinctrl_serial0_hw_flowctrl: serial0-0_hw_flowctrl { + st,pins { + tx = <&pio17 0 ALT1 OUT>; + rx = <&pio17 1 ALT1 IN>; + cts = <&pio17 2 ALT1 IN>; + rts = <&pio17 3 ALT1 OUT>; }; }; }; -- cgit v1.2.3-59-g8ed1b From cf38e1a60ea99a81ec479e8f995c63b1d19d1f6a Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Fri, 3 Feb 2017 10:23:18 +0000 Subject: ARM: dts: STiH407-family: Use new Pinctrl groups Having just defined some new Pinctrl groups for when HW flow-control is {en,dis}abled, let's reference them for use within the driver. Acked-by: Peter Griffin Signed-off-by: Lee Jones Signed-off-by: Greg Kroah-Hartman --- arch/arm/boot/dts/stih407-family.dtsi | 3 +-- arch/arm/boot/dts/stih410-b2260.dts | 5 ++++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/arch/arm/boot/dts/stih407-family.dtsi b/arch/arm/boot/dts/stih407-family.dtsi index c8b2944e304a..e480e329aaa4 100644 --- a/arch/arm/boot/dts/stih407-family.dtsi +++ b/arch/arm/boot/dts/stih407-family.dtsi @@ -222,9 +222,8 @@ compatible = "st,asc"; reg = <0x9830000 0x2c>; interrupts = ; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_serial0>; clocks = <&clk_s_c0_flexgen CLK_EXT2F_A9>; + /* Pinctrl moved out to a per-board configuration */ status = "disabled"; }; diff --git a/arch/arm/boot/dts/stih410-b2260.dts b/arch/arm/boot/dts/stih410-b2260.dts index fa16abac0e4d..cbcbcb4c6e4f 100644 --- a/arch/arm/boot/dts/stih410-b2260.dts +++ b/arch/arm/boot/dts/stih410-b2260.dts @@ -62,8 +62,11 @@ /* Low speed expansion connector */ uart0: serial@9830000 { label = "LS-UART0"; - status = "okay"; + pinctrl-names = "default", "no-hw-flowctrl"; + pinctrl-0 = <&pinctrl_serial0_hw_flowctrl>; + pinctrl-1 = <&pinctrl_serial0>; rts-gpios = <&pio17 3 GPIO_ACTIVE_LOW>; + status = "okay"; }; /* Low speed expansion connector */ -- cgit v1.2.3-59-g8ed1b From 36523b6830fa468ae9e0335601aed475480b7dd3 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Fri, 3 Feb 2017 10:23:19 +0000 Subject: ARM: dts: STiH410-b2260: Enable HW flow-control Hardware flow-control capability must be specified at a platform level in order to inform the ASC driver that the platform is capable (i.e. are the lines wired up, etc). STiH4{07,10} devices are indeed capable, so let's provide the property. Acked-by: Peter Griffin Signed-off-by: Lee Jones Signed-off-by: Greg Kroah-Hartman --- arch/arm/boot/dts/stih410-b2260.dts | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/boot/dts/stih410-b2260.dts b/arch/arm/boot/dts/stih410-b2260.dts index cbcbcb4c6e4f..93c14d183e29 100644 --- a/arch/arm/boot/dts/stih410-b2260.dts +++ b/arch/arm/boot/dts/stih410-b2260.dts @@ -66,6 +66,7 @@ pinctrl-0 = <&pinctrl_serial0_hw_flowctrl>; pinctrl-1 = <&pinctrl_serial0>; rts-gpios = <&pio17 3 GPIO_ACTIVE_LOW>; + uart-has-rtscts; status = "okay"; }; -- cgit v1.2.3-59-g8ed1b From 80cd94e759fd3d7b9fb1a95fa41e2c23e557a525 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Sun, 5 Feb 2017 16:12:34 +0000 Subject: serial: 8250_pci: make pciserial_detach_ports() static Fixes the following sparse warning: drivers/tty/serial/8250/8250_pci.c:3916:6: warning: symbol 'pciserial_detach_ports' was not declared. Should it be static? Signed-off-by: Wei Yongjun Reviewed-by: Andy Shevchenko Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_pci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c index 0b63109d8750..2c83fd54b36c 100644 --- a/drivers/tty/serial/8250/8250_pci.c +++ b/drivers/tty/serial/8250/8250_pci.c @@ -3695,7 +3695,7 @@ err_out: } EXPORT_SYMBOL_GPL(pciserial_init_ports); -void pciserial_detach_ports(struct serial_private *priv) +static void pciserial_detach_ports(struct serial_private *priv) { struct pci_serial_quirk *quirk; int i; -- cgit v1.2.3-59-g8ed1b From 10d258c51869916347adce4312e6fe41fa5144ad Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 8 Feb 2017 10:23:24 +0300 Subject: serdev: ttyport: check whether tty_init_dev() fails My static checker complains that we don't have any error handling here. It's simple enough to add it. Fixes: bed35c6dfa6a ("serdev: add a tty port controller driver") Signed-off-by: Dan Carpenter Acked-by: Rob Herring Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serdev/serdev-ttyport.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/tty/serdev/serdev-ttyport.c b/drivers/tty/serdev/serdev-ttyport.c index 683320b81a2b..d05393594f15 100644 --- a/drivers/tty/serdev/serdev-ttyport.c +++ b/drivers/tty/serdev/serdev-ttyport.c @@ -97,6 +97,8 @@ static int ttyport_open(struct serdev_controller *ctrl) struct ktermios ktermios; tty = tty_init_dev(serport->tty_drv, serport->tty_idx); + if (IS_ERR(tty)) + return PTR_ERR(tty); serport->tty = tty; serport->port->client_ops = &client_ops; -- cgit v1.2.3-59-g8ed1b From 424d79183af07fbcb8059f9e86efc9ff8b346c75 Mon Sep 17 00:00:00 2001 From: Douglas Anderson Date: Mon, 6 Feb 2017 15:30:00 -0800 Subject: serial: 8250_dw: Avoid "too much work" from bogus rx timeout interrupt On a Rockchip rk3399-based board during suspend/resume testing, we found that we could get the console UART into a state where it would print this to the console a lot: serial8250: too much work for irq42 Followed eventually by: NMI watchdog: BUG: soft lockup - CPU#0 stuck for 11s! Upon debugging I found that we're in this state: iir = 0x000000cc lsr = 0x00000060 It appears that somehow we have a RX Timeout interrupt but there is no actual data present to receive. When we're in this state the UART driver claims that it handled the interrupt but it actually doesn't really do anything. This means that we keep getting the interrupt over and over again. Normally we don't actually need to do anything special to handle a RX Timeout interrupt. We'll notice that there is some data ready and we'll read it, which will end up clearing the RX Timeout. In this case we have a problem specifically because we got the RX TImeout without any data. Reading a bogus byte is confirmed to get us out of this state. It's unclear how exactly the UART got into this state, but it is known that the UART lines are essentially undriven and unpowered during suspend, so possibly during resume some garbage / half transmitted bits are seen on the line and put the UART into this state. The UART on the rk3399 is a DesignWare based 8250 UART. From mailing list posts, it appears that other people have run into similar problems with DesignWare based IP. Presumably this problem is unique to that IP, so I have placed the workaround there to avoid possibly of accidentally triggering bad behavior on other IP. Also note the RX Timeout behaves very differently in the DMA case, for for now the workaround is only applied to the non-DMA case. Signed-off-by: Douglas Anderson Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_dw.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/drivers/tty/serial/8250/8250_dw.c b/drivers/tty/serial/8250/8250_dw.c index c89ae4581378..6ee55a2d47bb 100644 --- a/drivers/tty/serial/8250/8250_dw.c +++ b/drivers/tty/serial/8250/8250_dw.c @@ -201,8 +201,31 @@ static unsigned int dw8250_serial_in32be(struct uart_port *p, int offset) static int dw8250_handle_irq(struct uart_port *p) { + struct uart_8250_port *up = up_to_u8250p(p); struct dw8250_data *d = p->private_data; unsigned int iir = p->serial_in(p, UART_IIR); + unsigned int status; + unsigned long flags; + + /* + * There are ways to get Designware-based UARTs into a state where + * they are asserting UART_IIR_RX_TIMEOUT but there is no actual + * data available. If we see such a case then we'll do a bogus + * read. If we don't do this then the "RX TIMEOUT" interrupt will + * fire forever. + * + * This problem has only been observed so far when not in DMA mode + * so we limit the workaround only to non-DMA mode. + */ + if (!up->dma && ((iir & 0x3f) == UART_IIR_RX_TIMEOUT)) { + spin_lock_irqsave(&p->lock, flags); + status = p->serial_in(p, UART_LSR); + + if (!(status & (UART_LSR_DR | UART_LSR_BI))) + (void) p->serial_in(p, UART_RX); + + spin_unlock_irqrestore(&p->lock, flags); + } if (serial8250_handle_irq(p, iir)) return 1; -- cgit v1.2.3-59-g8ed1b From 6a5f0e2f9352accf857f683518bd3cc6ef6ae6c6 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Fri, 3 Feb 2017 23:53:16 +0100 Subject: tty/serial: atmel: ensure state is restored after suspending When going to suspend, the UART registers may be lost because the power to VDDcore is cut. This is not an issue in the normal case but when no_console_suspend is used, we need to restore the registers in order to get a functional console. Signed-off-by: Alexandre Belloni Reviewed-by: Nicolas Ferre Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/atmel_serial.c | 44 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c index fabbe76203bb..8d2cec0f03c2 100644 --- a/drivers/tty/serial/atmel_serial.c +++ b/drivers/tty/serial/atmel_serial.c @@ -175,6 +175,17 @@ struct atmel_uart_port { unsigned int pending_status; spinlock_t lock_suspended; + struct { + u32 cr; + u32 mr; + u32 imr; + u32 brgr; + u32 rtor; + u32 ttgr; + u32 fmr; + u32 fimr; + } cache; + int (*prepare_rx)(struct uart_port *port); int (*prepare_tx)(struct uart_port *port); void (*schedule_rx)(struct uart_port *port); @@ -2659,6 +2670,20 @@ static int atmel_serial_suspend(struct platform_device *pdev, cpu_relax(); } + if (atmel_is_console_port(port) && !console_suspend_enabled) { + /* Cache register values as we won't get a full shutdown/startup + * cycle + */ + atmel_port->cache.mr = atmel_uart_readl(port, ATMEL_US_MR); + atmel_port->cache.imr = atmel_uart_readl(port, ATMEL_US_IMR); + atmel_port->cache.brgr = atmel_uart_readl(port, ATMEL_US_BRGR); + atmel_port->cache.rtor = atmel_uart_readl(port, + atmel_port->rtor); + atmel_port->cache.ttgr = atmel_uart_readl(port, ATMEL_US_TTGR); + atmel_port->cache.fmr = atmel_uart_readl(port, ATMEL_US_FMR); + atmel_port->cache.fimr = atmel_uart_readl(port, ATMEL_US_FIMR); + } + /* we can not wake up if we're running on slow clock */ atmel_port->may_wakeup = device_may_wakeup(&pdev->dev); if (atmel_serial_clk_will_stop()) { @@ -2681,6 +2706,25 @@ static int atmel_serial_resume(struct platform_device *pdev) struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); unsigned long flags; + if (atmel_is_console_port(port) && !console_suspend_enabled) { + atmel_uart_writel(port, ATMEL_US_MR, atmel_port->cache.mr); + atmel_uart_writel(port, ATMEL_US_IER, atmel_port->cache.imr); + atmel_uart_writel(port, ATMEL_US_BRGR, atmel_port->cache.brgr); + atmel_uart_writel(port, atmel_port->rtor, + atmel_port->cache.rtor); + atmel_uart_writel(port, ATMEL_US_TTGR, atmel_port->cache.ttgr); + + if (atmel_port->fifo_size) { + atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_FIFOEN | + ATMEL_US_RXFCLR | ATMEL_US_TXFLCLR); + atmel_uart_writel(port, ATMEL_US_FMR, + atmel_port->cache.fmr); + atmel_uart_writel(port, ATMEL_US_FIER, + atmel_port->cache.fimr); + } + atmel_start_rx(port); + } + spin_lock_irqsave(&atmel_port->lock_suspended, flags); if (atmel_port->pending) { atmel_handle_receive(port, atmel_port->pending); -- cgit v1.2.3-59-g8ed1b From 90afa5255f5c5ae67c869918e4c5f60b8580db70 Mon Sep 17 00:00:00 2001 From: Ulrich Hecht Date: Wed, 8 Feb 2017 18:31:14 +0100 Subject: serial: sh-sci: fix hardware RX trigger level setting 1. Do not set the RX trigger level for software timeout devices on reset; there is no timeout by default, and data will rot. 2. Do set the RX trigger level for hardware timeout devices when set via sysfs attribute. Fixes SCIFA-type serial consoles. Signed-off-by: Ulrich Hecht Tested-by: Geert Uytterhoeven Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/sh-sci.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index f95a56ca936e..9a47cc4f16a2 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -1076,8 +1076,11 @@ static ssize_t rx_trigger_store(struct device *dev, if (kstrtol(buf, 0, &r) == -EINVAL) return -EINVAL; + sci->rx_trigger = scif_set_rtrg(port, r); - scif_set_rtrg(port, 1); + if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) + scif_set_rtrg(port, 1); + return count; } @@ -2179,7 +2182,11 @@ static void sci_reset(struct uart_port *port) setup_timer(&s->rx_fifo_timer, rx_fifo_timer_fn, (unsigned long)s); } else { - scif_set_rtrg(port, s->rx_trigger); + if (port->type == PORT_SCIFA || + port->type == PORT_SCIFB) + scif_set_rtrg(port, 1); + else + scif_set_rtrg(port, s->rx_trigger); } } } -- cgit v1.2.3-59-g8ed1b From 24572af4fb6ce0726dbe12b0286de11d25ff008b Mon Sep 17 00:00:00 2001 From: Jan Kiszka Date: Wed, 8 Feb 2017 17:09:03 +0100 Subject: serial: exar: Fix mapping of port I/O resources pcim_iomap_table only returns the table of mapping, it does not perform them. For that, we need to call pcim_iomap, but only if that mapping was not done before. Fixes: d0aeaa83f0b0 ("serial: exar: split out the exar code from 8250_pci") Signed-off-by: Jan Kiszka Reviewed-by: Andy Shevchenko Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_exar.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/tty/serial/8250/8250_exar.c b/drivers/tty/serial/8250/8250_exar.c index e6b44a75a5e0..58469d9d6515 100644 --- a/drivers/tty/serial/8250/8250_exar.c +++ b/drivers/tty/serial/8250/8250_exar.c @@ -72,6 +72,9 @@ static int default_setup(struct exar8250 *priv, struct pci_dev *pcidev, const struct exar8250_board *board = priv->board; unsigned int bar = 0; + if (!pcim_iomap_table(pcidev)[bar] && !pcim_iomap(pcidev, bar, 0)) + return -ENOMEM; + port->port.iotype = UPIO_MEM; port->port.mapbase = pci_resource_start(pcidev, bar) + offset; port->port.membase = pcim_iomap_table(pcidev)[bar] + offset; -- cgit v1.2.3-59-g8ed1b From 5b5f252d67afd7bd5b923c664206d60800bf5054 Mon Sep 17 00:00:00 2001 From: Jan Kiszka Date: Wed, 8 Feb 2017 17:09:04 +0100 Subject: serial: exar: Fix initialization of EXAR registers for ports > 0 So far, pci_xr17v35x_setup always initialized 8XMODE, FCTR & Co. for port 0 because it used the address of that port instead of moving the pointer according to the port number. Fix this and remove the unneeded temporary ioremap by moving default_setup up and reusing the membase it fills into the port structure. Fixes: 14faa8cce88e ("tty/8250 Add support for Commtech's Fastcom Async-335 and Fastcom Async-PCIe cards") Signed-off-by: Jan Kiszka Reviewed-by: Andy Shevchenko Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_exar.c | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/drivers/tty/serial/8250/8250_exar.c b/drivers/tty/serial/8250/8250_exar.c index 58469d9d6515..f489f25643c5 100644 --- a/drivers/tty/serial/8250/8250_exar.c +++ b/drivers/tty/serial/8250/8250_exar.c @@ -157,27 +157,23 @@ pci_xr17v35x_setup(struct exar8250 *priv, struct pci_dev *pcidev, if (board->has_slave && idx >= 8) port->port.uartclk /= 2; - p = pci_ioremap_bar(pcidev, 0); - if (!p) - return -ENOMEM; + ret = default_setup(priv, pcidev, idx, offset, port); + if (ret) + return ret; - /* Setup Multipurpose Input/Output pins. */ - if (idx == 0) - setup_gpio(p); + p = port->port.membase; writeb(0x00, p + UART_EXAR_8XMODE); writeb(UART_FCTR_EXAR_TRGD, p + UART_EXAR_FCTR); writeb(128, p + UART_EXAR_TXTRG); writeb(128, p + UART_EXAR_RXTRG); - iounmap(p); - ret = default_setup(priv, pcidev, idx, offset, port); - if (ret) - return ret; + if (idx == 0) { + /* Setup Multipurpose Input/Output pins. */ + setup_gpio(p); - if (idx == 0) - port->port.private_data = - xr17v35x_register_gpio(pcidev); + port->port.private_data = xr17v35x_register_gpio(pcidev); + } return 0; } -- cgit v1.2.3-59-g8ed1b From 7795753661f1a9423c3c8fbde322f6a2a8b94b68 Mon Sep 17 00:00:00 2001 From: Jan Kiszka Date: Wed, 8 Feb 2017 17:09:05 +0100 Subject: serial: exar: Fix feature control register constants According to the XR17V352 manual, bit 4 is IrDA control and bit 5 for 485. Fortunately, no driver used them so far. Signed-off-by: Jan Kiszka Reviewed-by: Andy Shevchenko Signed-off-by: Greg Kroah-Hartman --- include/uapi/linux/serial_reg.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/uapi/linux/serial_reg.h b/include/uapi/linux/serial_reg.h index 274d8fc206e3..25b93a764a1a 100644 --- a/include/uapi/linux/serial_reg.h +++ b/include/uapi/linux/serial_reg.h @@ -374,8 +374,8 @@ #define UART_EXAR_DVID 0x8d /* Device identification */ #define UART_EXAR_FCTR 0x08 /* Feature Control Register */ -#define UART_FCTR_EXAR_IRDA 0x08 /* IrDa data encode select */ -#define UART_FCTR_EXAR_485 0x10 /* Auto 485 half duplex dir ctl */ +#define UART_FCTR_EXAR_IRDA 0x10 /* IrDa data encode select */ +#define UART_FCTR_EXAR_485 0x20 /* Auto 485 half duplex dir ctl */ #define UART_FCTR_EXAR_TRGA 0x00 /* FIFO trigger table A */ #define UART_FCTR_EXAR_TRGB 0x60 /* FIFO trigger table B */ #define UART_FCTR_EXAR_TRGC 0x80 /* FIFO trigger table C */ -- cgit v1.2.3-59-g8ed1b From fc6cc9615779183f07d6ff4065368a732d09f49e Mon Sep 17 00:00:00 2001 From: Jan Kiszka Date: Wed, 8 Feb 2017 17:09:06 +0100 Subject: serial: exar: Move Commtech adapters to 8250_exar as well Those are Exar-based, too. With the required refactoring of the code to fit into 8250_exar, we automatically fix the same issue pci_xr17v35x_setup had before: 8XMODE, FCTL, TXTRG and RXTRG were always only set for port 0. Now they are initialized for the correct target port by using port.membase. Now we can also cleanly fix the blacklist of 8250_pci so that all Commtech devices are rejected and 8250_exar can handle them. Signed-off-by: Jan Kiszka Reviewed-by: Andy Shevchenko Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_exar.c | 83 +++++++++++++++++++-- drivers/tty/serial/8250/8250_pci.c | 139 +----------------------------------- 2 files changed, 79 insertions(+), 143 deletions(-) diff --git a/drivers/tty/serial/8250/8250_exar.c b/drivers/tty/serial/8250/8250_exar.c index f489f25643c5..9af4266eff96 100644 --- a/drivers/tty/serial/8250/8250_exar.c +++ b/drivers/tty/serial/8250/8250_exar.c @@ -24,11 +24,15 @@ #include "8250.h" -#define PCI_DEVICE_ID_COMMTECH_4224PCIE 0x0020 -#define PCI_DEVICE_ID_COMMTECH_4228PCIE 0x0021 -#define PCI_DEVICE_ID_COMMTECH_4222PCIE 0x0022 -#define PCI_DEVICE_ID_EXAR_XR17V4358 0x4358 -#define PCI_DEVICE_ID_EXAR_XR17V8358 0x8358 +#define PCI_DEVICE_ID_COMMTECH_4224PCI335 0x0002 +#define PCI_DEVICE_ID_COMMTECH_4222PCI335 0x0004 +#define PCI_DEVICE_ID_COMMTECH_2324PCI335 0x000a +#define PCI_DEVICE_ID_COMMTECH_2328PCI335 0x000b +#define PCI_DEVICE_ID_COMMTECH_4224PCIE 0x0020 +#define PCI_DEVICE_ID_COMMTECH_4228PCIE 0x0021 +#define PCI_DEVICE_ID_COMMTECH_4222PCIE 0x0022 +#define PCI_DEVICE_ID_EXAR_XR17V4358 0x4358 +#define PCI_DEVICE_ID_EXAR_XR17V8358 0x8358 #define UART_EXAR_MPIOINT_7_0 0x8f /* MPIOINT[7:0] */ #define UART_EXAR_MPIOLVL_7_0 0x90 /* MPIOLVL[7:0] */ @@ -83,6 +87,55 @@ static int default_setup(struct exar8250 *priv, struct pci_dev *pcidev, return 0; } +static int +pci_fastcom335_setup(struct exar8250 *priv, struct pci_dev *pcidev, + struct uart_8250_port *port, int idx) +{ + unsigned int offset = idx * 0x200; + unsigned int baud = 1843200; + u8 __iomem *p; + int err; + + port->port.flags |= UPF_EXAR_EFR; + port->port.uartclk = baud * 16; + + err = default_setup(priv, pcidev, idx, offset, port); + if (err) + return err; + + p = port->port.membase; + + writeb(0x00, p + UART_EXAR_8XMODE); + writeb(UART_FCTR_EXAR_TRGD, p + UART_EXAR_FCTR); + writeb(32, p + UART_EXAR_TXTRG); + writeb(32, p + UART_EXAR_RXTRG); + + /* + * Setup Multipurpose Input/Output pins. + */ + if (idx == 0) { + switch (pcidev->device) { + case PCI_DEVICE_ID_COMMTECH_4222PCI335: + case PCI_DEVICE_ID_COMMTECH_4224PCI335: + writeb(0x78, p + UART_EXAR_MPIOLVL_7_0); + writeb(0x00, p + UART_EXAR_MPIOINV_7_0); + writeb(0x00, p + UART_EXAR_MPIOSEL_7_0); + break; + case PCI_DEVICE_ID_COMMTECH_2324PCI335: + case PCI_DEVICE_ID_COMMTECH_2328PCI335: + writeb(0x00, p + UART_EXAR_MPIOLVL_7_0); + writeb(0xc0, p + UART_EXAR_MPIOINV_7_0); + writeb(0xc0, p + UART_EXAR_MPIOSEL_7_0); + break; + } + writeb(0x00, p + UART_EXAR_MPIOINT_7_0); + writeb(0x00, p + UART_EXAR_MPIO3T_7_0); + writeb(0x00, p + UART_EXAR_MPIOOD_7_0); + } + + return 0; +} + static int pci_connect_tech_setup(struct exar8250 *priv, struct pci_dev *pcidev, struct uart_8250_port *port, int idx) @@ -291,6 +344,21 @@ static int __maybe_unused exar_resume(struct device *dev) static SIMPLE_DEV_PM_OPS(exar_pci_pm, exar_suspend, exar_resume); +static const struct exar8250_board pbn_fastcom335_2 = { + .num_ports = 2, + .setup = pci_fastcom335_setup, +}; + +static const struct exar8250_board pbn_fastcom335_4 = { + .num_ports = 4, + .setup = pci_fastcom335_setup, +}; + +static const struct exar8250_board pbn_fastcom335_8 = { + .num_ports = 8, + .setup = pci_fastcom335_setup, +}; + static const struct exar8250_board pbn_connect = { .setup = pci_connect_tech_setup, }; @@ -375,6 +443,11 @@ static struct pci_device_id exar_pci_tbl[] = { EXAR_DEVICE(COMMTECH, COMMTECH_4222PCIE, pbn_exar_XR17V35x), EXAR_DEVICE(COMMTECH, COMMTECH_4224PCIE, pbn_exar_XR17V35x), EXAR_DEVICE(COMMTECH, COMMTECH_4228PCIE, pbn_exar_XR17V35x), + + EXAR_DEVICE(COMMTECH, COMMTECH_4222PCI335, pbn_fastcom335_2), + EXAR_DEVICE(COMMTECH, COMMTECH_4224PCI335, pbn_fastcom335_4), + EXAR_DEVICE(COMMTECH, COMMTECH_2324PCI335, pbn_fastcom335_4), + EXAR_DEVICE(COMMTECH, COMMTECH_2328PCI335, pbn_fastcom335_8), { 0, } }; MODULE_DEVICE_TABLE(pci, exar_pci_tbl); diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c index 2c83fd54b36c..d2bdcef7d759 100644 --- a/drivers/tty/serial/8250/8250_pci.c +++ b/drivers/tty/serial/8250/8250_pci.c @@ -1610,67 +1610,6 @@ static int pci_eg20t_init(struct pci_dev *dev) #endif } -#define UART_EXAR_MPIOINT_7_0 0x8f /* MPIOINT[7:0] */ -#define UART_EXAR_MPIOLVL_7_0 0x90 /* MPIOLVL[7:0] */ -#define UART_EXAR_MPIO3T_7_0 0x91 /* MPIO3T[7:0] */ -#define UART_EXAR_MPIOINV_7_0 0x92 /* MPIOINV[7:0] */ -#define UART_EXAR_MPIOSEL_7_0 0x93 /* MPIOSEL[7:0] */ -#define UART_EXAR_MPIOOD_7_0 0x94 /* MPIOOD[7:0] */ -#define UART_EXAR_MPIOINT_15_8 0x95 /* MPIOINT[15:8] */ -#define UART_EXAR_MPIOLVL_15_8 0x96 /* MPIOLVL[15:8] */ -#define UART_EXAR_MPIO3T_15_8 0x97 /* MPIO3T[15:8] */ -#define UART_EXAR_MPIOINV_15_8 0x98 /* MPIOINV[15:8] */ -#define UART_EXAR_MPIOSEL_15_8 0x99 /* MPIOSEL[15:8] */ -#define UART_EXAR_MPIOOD_15_8 0x9a /* MPIOOD[15:8] */ -#define PCI_DEVICE_ID_COMMTECH_4222PCI335 0x0004 -#define PCI_DEVICE_ID_COMMTECH_4224PCI335 0x0002 -#define PCI_DEVICE_ID_COMMTECH_2324PCI335 0x000a -#define PCI_DEVICE_ID_COMMTECH_2328PCI335 0x000b - -static int -pci_fastcom335_setup(struct serial_private *priv, - const struct pciserial_board *board, - struct uart_8250_port *port, int idx) -{ - u8 __iomem *p; - - p = pci_ioremap_bar(priv->dev, 0); - if (p == NULL) - return -ENOMEM; - - port->port.flags |= UPF_EXAR_EFR; - - /* - * Setup Multipurpose Input/Output pins. - */ - if (idx == 0) { - switch (priv->dev->device) { - case PCI_DEVICE_ID_COMMTECH_4222PCI335: - case PCI_DEVICE_ID_COMMTECH_4224PCI335: - writeb(0x78, p + UART_EXAR_MPIOLVL_7_0); - writeb(0x00, p + UART_EXAR_MPIOINV_7_0); - writeb(0x00, p + UART_EXAR_MPIOSEL_7_0); - break; - case PCI_DEVICE_ID_COMMTECH_2324PCI335: - case PCI_DEVICE_ID_COMMTECH_2328PCI335: - writeb(0x00, p + UART_EXAR_MPIOLVL_7_0); - writeb(0xc0, p + UART_EXAR_MPIOINV_7_0); - writeb(0xc0, p + UART_EXAR_MPIOSEL_7_0); - break; - } - writeb(0x00, p + UART_EXAR_MPIOINT_7_0); - writeb(0x00, p + UART_EXAR_MPIO3T_7_0); - writeb(0x00, p + UART_EXAR_MPIOOD_7_0); - } - writeb(0x00, p + UART_EXAR_8XMODE); - writeb(UART_FCTR_EXAR_TRGD, p + UART_EXAR_FCTR); - writeb(32, p + UART_EXAR_TXTRG); - writeb(32, p + UART_EXAR_RXTRG); - iounmap(p); - - return pci_default_setup(priv, board, port, idx); -} - static int pci_wch_ch353_setup(struct serial_private *priv, const struct pciserial_board *board, @@ -2430,38 +2369,6 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = { .subdevice = PCI_ANY_ID, .setup = pci_asix_setup, }, - /* - * Commtech, Inc. Fastcom adapters - * - */ - { - .vendor = PCI_VENDOR_ID_COMMTECH, - .device = PCI_DEVICE_ID_COMMTECH_4222PCI335, - .subvendor = PCI_ANY_ID, - .subdevice = PCI_ANY_ID, - .setup = pci_fastcom335_setup, - }, - { - .vendor = PCI_VENDOR_ID_COMMTECH, - .device = PCI_DEVICE_ID_COMMTECH_4224PCI335, - .subvendor = PCI_ANY_ID, - .subdevice = PCI_ANY_ID, - .setup = pci_fastcom335_setup, - }, - { - .vendor = PCI_VENDOR_ID_COMMTECH, - .device = PCI_DEVICE_ID_COMMTECH_2324PCI335, - .subvendor = PCI_ANY_ID, - .subdevice = PCI_ANY_ID, - .setup = pci_fastcom335_setup, - }, - { - .vendor = PCI_VENDOR_ID_COMMTECH, - .device = PCI_DEVICE_ID_COMMTECH_2328PCI335, - .subvendor = PCI_ANY_ID, - .subdevice = PCI_ANY_ID, - .setup = pci_fastcom335_setup, - }, /* * Broadcom TruManage (NetXtreme) */ @@ -2573,10 +2480,6 @@ enum pci_board_num_t { pbn_b0_4_1152000, - pbn_b0_2_1152000_200, - pbn_b0_4_1152000_200, - pbn_b0_8_1152000_200, - pbn_b0_4_1250000, pbn_b0_2_1843200, @@ -2780,27 +2683,6 @@ static struct pciserial_board pci_boards[] = { .uart_offset = 8, }, - [pbn_b0_2_1152000_200] = { - .flags = FL_BASE0, - .num_ports = 2, - .base_baud = 1152000, - .uart_offset = 0x200, - }, - - [pbn_b0_4_1152000_200] = { - .flags = FL_BASE0, - .num_ports = 4, - .base_baud = 1152000, - .uart_offset = 0x200, - }, - - [pbn_b0_8_1152000_200] = { - .flags = FL_BASE0, - .num_ports = 8, - .base_baud = 1152000, - .uart_offset = 0x200, - }, - [pbn_b0_4_1250000] = { .flags = FL_BASE0, .num_ports = 4, @@ -3521,6 +3403,7 @@ static const struct pci_device_id blacklist[] = { /* Exar devices */ { PCI_VDEVICE(EXAR, PCI_ANY_ID), }, + { PCI_VDEVICE(COMMTECH, PCI_ANY_ID), }, }; /* @@ -5248,26 +5131,6 @@ static struct pci_device_id serial_pci_tbl[] = { PCI_ANY_ID, PCI_ANY_ID, 0, 0, pbn_wch384_4 }, - /* - * Commtech, Inc. Fastcom adapters - */ - { PCI_VENDOR_ID_COMMTECH, PCI_DEVICE_ID_COMMTECH_4222PCI335, - PCI_ANY_ID, PCI_ANY_ID, - 0, - 0, pbn_b0_2_1152000_200 }, - { PCI_VENDOR_ID_COMMTECH, PCI_DEVICE_ID_COMMTECH_4224PCI335, - PCI_ANY_ID, PCI_ANY_ID, - 0, - 0, pbn_b0_4_1152000_200 }, - { PCI_VENDOR_ID_COMMTECH, PCI_DEVICE_ID_COMMTECH_2324PCI335, - PCI_ANY_ID, PCI_ANY_ID, - 0, - 0, pbn_b0_4_1152000_200 }, - { PCI_VENDOR_ID_COMMTECH, PCI_DEVICE_ID_COMMTECH_2328PCI335, - PCI_ANY_ID, PCI_ANY_ID, - 0, - 0, pbn_b0_8_1152000_200 }, - /* Fintek PCI serial cards */ { PCI_DEVICE(0x1c29, 0x1104), .driver_data = pbn_fintek_4 }, { PCI_DEVICE(0x1c29, 0x1108), .driver_data = pbn_fintek_8 }, -- cgit v1.2.3-59-g8ed1b From 0d560a1d549379e46139fb9eeae0b43328c76dea Mon Sep 17 00:00:00 2001 From: Jan Kiszka Date: Wed, 8 Feb 2017 17:09:07 +0100 Subject: serial: pci: Remove unused pci_boards entries Became obsolete with the split-out of 8250_exar. Signed-off-by: Jan Kiszka Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_pci.c | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c index d2bdcef7d759..00e51a064388 100644 --- a/drivers/tty/serial/8250/8250_pci.c +++ b/drivers/tty/serial/8250/8250_pci.c @@ -2485,10 +2485,6 @@ enum pci_board_num_t { pbn_b0_2_1843200, pbn_b0_4_1843200, - pbn_b0_2_1843200_200, - pbn_b0_4_1843200_200, - pbn_b0_8_1843200_200, - pbn_b0_1_4000000, pbn_b0_bt_1_115200, @@ -2703,24 +2699,6 @@ static struct pciserial_board pci_boards[] = { .uart_offset = 8, }, - [pbn_b0_2_1843200_200] = { - .flags = FL_BASE0, - .num_ports = 2, - .base_baud = 1843200, - .uart_offset = 0x200, - }, - [pbn_b0_4_1843200_200] = { - .flags = FL_BASE0, - .num_ports = 4, - .base_baud = 1843200, - .uart_offset = 0x200, - }, - [pbn_b0_8_1843200_200] = { - .flags = FL_BASE0, - .num_ports = 8, - .base_baud = 1843200, - .uart_offset = 0x200, - }, [pbn_b0_1_4000000] = { .flags = FL_BASE0, .num_ports = 1, -- cgit v1.2.3-59-g8ed1b From 7e12357ed64afdc8e60d64b8f8f17d711acf950a Mon Sep 17 00:00:00 2001 From: Jan Kiszka Date: Wed, 8 Feb 2017 17:09:08 +0100 Subject: serial: exar: Move register defines from uapi header to consumer site None of these registers is relevant for the userspace API. Signed-off-by: Jan Kiszka Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_exar.c | 13 +++++++++++++ drivers/tty/serial/8250/8250_port.c | 6 ++++++ include/uapi/linux/serial_reg.h | 18 ------------------ 3 files changed, 19 insertions(+), 18 deletions(-) diff --git a/drivers/tty/serial/8250/8250_exar.c b/drivers/tty/serial/8250/8250_exar.c index 9af4266eff96..f612da326e82 100644 --- a/drivers/tty/serial/8250/8250_exar.c +++ b/drivers/tty/serial/8250/8250_exar.c @@ -34,6 +34,19 @@ #define PCI_DEVICE_ID_EXAR_XR17V4358 0x4358 #define PCI_DEVICE_ID_EXAR_XR17V8358 0x8358 +#define UART_EXAR_8XMODE 0x88 /* 8X sampling rate select */ + +#define UART_EXAR_FCTR 0x08 /* Feature Control Register */ +#define UART_FCTR_EXAR_IRDA 0x10 /* IrDa data encode select */ +#define UART_FCTR_EXAR_485 0x20 /* Auto 485 half duplex dir ctl */ +#define UART_FCTR_EXAR_TRGA 0x00 /* FIFO trigger table A */ +#define UART_FCTR_EXAR_TRGB 0x60 /* FIFO trigger table B */ +#define UART_FCTR_EXAR_TRGC 0x80 /* FIFO trigger table C */ +#define UART_FCTR_EXAR_TRGD 0xc0 /* FIFO trigger table D programmable */ + +#define UART_EXAR_TXTRG 0x0a /* Tx FIFO trigger level write-only */ +#define UART_EXAR_RXTRG 0x0b /* Rx FIFO trigger level write-only */ + #define UART_EXAR_MPIOINT_7_0 0x8f /* MPIOINT[7:0] */ #define UART_EXAR_MPIOLVL_7_0 0x90 /* MPIOLVL[7:0] */ #define UART_EXAR_MPIO3T_7_0 0x91 /* MPIO3T[7:0] */ diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c index ec6b5e3dcaaa..6119516ef5fc 100644 --- a/drivers/tty/serial/8250/8250_port.c +++ b/drivers/tty/serial/8250/8250_port.c @@ -44,6 +44,12 @@ #include "8250.h" +/* + * These are definitions for the Exar XR17V35X and XR17(C|D)15X + */ +#define UART_EXAR_SLEEP 0x8b /* Sleep mode */ +#define UART_EXAR_DVID 0x8d /* Device identification */ + /* * Debugging. */ diff --git a/include/uapi/linux/serial_reg.h b/include/uapi/linux/serial_reg.h index 25b93a764a1a..5db76880b4ad 100644 --- a/include/uapi/linux/serial_reg.h +++ b/include/uapi/linux/serial_reg.h @@ -366,24 +366,6 @@ #define UART_OMAP_MDR1_CIR_MODE 0x06 /* CIR mode */ #define UART_OMAP_MDR1_DISABLE 0x07 /* Disable (default state) */ -/* - * These are definitions for the Exar XR17V35X and XR17(C|D)15X - */ -#define UART_EXAR_8XMODE 0x88 /* 8X sampling rate select */ -#define UART_EXAR_SLEEP 0x8b /* Sleep mode */ -#define UART_EXAR_DVID 0x8d /* Device identification */ - -#define UART_EXAR_FCTR 0x08 /* Feature Control Register */ -#define UART_FCTR_EXAR_IRDA 0x10 /* IrDa data encode select */ -#define UART_FCTR_EXAR_485 0x20 /* Auto 485 half duplex dir ctl */ -#define UART_FCTR_EXAR_TRGA 0x00 /* FIFO trigger table A */ -#define UART_FCTR_EXAR_TRGB 0x60 /* FIFO trigger table B */ -#define UART_FCTR_EXAR_TRGC 0x80 /* FIFO trigger table C */ -#define UART_FCTR_EXAR_TRGD 0xc0 /* FIFO trigger table D programmable */ - -#define UART_EXAR_TXTRG 0x0a /* Tx FIFO trigger level write-only */ -#define UART_EXAR_RXTRG 0x0b /* Rx FIFO trigger level write-only */ - /* * These are definitions for the Altera ALTR_16550_F32/F64/F128 * Normalized from 0x100 to 0x40 because of shift by 2 (32 bit regs). -- cgit v1.2.3-59-g8ed1b From 172c33cb61da0df5ccbdf1a8e736c8837d165a00 Mon Sep 17 00:00:00 2001 From: Jan Kiszka Date: Wed, 8 Feb 2017 17:09:09 +0100 Subject: serial: exar: Enable MSI support Use pci_alloc_irq_vectors to enable MSI when available. At least the XR17V352 supports this. Signed-off-by: Jan Kiszka Reviewed-by: Andy Shevchenko Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_exar.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/tty/serial/8250/8250_exar.c b/drivers/tty/serial/8250/8250_exar.c index f612da326e82..b89c4ffc0486 100644 --- a/drivers/tty/serial/8250/8250_exar.c +++ b/drivers/tty/serial/8250/8250_exar.c @@ -283,10 +283,16 @@ exar_pci_probe(struct pci_dev *pcidev, const struct pci_device_id *ent) priv->board = board; + pci_set_master(pcidev); + + rc = pci_alloc_irq_vectors(pcidev, 1, 1, PCI_IRQ_ALL_TYPES); + if (rc < 0) + return rc; + memset(&uart, 0, sizeof(uart)); uart.port.flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF | UPF_SHARE_IRQ | UPF_EXAR_EFR; - uart.port.irq = pcidev->irq; + uart.port.irq = pci_irq_vector(pcidev, 0); uart.port.dev = &pcidev->dev; for (i = 0; i < nr_ports && i < maxnr; i++) { -- cgit v1.2.3-59-g8ed1b From 6d35b131caea3e41f06625e391833e183f9042c0 Mon Sep 17 00:00:00 2001 From: Sergio Valverde Date: Tue, 31 Jan 2017 13:33:47 -0600 Subject: tty: Remove extra include in HVC console tty framework An extra "init.h" include is found in the HVC console code. As such, the extra line is deleted. Signed-off-by: Sergio Valverde Signed-off-by: Greg Kroah-Hartman --- drivers/tty/hvc/hvc_console.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/tty/hvc/hvc_console.c b/drivers/tty/hvc/hvc_console.c index 9b5c0fb216b5..b19ae36a05ec 100644 --- a/drivers/tty/hvc/hvc_console.c +++ b/drivers/tty/hvc/hvc_console.c @@ -29,7 +29,6 @@ #include #include #include -#include #include #include #include -- cgit v1.2.3-59-g8ed1b From 2867af2dcf4093d5617172c030ff449e5d5c5935 Mon Sep 17 00:00:00 2001 From: Romain Izard Date: Fri, 10 Feb 2017 16:24:46 +0100 Subject: atmel_serial: Use the fractional divider when possible The fractional baud rate generator is available when using the asynchronous mode of Atmel USART controllers. It makes it possible to use higher baudrates, in exchange for a less precise clock with a variable duty cycle. The existing code restricts its use to the normal mode of the USART controller, following the recommendation from the datasheet for the first chip embedding this type of controller. This recommendation has been removed from the documentation for the newer chips. After verification, all revisions of this controller should be able to use the fractional baud rate generator with the different asynchronous modes. Removing the condition on ATMEL_US_USMODE makes it possible to get correct baudrates at high speed in more cases. This was tested with a board using an Atmel SAMA5D2 chip and a TI WL1831 WiFi/Bluetooth combo chip at 3 Mbauds, with hardware flow control enabled. Signed-off-by: Romain Izard Acked-by: Ludovic Desroches Signed-off-by: Richard Genoud Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/atmel_serial.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c index 8d2cec0f03c2..dcebb28ffbc4 100644 --- a/drivers/tty/serial/atmel_serial.c +++ b/drivers/tty/serial/atmel_serial.c @@ -1769,7 +1769,9 @@ static void atmel_get_ip_name(struct uart_port *port) /* * Only USART devices from at91sam9260 SOC implement fractional - * baudrate. + * baudrate. It is available for all asynchronous modes, with the + * following restriction: the sampling clock's duty cycle is not + * constant. */ atmel_port->has_frac_baudrate = false; atmel_port->has_hw_timer = false; @@ -2213,8 +2215,7 @@ static void atmel_set_termios(struct uart_port *port, struct ktermios *termios, * then * 8 CD + FP = selected clock / (2 * baudrate) */ - if (atmel_port->has_frac_baudrate && - (mode & ATMEL_US_USMODE) == ATMEL_US_USMODE_NORMAL) { + if (atmel_port->has_frac_baudrate) { div = DIV_ROUND_CLOSEST(port->uartclk, baud * 2); cd = div >> 3; fp = div & ATMEL_US_FP_MASK; -- cgit v1.2.3-59-g8ed1b From d8a4995bcea168dfac8ee41c28c79109907e4fba Mon Sep 17 00:00:00 2001 From: Christopher Covington Date: Wed, 15 Feb 2017 16:39:43 -0500 Subject: tty: pl011: Work around QDF2400 E44 stuck BUSY bit The Qualcomm Datacenter Technologies QDF2400 family of SoCs contains a custom (non-PrimeCell) implementation of the SBSA UART. Occasionally the BUSY bit in the Flag Register gets stuck as 1, erratum 44 for both 2432v1 and 2400v1 SoCs.Checking that the Transmit FIFO Empty (TXFE) bit is 0, instead of checking that the BUSY bit is 1, works around the issue. To facilitate this substitution of flags and values, introduce vendor-specific inversion of Feature Register bits when UART AMBA Port (UAP) data is available. For the earlycon case, prior to UAP availability, implement alternative putc and early_write functions. Similar to what how ARMv8 ACPI PCI quirks are detected during MCFG parsing, check the OEM fields of the Serial Port Console Redirection (SPCR) ACPI table to determine if the current platform is known to be affected by the erratum. Signed-off-by: Christopher Covington Acked-by: Russell King Acked-by: Timur Tabi Acked-by: Mark Rutland Signed-off-by: Greg Kroah-Hartman --- drivers/acpi/spcr.c | 23 ++++++++++++++ drivers/tty/serial/amba-pl011.c | 66 ++++++++++++++++++++++++++++++++++++----- 2 files changed, 82 insertions(+), 7 deletions(-) diff --git a/drivers/acpi/spcr.c b/drivers/acpi/spcr.c index b8019c4c1d38..2b5d0fac81f0 100644 --- a/drivers/acpi/spcr.c +++ b/drivers/acpi/spcr.c @@ -16,6 +16,26 @@ #include #include +/* + * Some Qualcomm Datacenter Technologies SoCs have a defective UART BUSY bit. + * Detect them by examining the OEM fields in the SPCR header, similiar to PCI + * quirk detection in pci_mcfg.c. + */ +static bool qdf2400_erratum_44_present(struct acpi_table_header *h) +{ + if (memcmp(h->oem_id, "QCOM ", ACPI_OEM_ID_SIZE)) + return false; + + if (!memcmp(h->oem_table_id, "QDF2432 ", ACPI_OEM_TABLE_ID_SIZE)) + return true; + + if (!memcmp(h->oem_table_id, "QDF2400 ", ACPI_OEM_TABLE_ID_SIZE) && + h->oem_revision == 0) + return true; + + return false; +} + /** * parse_spcr() - parse ACPI SPCR table and add preferred console * @@ -93,6 +113,9 @@ int __init parse_spcr(bool earlycon) goto done; } + if (qdf2400_erratum_44_present(&table->header)) + uart = "qdf2400_e44"; + snprintf(opts, sizeof(opts), "%s,%s,0x%llx,%d", uart, iotype, table->serial_port.address, baud_rate); diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c index 533b18d4a587..8789ea423ccf 100644 --- a/drivers/tty/serial/amba-pl011.c +++ b/drivers/tty/serial/amba-pl011.c @@ -97,6 +97,7 @@ struct vendor_data { unsigned int fr_dsr; unsigned int fr_cts; unsigned int fr_ri; + unsigned int inv_fr; bool access_32b; bool oversampling; bool dma_threshold; @@ -141,6 +142,30 @@ static struct vendor_data vendor_sbsa = { .fixed_options = true, }; +/* + * Erratum 44 for QDF2432v1 and QDF2400v1 SoCs describes the BUSY bit as + * occasionally getting stuck as 1. To avoid the potential for a hang, check + * TXFE == 0 instead of BUSY == 1. This may not be suitable for all UART + * implementations, so only do so if an affected platform is detected in + * parse_spcr(). + */ +static bool qdf2400_e44_present = false; + +static struct vendor_data vendor_qdt_qdf2400_e44 = { + .reg_offset = pl011_std_offsets, + .fr_busy = UART011_FR_TXFE, + .fr_dsr = UART01x_FR_DSR, + .fr_cts = UART01x_FR_CTS, + .fr_ri = UART011_FR_RI, + .inv_fr = UART011_FR_TXFE, + .access_32b = true, + .oversampling = false, + .dma_threshold = false, + .cts_event_workaround = false, + .always_enabled = true, + .fixed_options = true, +}; + static u16 pl011_st_offsets[REG_ARRAY_SIZE] = { [REG_DR] = UART01x_DR, [REG_ST_DMAWM] = ST_UART011_DMAWM, @@ -1518,7 +1543,10 @@ static unsigned int pl011_tx_empty(struct uart_port *port) { struct uart_amba_port *uap = container_of(port, struct uart_amba_port, port); - unsigned int status = pl011_read(uap, REG_FR); + + /* Allow feature register bits to be inverted to work around errata */ + unsigned int status = pl011_read(uap, REG_FR) ^ uap->vendor->inv_fr; + return status & (uap->vendor->fr_busy | UART01x_FR_TXFF) ? 0 : TIOCSER_TEMT; } @@ -2215,10 +2243,12 @@ pl011_console_write(struct console *co, const char *s, unsigned int count) uart_console_write(&uap->port, s, count, pl011_console_putchar); /* - * Finally, wait for transmitter to become empty - * and restore the TCR + * Finally, wait for transmitter to become empty and restore the + * TCR. Allow feature register bits to be inverted to work around + * errata. */ - while (pl011_read(uap, REG_FR) & uap->vendor->fr_busy) + while ((pl011_read(uap, REG_FR) ^ uap->vendor->inv_fr) + & uap->vendor->fr_busy) cpu_relax(); if (!uap->vendor->always_enabled) pl011_write(old_cr, uap, REG_CR); @@ -2340,8 +2370,12 @@ static int __init pl011_console_match(struct console *co, char *name, int idx, resource_size_t addr; int i; - if (strcmp(name, "pl011") != 0 || strcmp(name, "ttyAMA") != 0) + if (strcmp(name, "qdf2400_e44") == 0) { + pr_info_once("UART: Working around QDF2400 SoC erratum 44"); + qdf2400_e44_present = true; + } else if (strcmp(name, "pl011") != 0 || strcmp(name, "ttyAMA") != 0) { return -ENODEV; + } if (uart_parse_earlycon(options, &iotype, &addr, &options)) return -ENODEV; @@ -2383,6 +2417,22 @@ static struct console amba_console = { #define AMBA_CONSOLE (&amba_console) +static void qdf2400_e44_putc(struct uart_port *port, int c) +{ + while (readl(port->membase + UART01x_FR) & UART01x_FR_TXFF) + cpu_relax(); + writel(c, port->membase + UART01x_DR); + while (!(readl(port->membase + UART01x_FR) & UART011_FR_TXFE)) + cpu_relax(); +} + +static void qdf2400_e44_early_write(struct console *con, const char *s, unsigned n) +{ + struct earlycon_device *dev = con->data; + + uart_console_write(&dev->port, s, n, qdf2400_e44_putc); +} + static void pl011_putc(struct uart_port *port, int c) { while (readl(port->membase + UART01x_FR) & UART01x_FR_TXFF) @@ -2408,7 +2458,8 @@ static int __init pl011_early_console_setup(struct earlycon_device *device, if (!device->port.membase) return -ENODEV; - device->con->write = pl011_early_write; + device->con->write = qdf2400_e44_present ? + qdf2400_e44_early_write : pl011_early_write; return 0; } OF_EARLYCON_DECLARE(pl011, "arm,pl011", pl011_early_console_setup); @@ -2645,7 +2696,8 @@ static int sbsa_uart_probe(struct platform_device *pdev) uap->port.irq = ret; uap->reg_offset = vendor_sbsa.reg_offset; - uap->vendor = &vendor_sbsa; + uap->vendor = qdf2400_e44_present ? + &vendor_qdt_qdf2400_e44 : &vendor_sbsa; uap->fifosize = 32; uap->port.iotype = vendor_sbsa.access_32b ? UPIO_MEM32 : UPIO_MEM; uap->port.ops = &sbsa_uart_pops; -- cgit v1.2.3-59-g8ed1b