summaryrefslogtreecommitdiffstats
path: root/drivers/serial
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/serial')
-rw-r--r--drivers/serial/Kconfig48
-rw-r--r--drivers/serial/Makefile5
-rw-r--r--drivers/serial/amba-pl011.c55
-rw-r--r--drivers/serial/arm_dcc.c6
-rw-r--r--drivers/serial/atmel.c28
-rw-r--r--drivers/serial/efi-stdio.c445
-rw-r--r--drivers/serial/efi-stdio.h58
-rw-r--r--drivers/serial/linux_console.c21
-rw-r--r--drivers/serial/serial_altera.c104
-rw-r--r--drivers/serial/serial_altera_jtag.c109
-rw-r--r--drivers/serial/serial_ar933x.c17
-rw-r--r--drivers/serial/serial_ar933x.h5
-rw-r--r--drivers/serial/serial_auart.c19
-rw-r--r--drivers/serial/serial_cadence.c23
-rw-r--r--drivers/serial/serial_clps711x.c67
-rw-r--r--drivers/serial/serial_digic.c18
-rw-r--r--drivers/serial/serial_efi.c5
-rw-r--r--drivers/serial/serial_imx.c30
-rw-r--r--drivers/serial/serial_litex.c10
-rw-r--r--drivers/serial/serial_lpuart.c22
-rw-r--r--drivers/serial/serial_lpuart32.c188
-rw-r--r--drivers/serial/serial_mpc5xxx.c26
-rw-r--r--drivers/serial/serial_ns16550.c240
-rw-r--r--drivers/serial/serial_ns16550.h13
-rw-r--r--drivers/serial/serial_ns16550_pci.c6
-rw-r--r--drivers/serial/serial_omap4_usbboot.c24
-rw-r--r--drivers/serial/serial_pl010.c4
-rw-r--r--drivers/serial/serial_pxa.c18
-rw-r--r--drivers/serial/serial_s3c.c209
-rw-r--r--drivers/serial/serial_sbi.c6
-rw-r--r--drivers/serial/serial_sifive.c10
-rw-r--r--drivers/serial/serial_stm32.c17
-rw-r--r--drivers/serial/serial_stm32.h2
-rw-r--r--drivers/serial/stm-serial.c21
34 files changed, 795 insertions, 1084 deletions
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index 5e30ea388b..60b0e5f1dc 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0-only
menu "serial drivers"
depends on !CONSOLE_NONE
@@ -30,7 +31,7 @@ config DRIVER_SERIAL_AR933X
config DRIVER_SERIAL_EFI
bool "EFI serial"
- depends on EFI_BOOTUP
+ depends on EFI_PAYLOAD
config DRIVER_SERIAL_IMX
depends on ARCH_IMX
@@ -38,8 +39,8 @@ config DRIVER_SERIAL_IMX
bool "i.MX serial driver"
config DRIVER_SERIAL_STM32
- depends on ARCH_STM32MP
- bool "stm32mp serial driver"
+ depends on ARCH_STM32
+ bool "stm32 serial driver"
config DRIVER_SERIAL_STM378X
depends on ARCH_MXS
@@ -57,7 +58,7 @@ config DRIVER_SERIAL_LINUX_CONSOLE
bool "linux console driver"
config DRIVER_SERIAL_EFI_STDIO
- depends on EFI_BOOTUP
+ depends on EFI_PAYLOAD
bool "EFI stdio driver"
config DRIVER_SERIAL_MPC5XXX
@@ -70,16 +71,6 @@ config DRIVER_SERIAL_CLPS711X
default y
bool "CLPS711X serial driver"
-config DRIVER_SERIAL_ALTERA
- depends on NIOS2
- default y
- bool "Altera serial driver"
-
-config DRIVER_SERIAL_ALTERA_JTAG
- depends on NIOS2
- default n
- bool "Altera JTAG serial driver"
-
config DRIVER_SERIAL_NS16550
default n
bool "NS16550 serial driver"
@@ -91,13 +82,6 @@ config DRIVER_SERIAL_ATMEL
default y
bool "Atmel serial driver"
-config DRIVER_SERIAL_NS16550_OMAP_EXTENSIONS
- bool "OMAP Extensions for NS16550"
- depends on DRIVER_SERIAL_NS16550
- depends on ARCH_OMAP
- help
- Say Y here if you are using OMAP extensions to NS16550
-
config DRIVER_SERIAL_NS16550_PCI
depends on DRIVER_SERIAL_NS16550
depends on PCI
@@ -113,24 +97,6 @@ config DRIVER_SERIAL_PL010
help
Enable this to get support for AMBA PL010 based serial devices
-config DRIVER_SERIAL_S3C_IMPROVED
- bool
-
-config DRIVER_SERIAL_S3C
- bool "Samsung S3C serial driver"
- depends on ARCH_SAMSUNG
- select DRIVER_SERIAL_S3C_IMPROVED if (CPU_S5PC110 || CPU_S5PV210 || CPU_S3C6410)
- default y
- help
- Say Y here if you want to use the CONS on a Samsung S3C CPU
-
-config DRIVER_SERIAL_S3C_AUTOSYNC
- bool "Enable auto flow"
- depends on DRIVER_SERIAL_S3C
- help
- Say Y here if you want to use the auto flow feature of this
- UART. RTS and CTS will be handled by the hardware when enabled.
-
config DRIVER_SERIAL_PXA
bool "PXA serial driver"
depends on ARCH_PXA
@@ -156,6 +122,10 @@ config DRIVER_SERIAL_LPUART
default y
bool "LPUART serial driver"
+config DRIVER_SERIAL_LPUART32
+ depends on ARCH_IMX
+ bool "LPUART32 serial driver"
+
config VIRTIO_CONSOLE
tristate "Virtio console"
depends on VIRTIO
diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile
index 02c5cc08bc..4887e24ee1 100644
--- a/drivers/serial/Makefile
+++ b/drivers/serial/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0-only
obj-$(CONFIG_DRIVER_SERIAL_ARM_DCC) += arm_dcc.o
obj-$(CONFIG_SERIAL_AMBA_PL011) += amba-pl011.o
obj-$(CONFIG_DRIVER_SERIAL_AR933X) += serial_ar933x.o
@@ -11,10 +12,7 @@ obj-$(CONFIG_DRIVER_SERIAL_CLPS711X) += serial_clps711x.o
obj-$(CONFIG_DRIVER_SERIAL_NS16550) += serial_ns16550.o
obj-$(CONFIG_DRIVER_SERIAL_NS16550_PCI) += serial_ns16550_pci.o
obj-$(CONFIG_DRIVER_SERIAL_PL010) += serial_pl010.o
-obj-$(CONFIG_DRIVER_SERIAL_S3C) += serial_s3c.o
obj-$(CONFIG_DRIVER_SERIAL_STM32) += serial_stm32.o
-obj-$(CONFIG_DRIVER_SERIAL_ALTERA) += serial_altera.o
-obj-$(CONFIG_DRIVER_SERIAL_ALTERA_JTAG) += serial_altera_jtag.o
obj-$(CONFIG_DRIVER_SERIAL_PXA) += serial_pxa.o
obj-$(CONFIG_DRIVER_SERIAL_OMAP4_USBBOOT) += serial_omap4_usbboot.o
obj-$(CONFIG_DRIVER_SERIAL_AUART) += serial_auart.o
@@ -22,6 +20,7 @@ obj-$(CONFIG_DRIVER_SERIAL_CADENCE) += serial_cadence.o
obj-$(CONFIG_DRIVER_SERIAL_EFI_STDIO) += efi-stdio.o
obj-$(CONFIG_DRIVER_SERIAL_DIGIC) += serial_digic.o
obj-$(CONFIG_DRIVER_SERIAL_LPUART) += serial_lpuart.o
+obj-$(CONFIG_DRIVER_SERIAL_LPUART32) += serial_lpuart32.o
obj-$(CONFIG_VIRTIO_CONSOLE) += virtio_console.o
obj-$(CONFIG_SERIAL_SIFIVE) += serial_sifive.o
obj-$(CONFIG_SERIAL_SBI) += serial_sbi.o
diff --git a/drivers/serial/amba-pl011.c b/drivers/serial/amba-pl011.c
index 9261d20f2a..b53ff6877b 100644
--- a/drivers/serial/amba-pl011.c
+++ b/drivers/serial/amba-pl011.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
* (C) Copyright 2000
* Rob Taylor, Flying Pig Systems. robt@flyingpig.com.
@@ -5,17 +6,6 @@
* (C) Copyright 2004
* ARM Ltd.
* Philippe Robin, <philippe.robin@arm.com>
- *
- * 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, or (at your option) any later version.
- *
- * 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.
- *
*/
/* Simple U-Boot driver for the PrimeCell PL010/PL011 UARTs */
@@ -64,6 +54,23 @@ to_amba_uart_port(struct console_device *uart)
return container_of(uart, struct amba_uart_port, uart);
}
+static void pl011_rlcr(struct amba_uart_port *uart, u32 lcr)
+{
+ struct vendor_data *vendor = uart->vendor;
+
+ writew(lcr, uart->base + vendor->lcrh_rx);
+ if (vendor->lcrh_tx != vendor->lcrh_rx) {
+ int i;
+ /*
+ * Wait 10 PCLKs before writing LCRH_TX register,
+ * to get this delay write read only register 10 times
+ */
+ for (i = 0; i < 10; ++i)
+ writew(0xff, uart->base + UART011_MIS);
+ writew(lcr, uart->base + vendor->lcrh_tx);
+ }
+}
+
static int pl011_setbaudrate(struct console_device *cdev, int baudrate)
{
struct amba_uart_port *uart = to_amba_uart_port(cdev);
@@ -71,6 +78,7 @@ static int pl011_setbaudrate(struct console_device *cdev, int baudrate)
unsigned int divider;
unsigned int remainder;
unsigned int fraction;
+ uint32_t cr;
/*
** Set baud rate
@@ -84,9 +92,15 @@ static int pl011_setbaudrate(struct console_device *cdev, int baudrate)
temp = (8 * remainder) / baudrate;
fraction = (temp >> 1) + (temp & 1);
+ cr = readl(uart->base + UART011_CR);
+ writel(0x0, uart->base + UART011_CR);
+
writel(divider, uart->base + UART011_IBRD);
writel(fraction, uart->base + UART011_FBRD);
+ pl011_rlcr(uart, UART01x_LCRH_WLEN_8 | UART01x_LCRH_FEN);
+ writel(cr, uart->base + UART011_CR);
+
return 0;
}
@@ -128,23 +142,6 @@ static int pl011_tstc(struct console_device *cdev)
return !(readl(uart->base + UART01x_FR) & UART01x_FR_RXFE);
}
-static void pl011_rlcr(struct amba_uart_port *uart, u32 lcr)
-{
- struct vendor_data *vendor = uart->vendor;
-
- writew(lcr, uart->base + vendor->lcrh_rx);
- if (vendor->lcrh_tx != vendor->lcrh_rx) {
- int i;
- /*
- * Wait 10 PCLKs before writing LCRH_TX register,
- * to get this delay write read only register 10 times
- */
- for (i = 0; i < 10; ++i)
- writew(0xff, uart->base + UART011_MIS);
- writew(lcr, uart->base + vendor->lcrh_tx);
- }
-}
-
static int pl011_init_port(struct console_device *cdev)
{
struct amba_uart_port *uart = to_amba_uart_port(cdev);
@@ -205,6 +202,8 @@ static int pl011_probe(struct amba_device *dev, const struct amba_id *id)
cdev->getc = pl011_getc;
cdev->setbrg = pl011_setbaudrate;
cdev->linux_console_name = "ttyAMA";
+ cdev->linux_earlycon_name = "pl011";
+ cdev->phys_base = uart->base;
pl011_init_port(cdev);
diff --git a/drivers/serial/arm_dcc.c b/drivers/serial/arm_dcc.c
index db0ee7fe09..1e2b4e425c 100644
--- a/drivers/serial/arm_dcc.c
+++ b/drivers/serial/arm_dcc.c
@@ -108,7 +108,7 @@ static int arm_dcc_tstc(struct console_device *cdev)
static struct console_device arm_dcc_dev;
-static int arm_dcc_probe(struct device_d *dev)
+static int arm_dcc_probe(struct device *dev)
{
struct console_device *cdev;
@@ -125,13 +125,13 @@ static int arm_dcc_probe(struct device_d *dev)
return 0;
}
-static struct driver_d arm_dcc_driver = {
+static struct driver arm_dcc_driver = {
.name = "arm_dcc",
.probe = arm_dcc_probe,
};
console_platform_driver(arm_dcc_driver);
-static struct device_d arm_dcc_device = {
+static struct device arm_dcc_device = {
.id = DEVICE_ID_DYNAMIC,
.name = "arm_dcc",
};
diff --git a/drivers/serial/atmel.c b/drivers/serial/atmel.c
index 8394273f9f..b957b75284 100644
--- a/drivers/serial/atmel.c
+++ b/drivers/serial/atmel.c
@@ -1,17 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
* (c) 2004 Sascha Hauer <sascha@saschahauer.de>
- *
- * 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, or
- * (at your option) any later version.
- *
- * 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 <common.h>
@@ -395,7 +384,7 @@ static int atmel_serial_set_mode(struct console_device *cdev, enum console_mode
*/
static int atmel_serial_init_port(struct console_device *cdev)
{
- struct device_d *dev = cdev->dev;
+ struct device *dev = cdev->dev;
struct atmel_uart_port *uart = to_atmel_uart_port(cdev);
uart->base = dev_request_mem_region_err_null(dev, 0);
@@ -423,10 +412,11 @@ static int atmel_serial_init_port(struct console_device *cdev)
return 0;
}
-static int atmel_serial_probe(struct device_d *dev)
+static int atmel_serial_probe(struct device *dev)
{
struct atmel_uart_port *uart;
struct console_device *cdev;
+ int ret;
uart = xzalloc(sizeof(struct atmel_uart_port));
cdev = &uart->uart;
@@ -437,8 +427,13 @@ static int atmel_serial_probe(struct device_d *dev)
cdev->setbrg = atmel_serial_setbaudrate;
cdev->set_mode = atmel_serial_set_mode;
cdev->linux_console_name = "ttyAT";
+ cdev->linux_earlycon_name = "atmel_serial";
+
+ ret = atmel_serial_init_port(cdev);
+ if (ret)
+ return ret;
- atmel_serial_init_port(cdev);
+ cdev->phys_base = uart->base;
/* Enable UART */
@@ -452,8 +447,9 @@ static const struct of_device_id __maybe_unused atmel_serial_dt_ids[] = {
{ .compatible = "atmel,at91sam9260-usart" },
{ /* sentinel */ }
};
+MODULE_DEVICE_TABLE(of, atmel_serial_dt_ids);
-static struct driver_d atmel_serial_driver = {
+static struct driver atmel_serial_driver = {
.name = "atmel_usart",
.probe = atmel_serial_probe,
.of_compatible = DRV_OF_COMPAT(atmel_serial_dt_ids),
diff --git a/drivers/serial/efi-stdio.c b/drivers/serial/efi-stdio.c
index d269985ce7..92133f8378 100644
--- a/drivers/serial/efi-stdio.c
+++ b/drivers/serial/efi-stdio.c
@@ -1,17 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-only
/*
* efi_console.c - EFI console support
*
* Copyright (c) 2014 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License 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 <common.h>
#include <driver.h>
@@ -22,63 +13,32 @@
#include <efi.h>
#include <readkey.h>
#include <linux/ctype.h>
-#include <efi/efi.h>
+#include <efi/efi-payload.h>
+#include <kfifo.h>
#include <efi/efi-device.h>
-#include "efi-stdio.h"
-
-#define EFI_SHIFT_STATE_VALID 0x80000000
-#define EFI_RIGHT_CONTROL_PRESSED 0x00000004
-#define EFI_LEFT_CONTROL_PRESSED 0x00000008
-#define EFI_RIGHT_ALT_PRESSED 0x00000010
-#define EFI_LEFT_ALT_PRESSED 0x00000020
-
-#define EFI_CONTROL_PRESSED (EFI_RIGHT_CONTROL_PRESSED | EFI_LEFT_CONTROL_PRESSED)
-#define EFI_ALT_PRESSED (EFI_RIGHT_ALT_PRESSED | EFI_LEFT_ALT_PRESSED)
-#define KEYPRESS(keys, scan, uni) ((((uint64_t)keys) << 32) | ((scan) << 16) | (uni))
-#define KEYCHAR(k) ((k) & 0xffff)
-#define CHAR_CTRL(c) ((c) - 'a' + 1)
-
-#define EFI_BLACK 0x00
-#define EFI_BLUE 0x01
-#define EFI_GREEN 0x02
-#define EFI_CYAN (EFI_BLUE | EFI_GREEN)
-#define EFI_RED 0x04
-#define EFI_MAGENTA (EFI_BLUE | EFI_RED)
-#define EFI_BROWN (EFI_GREEN | EFI_RED)
-#define EFI_LIGHTGRAY (EFI_BLUE | EFI_GREEN | EFI_RED)
-#define EFI_BRIGHT 0x08
-#define EFI_DARKGRAY (EFI_BRIGHT)
-#define EFI_LIGHTBLUE (EFI_BLUE | EFI_BRIGHT)
-#define EFI_LIGHTGREEN (EFI_GREEN | EFI_BRIGHT)
-#define EFI_LIGHTCYAN (EFI_CYAN | EFI_BRIGHT)
-#define EFI_LIGHTRED (EFI_RED | EFI_BRIGHT)
-#define EFI_LIGHTMAGENTA (EFI_MAGENTA | EFI_BRIGHT)
-#define EFI_YELLOW (EFI_BROWN | EFI_BRIGHT)
-#define EFI_WHITE (EFI_BLUE | EFI_GREEN | EFI_RED | EFI_BRIGHT)
-
-#define EFI_TEXT_ATTR(f,b) ((f) | ((b) << 4))
-
-#define EFI_BACKGROUND_BLACK 0x00
-#define EFI_BACKGROUND_BLUE 0x10
-#define EFI_BACKGROUND_GREEN 0x20
-#define EFI_BACKGROUND_CYAN (EFI_BACKGROUND_BLUE | EFI_BACKGROUND_GREEN)
-#define EFI_BACKGROUND_RED 0x40
-#define EFI_BACKGROUND_MAGENTA (EFI_BACKGROUND_BLUE | EFI_BACKGROUND_RED)
-#define EFI_BACKGROUND_BROWN (EFI_BACKGROUND_GREEN | EFI_BACKGROUND_RED)
-#define EFI_BACKGROUND_LIGHTGRAY (EFI_BACKGROUND_BLUE | EFI_BACKGROUND_GREEN | EFI_BACKGROUND_RED)
+#include <efi/efi-stdio.h>
struct efi_console_priv {
struct efi_simple_text_output_protocol *out;
- struct efi_simple_input_interface *in;
+ struct efi_simple_text_input_protocol *in;
struct efi_simple_text_input_ex_protocol *inex;
struct console_device cdev;
- int lastkey;
- u16 efi_console_buffer[CONFIG_CBSIZE];
+ u16 efi_console_buffer[CONFIG_CBSIZE + 1];
+ int pos;
+
+ struct kfifo *inputbuffer;
unsigned long columns, rows;
- int current_color;
+ int fg;
+ int bg;
+ bool inverse;
s16 *blank_line;
+
+ struct param_d *param_mode;
+ const char **mode_names;
+ int *mode_num;
+ unsigned int var_mode;
};
static inline struct efi_console_priv *to_efi(struct console_device *cdev)
@@ -119,17 +79,23 @@ static int xlate_keypress(struct efi_input_key *k)
return k->unicode_char & 0xff;
}
+static void efi_wait_single_event(struct efi_event *event)
+{
+ size_t index;
+
+ /* wait until key is pressed */
+ BS->wait_for_event(1, &event, &index);
+}
+
static int efi_read_key(struct efi_console_priv *priv, bool wait)
{
- unsigned long index;
efi_status_t efiret;
struct efi_key_data kd;
- /* wait until key is pressed */
- if (wait)
- BS->wait_for_event(1, priv->in->wait_for_key, &index);
-
if (priv->inex) {
+ if (wait)
+ efi_wait_single_event(priv->inex->wait_for_key_ex);
+
efiret = priv->inex->read_key_stroke_ex(priv->inex, &kd);
if (efiret == EFI_NOT_READY)
@@ -158,6 +124,9 @@ static int efi_read_key(struct efi_console_priv *priv, bool wait)
}
}
+ if (wait)
+ efi_wait_single_event(priv->in->wait_for_key);
+
efiret = priv->in->read_key_stroke(priv->in, &kd.key);
if (EFI_ERROR(efiret))
@@ -166,148 +135,221 @@ static int efi_read_key(struct efi_console_priv *priv, bool wait)
return xlate_keypress(&kd.key);
}
-static void efi_console_putc(struct console_device *cdev, char c)
+static void clear_to_eol(struct efi_console_priv *priv)
{
- uint16_t str[2] = {};
- struct efi_console_priv *priv = to_efi(cdev);
- struct efi_simple_text_output_protocol *con_out = priv->out;
+ int pos = priv->out->mode->cursor_column;
+
+ priv->out->output_string(priv->out, priv->blank_line + pos);
+}
- str[0] = c;
+static int ansi_to_efi_color(int ansi)
+{
+ switch (ansi) {
+ case 30:
+ return EFI_BLACK;
+ case 31:
+ return EFI_RED;
+ case 32:
+ return EFI_GREEN;
+ case 33:
+ return EFI_YELLOW;
+ case 34:
+ return EFI_BLUE;
+ case 35:
+ return EFI_MAGENTA;
+ case 36:
+ return EFI_CYAN;
+ case 37:
+ return EFI_WHITE;
+ case 39:
+ return EFI_LIGHTGRAY;
+ }
- con_out->output_string(con_out, str);
+ return -1;
}
-static void clear_to_eol(struct efi_console_priv *priv)
+static void set_fg_bg_colors(struct efi_console_priv *priv)
{
- int pos = priv->out->mode->cursor_column;
+ int fg = priv->inverse ? priv->bg : priv->fg;
+ int bg = priv->inverse ? priv->fg : priv->bg;
- priv->out->output_string(priv->out, priv->blank_line + pos);
+ priv->out->set_attribute(priv->out, EFI_TEXT_ATTR(fg , bg));
}
static int efi_process_square_bracket(struct efi_console_priv *priv, const char *inp)
{
- int x, y;
char *endp;
+ int n, retlen;
+ int arg0 = -1, arg1 = -1, arg2 = -1;
+ char *buf;
- inp++;
-
- switch (*inp) {
- case 'A':
- /* Cursor up */
- case 'B':
- /* Cursor down */
- case 'C':
- /* Cursor right */
- case 'D':
- /* Cursor left */
- case 'H':
- /* home */
- case 'F':
- /* end */
- return 3;
- case 'K':
- clear_to_eol(priv);
- return 3;
- }
-
- if (*inp == '2' && *(inp + 1) == 'J') {
- priv->out->clear_screen(priv->out);
- return 4;
- }
+ endp = strpbrk(inp, "ABCDEFGHJKmrnhl");
+ if (!endp)
+ return 0;
- if (*inp == '0' && *(inp + 1) == 'm') {
- priv->out->set_attribute(priv->out,
- EFI_TEXT_ATTR(EFI_WHITE, EFI_BLACK));
- return 4;
- }
+ retlen = endp - inp + 1;
- if (*inp == '7' && *(inp + 1) == 'm') {
- priv->out->set_attribute(priv->out,
- EFI_TEXT_ATTR(EFI_BLACK, priv->current_color));
- return 4;
- }
+ inp++;
- if (*inp == '1' &&
- *(inp + 1) == ';' &&
- *(inp + 2) == '3' &&
- *(inp + 3) &&
- *(inp + 4) == 'm') {
- int color;
- switch (*(inp + 3)) {
- case '1': color = EFI_RED; break;
- case '4': color = EFI_BLUE; break;
- case '2': color = EFI_GREEN; break;
- case '6': color = EFI_CYAN; break;
- case '3': color = EFI_YELLOW; break;
- case '5': color = EFI_MAGENTA; break;
- case '7': color = EFI_WHITE; break;
- default: color = EFI_WHITE; break;
+ if (isdigit(*inp)) {
+ char *e;
+ arg0 = simple_strtoul(inp, &e, 10);
+ if (*e == ';') {
+ arg1 = simple_strtoul(e + 1, &e, 10);
+ if (*e == ';')
+ arg2 = simple_strtoul(e + 1, &e, 10);
}
-
- priv->current_color = color;
-
- priv->out->set_attribute(priv->out,
- EFI_TEXT_ATTR(color, EFI_BLACK));
- return 7;
+ } else if (*inp == '?') {
+ arg0 = simple_strtoul(inp + 1, NULL, 10);
}
- y = simple_strtoul(inp, &endp, 10);
- if (*endp == ';') {
- x = simple_strtoul(endp + 1, &endp, 10);
- if (*endp == 'H') {
- priv->out->set_cursor_position(priv->out, x - 1, y - 1);
- return endp - inp + 3;
+ switch (*endp) {
+ case 'K':
+ switch (arg0) {
+ case 0:
+ case -1:
+ clear_to_eol(priv);
+ break;
+ }
+ break;
+ case 'J':
+ switch (arg0) {
+ case 2:
+ priv->out->clear_screen(priv->out);
+ break;
+ }
+ break;
+ case 'H':
+ if (arg0 >= 0 && arg1 >= 0) {
+ int row = min_t(int, arg0, priv->rows);
+ int col = min_t(int, arg1, priv->columns);
+ priv->out->set_cursor_position(priv->out, col - 1, row - 1);
+ }
+ break;
+ case 'm':
+ switch (arg0) {
+ case 0:
+ priv->inverse = false;
+ priv->fg = EFI_LIGHTGRAY;
+ priv->bg = EFI_BLACK;
+ set_fg_bg_colors(priv);
+ break;
+ case 7:
+ priv->inverse = true;
+ set_fg_bg_colors(priv);
+ break;
+ case 1:
+ priv->fg = ansi_to_efi_color(arg1);
+ if (priv->fg < 0)
+ priv->fg = EFI_LIGHTGRAY;
+ priv->bg = ansi_to_efi_color(arg2);
+ if (priv->bg < 0)
+ priv->bg = EFI_BLACK;
+ set_fg_bg_colors(priv);
+ break;
}
+ break;
+ case 'n':
+ switch (arg0) {
+ case 6:
+ n = asprintf(&buf, "\033[%d;%dR", priv->out->mode->cursor_row + 1,
+ priv->out->mode->cursor_column + 1);
+ kfifo_put(priv->inputbuffer, buf, n);
+ free(buf);
+ break;
+ }
+ break;
+ case 'h':
+ if (*inp == '?' && arg0 == 25)
+ priv->out->enable_cursor(priv->out, true);
+ break;
+ case 'l':
+ if (*inp == '?' && arg0 == 25)
+ priv->out->enable_cursor(priv->out, false);
+ break;
}
- return 8;
+ return retlen;
}
-static int efi_process_key(struct efi_console_priv *priv, const char *inp)
+static int efi_process_escape(struct efi_console_priv *priv, const char *inp)
{
char c;
c = *inp;
- if (c != 27)
- return 0;
-
inp++;
if (*inp == '[')
- return efi_process_square_bracket(priv, inp);
+ return efi_process_square_bracket(priv, inp) + 1;
return 1;
}
+static void efi_console_add_char(struct efi_console_priv *priv, int c)
+{
+ if (priv->pos >= CONFIG_CBSIZE)
+ return;
+
+ priv->efi_console_buffer[priv->pos] = c;
+ priv->pos++;
+}
+
+static void efi_console_flush(struct efi_console_priv *priv)
+{
+ priv->efi_console_buffer[priv->pos] = 0;
+
+ priv->out->output_string(priv->out, priv->efi_console_buffer);
+
+ priv->pos = 0;
+}
+
static int efi_console_puts(struct console_device *cdev, const char *s,
size_t nbytes)
{
struct efi_console_priv *priv = to_efi(cdev);
- int n = 0;
-
- while (nbytes--) {
- if (*s == 27) {
- priv->efi_console_buffer[n] = 0;
- priv->out->output_string(priv->out,
- priv->efi_console_buffer);
- n = 0;
- s += efi_process_key(priv, s);
- continue;
+ int n, pos = 0;
+
+ while (pos < nbytes) {
+ switch (s[pos]) {
+ case 27:
+ efi_console_flush(priv);
+ pos += efi_process_escape(priv, s + pos);
+ break;
+ case '\n':
+ efi_console_add_char(priv, '\r');
+ efi_console_add_char(priv, '\n');
+ pos++;
+ break;
+ case '\t':
+ efi_console_flush(priv);
+ n = 8 - priv->out->mode->cursor_column % 8;
+ while (n--)
+ efi_console_add_char(priv, ' ');
+ pos++;
+ break;
+ case '\b':
+ n = priv->out->mode->cursor_column;
+ if (n > 0)
+ priv->out->set_cursor_position(priv->out,
+ n - 1, priv->out->mode->cursor_row);
+ pos++;
+ break;
+ default:
+ efi_console_add_char(priv, s[pos]);
+ pos++;
+ break;
}
-
- if (*s == '\n')
- priv->efi_console_buffer[n++] = '\r';
- priv->efi_console_buffer[n] = *s;
- s++;
- n++;
}
- priv->efi_console_buffer[n] = 0;
+ efi_console_flush(priv);
- priv->out->output_string(priv->out, priv->efi_console_buffer);
+ return nbytes;
+}
- return n;
+static void efi_console_putc(struct console_device *cdev, char c)
+{
+ efi_console_puts(cdev, &c, 1);
}
static int efi_console_tstc(struct console_device *cdev)
@@ -315,14 +357,14 @@ static int efi_console_tstc(struct console_device *cdev)
struct efi_console_priv *priv = to_efi(cdev);
int key;
- if (priv->lastkey > 0)
+ if (kfifo_len(priv->inputbuffer))
return 1;
key = efi_read_key(priv, 0);
if (key < 0)
return 0;
- priv->lastkey = key;
+ kfifo_putc(priv->inputbuffer, key);
return 1;
}
@@ -330,58 +372,74 @@ static int efi_console_tstc(struct console_device *cdev)
static int efi_console_getc(struct console_device *cdev)
{
struct efi_console_priv *priv = to_efi(cdev);
- int key;
+ unsigned char c;
- if (priv->lastkey > 0) {
- key = priv->lastkey;
- priv->lastkey = -1;
- return key;
- }
+ if (!kfifo_getc(priv->inputbuffer, &c))
+ return c;
return efi_read_key(priv, 1);
}
+static int efi_console_set_mode(struct param_d *param, void *p)
+{
+ struct efi_console_priv *priv = p;
+
+ priv->out->set_mode(priv->out, priv->mode_num[priv->var_mode]);
+
+ priv->out->query_mode(priv->out, priv->out->mode->mode,
+ &priv->columns, &priv->rows);
+ return 0;
+}
+
static void efi_set_mode(struct efi_console_priv *priv)
{
-#if 0
int i;
- unsigned long rows, columns, best = 0, mode = 0;
+ unsigned long rows, columns;
+ int n = 0;
efi_status_t efiret;
+ priv->mode_names = xzalloc(priv->out->mode->max_mode * sizeof(*priv->mode_names));
+ priv->mode_num = xzalloc(priv->out->mode->max_mode * sizeof(*priv->mode_num));
+
+ priv->out->query_mode(priv->out, priv->out->mode->mode, &priv->columns, &priv->rows);
+
for (i = 0; i < priv->out->mode->max_mode; i++) {
- priv->out->query_mode(priv->out, i, &columns, &rows);
- printf("%d: %ld %ld\n", i, columns, rows);
- if (rows * columns > best) {
- best = rows * columns;
- mode = i;
- }
+ efiret = priv->out->query_mode(priv->out, i, &columns, &rows);
+ if (EFI_ERROR(efiret))
+ continue;
+
+ if (columns == priv->columns && rows == priv->rows)
+ priv->var_mode = n;
+
+ priv->mode_names[n] = basprintf("%ldx%ld", columns, rows);
+ priv->mode_num[n] = i;
+ n++;
}
- /*
- * Setting the mode doesn't work as expected. set_mode succeeds, but
- * the graphics resolution is not changed.
- */
- priv->out->set_mode(priv->out, mode);
-#endif
- priv->out->query_mode(priv->out, priv->out->mode->mode, &priv->columns, &priv->rows);
+ priv->param_mode = dev_add_param_enum(&priv->cdev.class_dev, "mode",
+ efi_console_set_mode, NULL, &priv->var_mode,
+ priv->mode_names, n, priv);
}
-static int efi_console_probe(struct device_d *dev)
+static int efi_console_probe(struct device *dev)
{
efi_guid_t inex_guid = EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL_GUID;
struct efi_simple_text_input_ex_protocol *inex;
struct console_device *cdev;
struct efi_console_priv *priv;
efi_status_t efiret;
-
- int i;
+ int i, ret;
priv = xzalloc(sizeof(*priv));
priv->out = efi_sys_table->con_out;
priv->in = efi_sys_table->con_in;
- efiret = BS->open_protocol((void *)efi_sys_table->con_in_handle,
+ priv->inputbuffer = kfifo_alloc(128);
+ if (!priv->inputbuffer)
+ return -ENOMEM;
+
+ efiret = BS->open_protocol(efi_sys_table->con_in_handle,
&inex_guid,
(void **)&inex,
efi_parent_image,
@@ -393,9 +451,8 @@ static int efi_console_probe(struct device_d *dev)
dev_dbg(dev, "Using simple_text_input_ex_protocol\n");
}
- priv->current_color = EFI_WHITE;
-
- efi_set_mode(priv);
+ priv->fg = EFI_LIGHTGRAY;
+ priv->bg = EFI_BLACK;
priv->out->enable_cursor(priv->out, 1);
@@ -410,12 +467,16 @@ static int efi_console_probe(struct device_d *dev)
cdev->putc = efi_console_putc;
cdev->puts = efi_console_puts;
- priv->lastkey = -1;
+ ret = console_register(cdev);
+ if (ret)
+ return ret;
+
+ efi_set_mode(priv);
- return console_register(cdev);
+ return 0;
}
-static struct driver_d efi_console_driver = {
+static struct driver efi_console_driver = {
.name = "efi-stdio",
.probe = efi_console_probe,
};
diff --git a/drivers/serial/efi-stdio.h b/drivers/serial/efi-stdio.h
deleted file mode 100644
index 1fa417c706..0000000000
--- a/drivers/serial/efi-stdio.h
+++ /dev/null
@@ -1,58 +0,0 @@
-#ifndef EFI_STDIO_H_
-#define EFI_STDIO_H_
-
-#include <efi.h>
-
-struct efi_simple_text_input_ex_protocol;
-
-typedef efi_status_t (EFIAPI *efi_input_reset_ex)(
- struct efi_simple_text_input_ex_protocol *this,
- efi_bool_t extended_verification
-);
-
-struct efi_key_state {
- u32 shift_state;
- u8 toggle_state;
-};
-
-struct efi_key_data {
- struct efi_input_key key;
- struct efi_key_state state;
-};
-
-typedef efi_status_t (EFIAPI *efi_input_read_key_ex)(
- struct efi_simple_text_input_ex_protocol *this,
- struct efi_key_data *keydata
-);
-
-typedef efi_status_t (EFIAPI *efi_set_state)(
- struct efi_simple_text_input_ex_protocol *this,
- u8 *key_toggle_state
-);
-
-typedef efi_status_t (EFIAPI *efi_key_notify_function)(
- struct efi_key_data *keydata
-);
-
-typedef efi_status_t (EFIAPI *efi_register_keystroke_notify)(
- struct efi_simple_text_input_ex_protocol *this,
- struct efi_key_data keydata,
- efi_key_notify_function key_notification_function,
- void **notify_handle
-);
-
-typedef efi_status_t (EFIAPI *efi_unregister_keystroke_notify)(
- struct efi_simple_text_input_ex_protocol *this,
- void *notification_handle
-);
-
-struct efi_simple_text_input_ex_protocol {
- efi_input_reset_ex reset;
- efi_input_read_key_ex read_key_stroke_ex;
- void *wait_for_key_ex;
- efi_set_state set_state;
- efi_register_keystroke_notify register_key_notify;
- efi_unregister_keystroke_notify unregister_key_notify;
-};
-
-#endif
diff --git a/drivers/serial/linux_console.c b/drivers/serial/linux_console.c
index 056fbc65d9..b8303dfd12 100644
--- a/drivers/serial/linux_console.c
+++ b/drivers/serial/linux_console.c
@@ -1,17 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-only
/*
* linux_console.c - Use stdin/stdout as a console device
*
* Copyright (c) 2007 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License 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 <common.h>
@@ -24,7 +15,7 @@
static void linux_console_putc(struct console_device *cdev, char c)
{
- struct device_d *dev = cdev->dev;
+ struct device *dev = cdev->dev;
struct linux_console_data *d = dev->platform_data;
linux_write(d->stdoutfd, &c, 1);
@@ -32,7 +23,7 @@ static void linux_console_putc(struct console_device *cdev, char c)
static int linux_console_tstc(struct console_device *cdev)
{
- struct device_d *dev = cdev->dev;
+ struct device *dev = cdev->dev;
struct linux_console_data *d = dev->platform_data;
return linux_tstc(d->stdinfd);
@@ -40,7 +31,7 @@ static int linux_console_tstc(struct console_device *cdev)
static int linux_console_getc(struct console_device *cdev)
{
- struct device_d *dev = cdev->dev;
+ struct device *dev = cdev->dev;
struct linux_console_data *d = dev->platform_data;
static char old_c;
char c;
@@ -54,7 +45,7 @@ static int linux_console_getc(struct console_device *cdev)
return c;
}
-static int linux_console_probe(struct device_d *dev)
+static int linux_console_probe(struct device *dev)
{
struct console_device *cdev;
struct linux_console_data *data = dev->platform_data;
@@ -76,7 +67,7 @@ static int linux_console_probe(struct device_d *dev)
return 0;
}
-static struct driver_d linux_console_driver = {
+static struct driver linux_console_driver = {
.name = "console",
.probe = linux_console_probe,
};
diff --git a/drivers/serial/serial_altera.c b/drivers/serial/serial_altera.c
deleted file mode 100644
index 51dcf8c790..0000000000
--- a/drivers/serial/serial_altera.c
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * (C) Copyright 2011, Franck JULLIEN, <elec4fun@gmail.com>
- *
- * 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, or (at your option) any later version.
- *
- * 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 <common.h>
-#include <driver.h>
-#include <init.h>
-#include <malloc.h>
-#include <io.h>
-#include <asm/nios2-io.h>
-
-struct altera_serial_priv {
- struct console_device cdev;
- void __iomem *regs;
-};
-
-static int altera_serial_setbaudrate(struct console_device *cdev, int baudrate)
-{
- struct altera_serial_priv *priv = container_of(cdev,
- struct altera_serial_priv, cdev);
-
- struct nios_uart *uart = priv->regs;
- uint16_t div;
-
- div = (CPU_FREQ / baudrate) - 1;
- writew(div, &uart->divisor);
-
- return 0;
-}
-
-static void altera_serial_putc(struct console_device *cdev, char c)
-{
- struct altera_serial_priv *priv = container_of(cdev,
- struct altera_serial_priv, cdev);
-
- struct nios_uart *uart = priv->regs;
-
- while ((readw(&uart->status) & NIOS_UART_TRDY) == 0);
-
- writew(c, &uart->txdata);
-}
-
-static int altera_serial_tstc(struct console_device *cdev)
-{
- struct altera_serial_priv *priv = container_of(cdev,
- struct altera_serial_priv, cdev);
-
- struct nios_uart *uart = priv->regs;
-
- return readw(&uart->status) & NIOS_UART_RRDY;
-}
-
-static int altera_serial_getc(struct console_device *cdev)
-{
- struct altera_serial_priv *priv = container_of(cdev,
- struct altera_serial_priv, cdev);
-
- struct nios_uart *uart = priv->regs;
-
- while (altera_serial_tstc(cdev) == 0);
-
- return readw(&uart->rxdata) & 0x000000FF;
-}
-
-static int altera_serial_probe(struct device_d *dev)
-{
- struct resource *iores;
- struct console_device *cdev;
- struct altera_serial_priv *priv;
-
- priv = xzalloc(sizeof(*priv));
- cdev = &priv->cdev;
-
- iores = dev_request_mem_resource(dev, 0);
- if (IS_ERR(iores))
- return PTR_ERR(iores);
- priv->regs = IOMEM(iores->start);
- cdev->dev = dev;
- cdev->tstc = altera_serial_tstc;
- cdev->putc = altera_serial_putc;
- cdev->getc = altera_serial_getc;
- cdev->setbrg = altera_serial_setbaudrate;
-
- console_register(cdev);
-
- return 0;
-}
-
-static struct driver_d altera_serial_driver = {
- .name = "altera_serial",
- .probe = altera_serial_probe,
-};
-console_platform_driver(altera_serial_driver);
diff --git a/drivers/serial/serial_altera_jtag.c b/drivers/serial/serial_altera_jtag.c
deleted file mode 100644
index 1c485ed316..0000000000
--- a/drivers/serial/serial_altera_jtag.c
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * (C) Copyright 2004, Psyent Corporation <www.psyent.com>
- * Scott McNutt <smcnutt@psyent.com>
- *
- * (C) Copyright 2011 - Franck JULLIEN <elec4fun@gmail.com>
- *
- * 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, or (at your option) any later version.
- *
- * 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 <common.h>
-#include <driver.h>
-#include <init.h>
-#include <malloc.h>
-#include <io.h>
-#include <asm/nios2-io.h>
-
-struct altera_serial_jtag_priv {
- struct console_device cdev;
- void __iomem *regs;
-};
-
-
-static int altera_serial_jtag_setbaudrate(struct console_device *cdev, int baudrate)
-{
- return 0;
-}
-
-static void altera_serial_jtag_putc(struct console_device *cdev, char c)
-{
- struct altera_serial_jtag_priv *priv = container_of(cdev,
- struct altera_serial_jtag_priv, cdev);
-
- struct nios_jtag *jtag = priv->regs;
- uint32_t st;
-
- while (1) {
- st = readl(&jtag->control);
- if (NIOS_JTAG_WSPACE(st))
- break;
- }
-
- writel(c, &jtag->data);
-}
-
-static int altera_serial_jtag_tstc(struct console_device *cdev)
-{
- struct altera_serial_jtag_priv *priv = container_of(cdev,
- struct altera_serial_jtag_priv, cdev);
-
- struct nios_jtag *jtag = priv->regs;
-
- return readl(&jtag->control) & NIOS_JTAG_RRDY;
-}
-
-static int altera_serial_jtag_getc(struct console_device *cdev)
-{
- struct altera_serial_jtag_priv *priv = container_of(cdev,
- struct altera_serial_jtag_priv, cdev);
-
- struct nios_jtag *jtag = priv->regs;
- uint32_t val;
-
- while (1) {
- val = readl(&jtag->data);
- if (val & NIOS_JTAG_RVALID)
- break;
- }
-
- return val & 0xFF;
-}
-
-static int altera_serial_jtag_probe(struct device_d *dev) {
- struct resource *iores;
-
- struct console_device *cdev;
- struct altera_serial_jtag_priv *priv;
-
- priv = xzalloc(sizeof(*priv));
- cdev = &priv->cdev;
-
- iores = dev_request_mem_resource(dev, 0);
- if (IS_ERR(iores))
- return PTR_ERR(iores);
- priv->regs = IOMEM(iores->start);
- cdev->dev = dev;
- cdev->tstc = altera_serial_jtag_tstc;
- cdev->putc = altera_serial_jtag_putc;
- cdev->getc = altera_serial_jtag_getc;
- cdev->setbrg = altera_serial_jtag_setbaudrate;
-
- console_register(cdev);
-
- return 0;
-}
-
-static struct driver_d altera_serial_jtag_driver = {
- .name = "altera_serial_jtag",
- .probe = altera_serial_jtag_probe,
-};
-console_platform_driver(altera_serial_jtag_driver);
diff --git a/drivers/serial/serial_ar933x.c b/drivers/serial/serial_ar933x.c
index 32ad1ba463..f5595ec1ee 100644
--- a/drivers/serial/serial_ar933x.c
+++ b/drivers/serial/serial_ar933x.c
@@ -1,16 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
* based on linux.git/drivers/tty/serial/serial_ar933x.c
- *
- * 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, or (at your option) any later version.
- *
- * 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 <common.h>
@@ -151,7 +141,7 @@ static int ar933x_serial_getc(struct console_device *cdev)
return rdata & AR933X_UART_DATA_TX_RX_MASK;
}
-static int ar933x_serial_probe(struct device_d *dev)
+static int ar933x_serial_probe(struct device *dev)
{
struct resource *iores;
struct console_device *cdev;
@@ -198,8 +188,9 @@ static struct of_device_id ar933x_serial_dt_ids[] = {
/* sentinel */
},
};
+MODULE_DEVICE_TABLE(of, ar933x_serial_dt_ids);
-static struct driver_d ar933x_serial_driver = {
+static struct driver ar933x_serial_driver = {
.name = "ar933x_serial",
.probe = ar933x_serial_probe,
.of_compatible = DRV_OF_COMPAT(ar933x_serial_dt_ids),
diff --git a/drivers/serial/serial_ar933x.h b/drivers/serial/serial_ar933x.h
index f55f0fa3d7..d73e77a603 100644
--- a/drivers/serial/serial_ar933x.h
+++ b/drivers/serial/serial_ar933x.h
@@ -1,11 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Atheros AR933X UART defines
*
* Copyright (C) 2011 Gabor Juhos <juhosg@openwrt.org>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published
- * by the Free Software Foundation.
*/
#ifndef __AR933X_UART_H
diff --git a/drivers/serial/serial_auart.c b/drivers/serial/serial_auart.c
index ee64f2f8db..217ac5c891 100644
--- a/drivers/serial/serial_auart.c
+++ b/drivers/serial/serial_auart.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
* (C) 2013 Marc Kleine-Budde <mkl@pengutronix.de>
*
@@ -23,17 +24,6 @@
*
* Copyright 2008-2010 Freescale Semiconductor, Inc.
* Copyright 2008 Embedded Alley Solutions, Inc 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, or
- * (at your option) any later version.
- *
- * 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 <common.h>
@@ -46,8 +36,6 @@
#include <linux/clk.h>
#include <linux/err.h>
-#include <mach/clock.h>
-
#define HW_UARTAPP_CTRL0 (0x00000000)
#define HW_UARTAPP_CTRL2 (0x00000020)
@@ -178,7 +166,7 @@ static void auart_serial_init_port(struct auart_priv *priv)
writel(0x0, priv->base + HW_UARTAPP_INTR);
}
-static int auart_serial_probe(struct device_d *dev)
+static int auart_serial_probe(struct device *dev)
{
struct resource *iores;
struct auart_priv *priv;
@@ -228,8 +216,9 @@ static const __maybe_unused struct of_device_id auart_serial_dt_ids[] = {
/* sentinel */
}
};
+MODULE_DEVICE_TABLE(of, auart_serial_dt_ids);
-static struct driver_d auart_serial_driver = {
+static struct driver auart_serial_driver = {
.name = "auart_serial",
.probe = auart_serial_probe,
.of_compatible = DRV_OF_COMPAT(auart_serial_dt_ids),
diff --git a/drivers/serial/serial_cadence.c b/drivers/serial/serial_cadence.c
index e86dccbbc1..ee162e541a 100644
--- a/drivers/serial/serial_cadence.c
+++ b/drivers/serial/serial_cadence.c
@@ -1,16 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
* (c) 2012 Steffen Trumtrar <s.trumtrar@pengutronix.de>
- *
- * 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, or
- * (at your option) any later version.
- *
- * 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 <common.h>
@@ -183,7 +173,7 @@ static int cadence_clocksource_clock_change(struct notifier_block *nb,
return 0;
}
-static int cadence_serial_probe(struct device_d *dev)
+static int cadence_serial_probe(struct device *dev)
{
struct resource *iores;
struct console_device *cdev;
@@ -241,9 +231,16 @@ static __maybe_unused struct of_device_id cadence_serial_dt_ids[] = {
.compatible = "xlnx,xuartps",
.data = &cadence_r1p08_data,
}, {
+ .compatible = "cdns,uart-r1p12",
+ .data = &cadence_r1p08_data,
+ }, {
+ .compatible = "xlnx,zynqmp-uart",
+ .data = &cadence_r1p08_data,
+ }, {
/* sentinel */
}
};
+MODULE_DEVICE_TABLE(of, cadence_serial_dt_ids);
static struct platform_device_id cadence_serial_ids[] = {
{
@@ -254,7 +251,7 @@ static struct platform_device_id cadence_serial_ids[] = {
},
};
-static struct driver_d cadence_serial_driver = {
+static struct driver cadence_serial_driver = {
.name = "cadence_serial",
.probe = cadence_serial_probe,
.of_compatible = DRV_OF_COMPAT(cadence_serial_dt_ids),
diff --git a/drivers/serial/serial_clps711x.c b/drivers/serial/serial_clps711x.c
index 294c88b92f..2a284909bf 100644
--- a/drivers/serial/serial_clps711x.c
+++ b/drivers/serial/serial_clps711x.c
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: GPL-2.0+
+// SPDX-License-Identifier: GPL-2.0-or-later
/* Author: Alexander Shiyan <shc_work@mail.ru> */
#include <common.h>
@@ -8,6 +8,7 @@
#include <linux/clk.h>
#include <linux/err.h>
#include <mfd/syscon.h>
+#include <linux/regmap.h>
#define UARTDR 0x00
# define UARTDR_FRMERR (1 << 8)
@@ -35,7 +36,7 @@
struct clps711x_uart {
void __iomem *base;
- void __iomem *syscon;
+ struct regmap *regmap;
struct clk *uart_clk;
struct console_device cdev;
};
@@ -61,8 +62,7 @@ static void clps711x_init_port(struct console_device *cdev)
u32 tmp;
/* Disable the UART */
- tmp = readl(s->syscon + SYSCON);
- writel(tmp & ~SYSCON_UARTEN, s->syscon + SYSCON);
+ regmap_update_bits(s->regmap, SYSCON, SYSCON_UARTEN, 0);
/* Setup Line Control Register */
tmp = readl(s->base + UBRLCR) & UBRLCR_BAUD_MASK;
@@ -70,17 +70,19 @@ static void clps711x_init_port(struct console_device *cdev)
writel(tmp, s->base + UBRLCR);
/* Enable the UART */
- tmp = readl(s->syscon + SYSCON);
- writel(tmp | SYSCON_UARTEN, s->syscon + SYSCON);
+ regmap_update_bits(s->regmap, SYSCON, SYSCON_UARTEN, SYSCON_UARTEN);
}
static void clps711x_putc(struct console_device *cdev, char c)
{
struct clps711x_uart *s = cdev->dev->priv;
+ u32 tmp;
/* Wait until there is space in the FIFO */
do {
- } while (readl(s->syscon + SYSFLG) & SYSFLG_UTXFF);
+ regmap_read(s->regmap, SYSFLG, &tmp);
+
+ } while (tmp & SYSFLG_UTXFF);
/* Send the character */
writew(c, s->base + UARTDR);
@@ -90,10 +92,12 @@ static int clps711x_getc(struct console_device *cdev)
{
struct clps711x_uart *s = cdev->dev->priv;
u16 data;
+ u32 tmp;
/* Wait until there is data in the FIFO */
do {
- } while (readl(s->syscon + SYSFLG) & SYSFLG_URXFE);
+ regmap_read(s->regmap, SYSFLG, &tmp);
+ } while (tmp & SYSFLG_URXFE);
data = readw(s->base + UARTDR);
@@ -107,32 +111,32 @@ static int clps711x_getc(struct console_device *cdev)
static int clps711x_tstc(struct console_device *cdev)
{
struct clps711x_uart *s = cdev->dev->priv;
+ u32 tmp;
+
+ regmap_read(s->regmap, SYSFLG, &tmp);
- return !(readl(s->syscon + SYSFLG) & SYSFLG_URXFE);
+ return !(tmp & SYSFLG_URXFE);
}
static void clps711x_flush(struct console_device *cdev)
{
struct clps711x_uart *s = cdev->dev->priv;
+ u32 tmp;
do {
- } while (readl(s->syscon + SYSFLG) & SYSFLG_UBUSY);
+ regmap_read(s->regmap, SYSFLG, &tmp);
+ } while (tmp & SYSFLG_UBUSY);
}
-static int clps711x_probe(struct device_d *dev)
+static int clps711x_probe(struct device *dev)
{
+ struct device_node *syscon;
struct clps711x_uart *s;
- int err, id = dev->id;
- char syscon_dev[8];
const char *devname;
-
- if (dev->device_node)
- id = of_alias_get_id(dev->device_node, "serial");
-
- if (id != 0 && id != 1)
- return -EINVAL;
+ int err;
s = xzalloc(sizeof(struct clps711x_uart));
+
s->uart_clk = clk_get(dev, NULL);
if (IS_ERR(s->uart_clk)) {
err = PTR_ERR(s->uart_clk);
@@ -140,19 +144,15 @@ static int clps711x_probe(struct device_d *dev)
}
s->base = dev_get_mem_region(dev, 0);
- if (IS_ERR(s->base))
- return PTR_ERR(s->base);
-
- if (!dev->device_node) {
- sprintf(syscon_dev, "syscon%i", id + 1);
- s->syscon = syscon_base_lookup_by_pdevname(syscon_dev);
- } else {
- s->syscon = syscon_base_lookup_by_phandle(dev->device_node,
- "syscon");
+ if (IS_ERR(s->base)) {
+ err = PTR_ERR(s->base);
+ goto out_err;
}
- if (IS_ERR(s->syscon)) {
- err = PTR_ERR(s->syscon);
+ syscon = of_parse_phandle(dev->of_node, "syscon", 0);
+ s->regmap = syscon_node_to_regmap(syscon);
+ if (IS_ERR(s->regmap)) {
+ err = PTR_ERR(s->regmap);
goto out_err;
}
@@ -165,7 +165,7 @@ static int clps711x_probe(struct device_d *dev)
s->cdev.setbrg = clps711x_setbaudrate;
s->cdev.linux_console_name = "ttyCL";
- devname = of_alias_get(dev->device_node);
+ devname = of_alias_get(dev->of_node);
if (devname) {
s->cdev.devname = xstrdup(devname);
s->cdev.devid = DEVICE_ID_SINGLE;
@@ -182,12 +182,13 @@ out_err:
return err;
}
-static struct of_device_id __maybe_unused clps711x_uart_dt_ids[] = {
+static const struct of_device_id __maybe_unused clps711x_uart_dt_ids[] = {
{ .compatible = "cirrus,ep7209-uart", },
{ /* sentinel */ }
};
+MODULE_DEVICE_TABLE(of, clps711x_uart_dt_ids);
-static struct driver_d clps711x_driver = {
+static struct driver clps711x_driver = {
.name = "clps711x-uart",
.probe = clps711x_probe,
.of_compatible = DRV_OF_COMPAT(clps711x_uart_dt_ids),
diff --git a/drivers/serial/serial_digic.c b/drivers/serial/serial_digic.c
index d3cfa69e81..48e9cd3248 100644
--- a/drivers/serial/serial_digic.c
+++ b/drivers/serial/serial_digic.c
@@ -1,17 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (C) 2013, 2014 Antony Pavlov <antonynpavlov@gmail.com>
*
* This file is part of barebox.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License 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 <common.h>
@@ -19,7 +10,7 @@
#include <malloc.h>
#include <io.h>
-#include <mach/uart.h>
+#include <mach/digic/uart.h>
/*
* This driver is based on the "Serial terminal" docs here:
@@ -98,7 +89,7 @@ static int digic_serial_tstc(struct console_device *cdev)
*/
}
-static int digic_serial_probe(struct device_d *dev)
+static int digic_serial_probe(struct device *dev)
{
struct resource *iores;
struct console_device *cdev;
@@ -126,8 +117,9 @@ static __maybe_unused struct of_device_id digic_serial_dt_ids[] = {
/* sentinel */
}
};
+MODULE_DEVICE_TABLE(of, digic_serial_dt_ids);
-static struct driver_d digic_serial_driver = {
+static struct driver digic_serial_driver = {
.name = "digic-uart",
.probe = digic_serial_probe,
.of_compatible = DRV_OF_COMPAT(digic_serial_dt_ids),
diff --git a/drivers/serial/serial_efi.c b/drivers/serial/serial_efi.c
index 667d51f622..6ed068f159 100644
--- a/drivers/serial/serial_efi.c
+++ b/drivers/serial/serial_efi.c
@@ -1,7 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (C) 2017 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
- *
- * Under GPLv2 Only
*/
#include <common.h>
@@ -9,7 +8,7 @@
#include <init.h>
#include <malloc.h>
#include <efi.h>
-#include <efi/efi.h>
+#include <efi/efi-payload.h>
#include <efi/efi-device.h>
/*
diff --git a/drivers/serial/serial_imx.c b/drivers/serial/serial_imx.c
index d1329ca1eb..0f91028605 100644
--- a/drivers/serial/serial_imx.c
+++ b/drivers/serial/serial_imx.c
@@ -1,17 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
* (c) 2004 Sascha Hauer <sascha@saschahauer.de>
- *
- * 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, or
- * (at your option) any later version.
- *
- * 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 <common.h>
@@ -208,7 +197,7 @@ static int imx_clocksource_clock_change(struct notifier_block *nb,
return 0;
}
-static int imx_serial_probe(struct device_d *dev)
+static int imx_serial_probe(struct device *dev)
{
struct resource *iores;
struct console_device *cdev;
@@ -245,19 +234,21 @@ static int imx_serial_probe(struct device_d *dev)
cdev->flush = imx_serial_flush;
cdev->setbrg = imx_serial_setbaudrate;
cdev->linux_console_name = "ttymxc";
- if (dev->device_node) {
- devname = of_alias_get(dev->device_node);
+ cdev->linux_earlycon_name = "ec_imx6q";
+ cdev->phys_base = priv->regs;
+ if (dev->of_node) {
+ devname = of_alias_get(dev->of_node);
if (devname) {
cdev->devname = xstrdup(devname);
cdev->devid = DEVICE_ID_SINGLE;
}
}
- if (of_property_read_bool(dev->device_node, "fsl,dte-mode"))
+ if (of_property_read_bool(dev->of_node, "fsl,dte-mode"))
priv->dte_mode = 1;
- if (of_property_read_bool(dev->device_node, "linux,rs485-enabled-at-boot-time") &&
- !of_property_read_bool(dev->device_node, "rs485-rts-active-low"))
+ if (of_property_read_bool(dev->of_node, "linux,rs485-enabled-at-boot-time") &&
+ !of_property_read_bool(dev->of_node, "rs485-rts-active-low"))
priv->rs485_mode = 1;
imx_serial_init_port(cdev);
@@ -308,6 +299,7 @@ static __maybe_unused struct of_device_id imx_serial_dt_ids[] = {
/* sentinel */
}
};
+MODULE_DEVICE_TABLE(of, imx_serial_dt_ids);
static struct platform_device_id imx_serial_ids[] = {
{
@@ -321,7 +313,7 @@ static struct platform_device_id imx_serial_ids[] = {
},
};
-static struct driver_d imx_serial_driver = {
+static struct driver imx_serial_driver = {
.name = "imx_serial",
.probe = imx_serial_probe,
.of_compatible = DRV_OF_COMPAT(imx_serial_dt_ids),
diff --git a/drivers/serial/serial_litex.c b/drivers/serial/serial_litex.c
index 8562a45ecc..04da556f6a 100644
--- a/drivers/serial/serial_litex.c
+++ b/drivers/serial/serial_litex.c
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: GPL-2.0
+// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (C) 2019 Antony Pavlov <antonynpavlov@gmail.com>
*
@@ -58,7 +58,7 @@ static int litex_serial_tstc(struct console_device *cdev)
return !litex_serial_readb(cdev, UART_RXEMPTY);
}
-static int litex_serial_probe(struct device_d *dev)
+static int litex_serial_probe(struct device *dev)
{
struct resource *iores;
struct console_device *cdev;
@@ -74,6 +74,9 @@ static int litex_serial_probe(struct device_d *dev)
cdev->putc = &litex_serial_putc;
cdev->getc = &litex_serial_getc;
cdev->setbrg = NULL;
+ cdev->linux_console_name = "ttyLXU";
+ cdev->linux_earlycon_name = "liteuart";
+ cdev->phys_base = IOMEM(iores->start);
console_register(cdev);
@@ -87,8 +90,9 @@ static __maybe_unused struct of_device_id litex_serial_dt_ids[] = {
/* sentinel */
}
};
+MODULE_DEVICE_TABLE(of, litex_serial_dt_ids);
-static struct driver_d litex_serial_driver = {
+static struct driver litex_serial_driver = {
.name = "litex-uart",
.probe = litex_serial_probe,
.of_compatible = DRV_OF_COMPAT(litex_serial_dt_ids),
diff --git a/drivers/serial/serial_lpuart.c b/drivers/serial/serial_lpuart.c
index bfc3a13672..828a0dd0bb 100644
--- a/drivers/serial/serial_lpuart.c
+++ b/drivers/serial/serial_lpuart.c
@@ -1,18 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2016 Zodiac Inflight Innovation
* Author: Andrey Smirnov <andrew.smirnov@gmail.com>
*
* Based on analogous driver from U-Boot
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License 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 <common.h>
@@ -122,7 +113,7 @@ static int lpuart_clocksource_clock_change(struct notifier_block *nb,
return lpuart_serial_setbaudrate(&lpuart->cdev, lpuart->baudrate);
}
-static int lpuart_serial_probe(struct device_d *dev)
+static int lpuart_serial_probe(struct device *dev)
{
int ret;
struct console_device *cdev;
@@ -160,8 +151,8 @@ static int lpuart_serial_probe(struct device_d *dev)
cdev->flush = lpuart_serial_flush;
cdev->setbrg = lpuart_serial_setbaudrate;
- if (dev->device_node) {
- devname = of_alias_get(dev->device_node);
+ if (dev->of_node) {
+ devname = of_alias_get(dev->of_node);
if (devname) {
cdev->devname = xstrdup(devname);
cdev->devid = DEVICE_ID_SINGLE;
@@ -169,6 +160,8 @@ static int lpuart_serial_probe(struct device_d *dev)
}
cdev->linux_console_name = "ttyLP";
+ cdev->linux_earlycon_name = "lpuart";
+ cdev->phys_base = lpuart->base;
lpuart_setup(lpuart->base, clk_get_rate(lpuart->clk));
@@ -193,8 +186,9 @@ static struct of_device_id lpuart_serial_dt_ids[] = {
{ .compatible = "fsl,vf610-lpuart" },
{}
};
+MODULE_DEVICE_TABLE(of, lpuart_serial_dt_ids);
-static struct driver_d lpuart_serial_driver = {
+static struct driver lpuart_serial_driver = {
.name = "lpuart-serial",
.probe = lpuart_serial_probe,
.of_compatible = DRV_OF_COMPAT(lpuart_serial_dt_ids),
diff --git a/drivers/serial/serial_lpuart32.c b/drivers/serial/serial_lpuart32.c
new file mode 100644
index 0000000000..09d4b620be
--- /dev/null
+++ b/drivers/serial/serial_lpuart32.c
@@ -0,0 +1,188 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2023 Pengutronix
+ */
+
+#include <common.h>
+#include <driver.h>
+#include <init.h>
+#include <malloc.h>
+#include <notifier.h>
+#include <io.h>
+#include <of.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <serial/lpuart32.h>
+
+struct lpuart32_devtype_data {
+ unsigned int reg_offs;
+};
+
+struct lpuart32 {
+ struct console_device cdev;
+ int baudrate;
+ int dte_mode;
+ struct notifier_block notify;
+ struct resource *io;
+ void __iomem *base;
+ struct clk *clk;
+};
+
+static struct lpuart32 *cdev_to_lpuart32(struct console_device *cdev)
+{
+ return container_of(cdev, struct lpuart32, cdev);
+}
+
+static void lpuart32_enable(struct lpuart32 *lpuart32)
+{
+ writel(LPUART32_UARTCTRL_TE | LPUART32_UARTCTRL_RE,
+ lpuart32->base + LPUART32_UARTCTRL);
+}
+
+static void lpuart32_disable(struct lpuart32 *lpuart32)
+{
+ writel(0, lpuart32->base + LPUART32_UARTCTRL);
+}
+
+/* Test whether a character is in the RX buffer */
+static int lpuart32_serial_tstc(struct console_device *cdev)
+{
+ struct lpuart32 *lpuart32 = cdev_to_lpuart32(cdev);
+
+ if (readl(lpuart32->base + LPUART32_UARTSTAT) & LPUART32_UARTSTAT_OR)
+ writel(LPUART32_UARTSTAT_OR, lpuart32->base + LPUART32_UARTSTAT);
+
+ return readl(lpuart32->base + LPUART32_UARTSTAT) & LPUART32_UARTSTAT_RDRF;
+}
+
+static int lpuart32_serial_setbaudrate(struct console_device *cdev,
+ int baudrate)
+{
+ struct lpuart32 *lpuart32 = cdev_to_lpuart32(cdev);
+
+ lpuart32_disable(lpuart32);
+
+ /*
+ * We treat baudrate of 0 as a request to disable UART
+ */
+ if (baudrate) {
+ lpuart32_setbrg(lpuart32->base, clk_get_rate(lpuart32->clk),
+ baudrate);
+ lpuart32_enable(lpuart32);
+ }
+
+ lpuart32->baudrate = baudrate;
+
+ return 0;
+}
+
+static int lpuart32_serial_getc(struct console_device *cdev)
+{
+ struct lpuart32 *lpuart32 = cdev_to_lpuart32(cdev);
+
+ while (!lpuart32_serial_tstc(cdev));
+
+ return readl(lpuart32->base + LPUART32_UARTDATA) & 0xff;
+}
+
+static void lpuart32_serial_putc(struct console_device *cdev, char c)
+{
+ struct lpuart32 *lpuart32 = cdev_to_lpuart32(cdev);
+
+ lpuart32_putc(lpuart32->base, c);
+}
+
+static void lpuart32_serial_flush(struct console_device *cdev)
+{
+}
+
+static int lpuart32_serial_probe(struct device *dev)
+{
+ int ret;
+ struct console_device *cdev;
+ struct lpuart32 *lpuart32;
+ const char *devname;
+ struct lpuart32_devtype_data *devtype;
+
+ ret = dev_get_drvdata(dev, (const void **)&devtype);
+ if (ret)
+ return ret;
+
+ lpuart32 = xzalloc(sizeof(*lpuart32));
+ cdev = &lpuart32->cdev;
+ dev->priv = lpuart32;
+
+ lpuart32->io = dev_request_mem_resource(dev, 0);
+ if (IS_ERR(lpuart32->io)) {
+ ret = PTR_ERR(lpuart32->io);
+ goto err_free;
+ }
+ lpuart32->base = IOMEM(lpuart32->io->start) + devtype->reg_offs;
+
+ lpuart32->clk = clk_get(dev, NULL);
+ if (IS_ERR(lpuart32->clk)) {
+ ret = PTR_ERR(lpuart32->clk);
+ dev_err(dev, "Failed to get UART clock %d\n", ret);
+ goto io_release;
+ }
+
+ ret = clk_enable(lpuart32->clk);
+ if (ret) {
+ dev_err(dev, "Failed to enable UART clock %d\n", ret);
+ goto io_release;
+ }
+
+ cdev->dev = dev;
+ cdev->tstc = lpuart32_serial_tstc;
+ cdev->putc = lpuart32_serial_putc;
+ cdev->getc = lpuart32_serial_getc;
+ cdev->flush = lpuart32_serial_flush;
+ cdev->setbrg = lpuart32_serial_setbaudrate;
+
+ if (dev->of_node) {
+ devname = of_alias_get(dev->of_node);
+ if (devname) {
+ cdev->devname = xstrdup(devname);
+ cdev->devid = DEVICE_ID_SINGLE;
+ }
+ }
+
+ cdev->linux_console_name = "ttyLP";
+ cdev->linux_earlycon_name = "lpuart";
+ cdev->phys_base = lpuart32->base;
+
+ lpuart32_setup(lpuart32->base, clk_get_rate(lpuart32->clk));
+
+ ret = console_register(cdev);
+ if (!ret)
+ return 0;
+
+ clk_put(lpuart32->clk);
+io_release:
+ release_region(lpuart32->io);
+err_free:
+ free(lpuart32);
+
+ return ret;
+}
+
+static struct lpuart32_devtype_data imx7ulp_data = {
+ .reg_offs = 0x10,
+};
+
+static struct of_device_id lpuart32_serial_dt_ids[] = {
+ {
+ .compatible = "fsl,imx7ulp-lpuart",
+ .data = &imx7ulp_data,
+ }, {
+ /* sentinel */
+ }
+};
+MODULE_DEVICE_TABLE(of, lpuart32_serial_dt_ids);
+
+static struct driver lpuart32_serial_driver = {
+ .name = "lpuart32-serial",
+ .probe = lpuart32_serial_probe,
+ .of_compatible = DRV_OF_COMPAT(lpuart32_serial_dt_ids),
+};
+console_platform_driver(lpuart32_serial_driver);
diff --git a/drivers/serial/serial_mpc5xxx.c b/drivers/serial/serial_mpc5xxx.c
index 742af27650..4408de9e91 100644
--- a/drivers/serial/serial_mpc5xxx.c
+++ b/drivers/serial/serial_mpc5xxx.c
@@ -1,18 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
* (C) Copyright 2000 - 2003
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
- * 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, or (at your option) any later version.
- *
- * 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.
- *
- *
* Hacked for MPC8260 by Murray.Jensen@cmst.csiro.au, 19-Oct-00, with
* changes based on the file arch/ppc/mbxboot/m8260_tty.c from the
* Linux/PPC sources (m8260_tty.c had no copyright info in it).
@@ -56,7 +46,7 @@ static int __mpc5xxx_serial_setbaudrate(struct mpc5xxx_psc *psc, int baudrate)
static int mpc5xxx_serial_setbaudrate(struct console_device *cdev, int baudrate)
{
- struct device_d *dev = cdev->dev;
+ struct device *dev = cdev->dev;
struct mpc5xxx_psc *psc = dev->priv;
__mpc5xxx_serial_setbaudrate(psc, baudrate);
@@ -100,7 +90,7 @@ static int __mpc5xxx_serial_init(struct mpc5xxx_psc *psc)
static int mpc5xxx_serial_init(struct console_device *cdev)
{
- struct device_d *dev = cdev->dev;
+ struct device *dev = cdev->dev;
struct mpc5xxx_psc *psc = dev->priv;
__mpc5xxx_serial_init(psc);
@@ -110,7 +100,7 @@ static int mpc5xxx_serial_init(struct console_device *cdev)
static void mpc5xxx_serial_putc (struct console_device *cdev, const char c)
{
- struct device_d *dev = cdev->dev;
+ struct device *dev = cdev->dev;
struct mpc5xxx_psc *psc = dev->priv;
/* Wait for last character to go. */
@@ -122,7 +112,7 @@ static void mpc5xxx_serial_putc (struct console_device *cdev, const char c)
static int mpc5xxx_serial_getc (struct console_device *cdev)
{
- struct device_d *dev = cdev->dev;
+ struct device *dev = cdev->dev;
struct mpc5xxx_psc *psc = dev->priv;
/* Wait for a character to arrive. */
@@ -134,13 +124,13 @@ static int mpc5xxx_serial_getc (struct console_device *cdev)
static int mpc5xxx_serial_tstc (struct console_device *cdev)
{
- struct device_d *dev = cdev->dev;
+ struct device *dev = cdev->dev;
struct mpc5xxx_psc *psc = dev->priv;
return (psc->psc_status & PSC_SR_RXRDY);
}
-static int mpc5xxx_serial_probe(struct device_d *dev)
+static int mpc5xxx_serial_probe(struct device *dev)
{
struct resource *iores;
struct console_device *cdev;
@@ -163,7 +153,7 @@ static int mpc5xxx_serial_probe(struct device_d *dev)
return 0;
}
-static struct driver_d mpc5xxx_serial_driver = {
+static struct driver mpc5xxx_serial_driver = {
.name = "mpc5xxx_serial",
.probe = mpc5xxx_serial_probe,
};
diff --git a/drivers/serial/serial_ns16550.c b/drivers/serial/serial_ns16550.c
index fc6fa7dc3e..1b1692658f 100644
--- a/drivers/serial/serial_ns16550.c
+++ b/drivers/serial/serial_ns16550.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/**
* @file
* @brief NS16550 Driver implementation
@@ -16,17 +17,6 @@
*
* (C) Copyright 2000
* Rob Taylor, Flying Pig Systems. robt@flyingpig.com.
- *
- * 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, or (at your option) any later version.
- *
- * 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 <common.h>
@@ -49,11 +39,18 @@ struct ns16550_priv {
unsigned iobase;
void (*write_reg)(struct ns16550_priv *, uint8_t val, unsigned offset);
uint8_t (*read_reg)(struct ns16550_priv *, unsigned offset);
+ const char *access_type;
+
+ bool rs485_mode;
+ bool rs485_rts_active_low;
+ bool rs485_rx_during_tx;
};
struct ns16550_drvdata {
void (*init_port)(struct console_device *cdev);
const char *linux_console_name;
+ const char *linux_earlycon_name;
+ unsigned int clk_default;
};
static inline struct ns16550_priv *to_ns16550_priv(struct console_device *cdev)
@@ -179,7 +176,6 @@ static inline unsigned int ns16550_calc_divisor(struct console_device *cdev,
unsigned int clk = plat->clock;
return (clk / MODE_X_DIV / baudrate);
-
}
/**
@@ -250,14 +246,10 @@ static void ns16550_jz_init_port(struct console_device *cdev)
ns16550_serial_init_port(cdev);
}
-#define BCM2836_AUX_CLOCK_ENB 0x3f215004 /* BCM2835 AUX Clock enable register */
-#define BCM2836_AUX_CLOCK_EN_UART BIT(0) /* Bit 0 enables the Miniuart */
-
static void rpi_init_port(struct console_device *cdev)
{
struct ns16550_priv *priv = to_ns16550_priv(cdev);
- writeb(BCM2836_AUX_CLOCK_EN_UART, BCM2836_AUX_CLOCK_ENB);
priv->plat.shift = 2;
/*
* We double the clock rate since the 16550 will divide by 16
@@ -277,9 +269,37 @@ static void rpi_init_port(struct console_device *cdev)
*/
static void ns16550_putc(struct console_device *cdev, char c)
{
- /* Loop Doing Nothing */
- while ((ns16550_read(cdev, lsr) & LSR_THRE) == 0) ;
+ struct ns16550_priv *priv = to_ns16550_priv(cdev);
+
+ /* wait until FIFO can accept at least one byte */
+ while ((ns16550_read(cdev, lsr) & (LSR_THRE)) != (LSR_THRE))
+ ;
+
+ if (priv->rs485_mode) {
+ if (priv->rs485_rts_active_low)
+ ns16550_write(cdev, MCR_RTS, mcr);
+ else
+ ns16550_write(cdev, 0, mcr);
+
+ if (!priv->rs485_rx_during_tx)
+ ns16550_write(cdev, CNTL_TXEN, cntl);
+ }
+
ns16550_write(cdev, c, thr);
+
+ if (priv->rs485_mode) {
+ /* wait until FIFO is cleared*/
+ while ((ns16550_read(cdev, lsr) & (LSR_EMPTY)) != (LSR_EMPTY))
+ ;
+
+ if (priv->rs485_rts_active_low)
+ ns16550_write(cdev, 0, mcr);
+ else
+ ns16550_write(cdev, MCR_RTS, mcr);
+
+ if (!priv->rs485_rx_during_tx)
+ ns16550_write(cdev, CNTL_TXEN | CNTL_RXEN, cntl);
+ }
}
/**
@@ -319,13 +339,13 @@ static void ns16550_flush(struct console_device *cdev)
while ((ns16550_read(cdev, lsr) & LSR_TEMT) == 0) ;
}
-static void ns16550_probe_dt(struct device_d *dev, struct ns16550_priv *priv)
+static void ns16550_probe_dt(struct device *dev, struct ns16550_priv *priv)
{
- struct device_node *np = dev->device_node;
+ struct device_node *np = dev_of_node(dev);
u32 offset;
u32 width = 1;
- if (!IS_ENABLED(CONFIG_OFDEVICE))
+ if (!np)
return;
of_property_read_u32(np, "clock-frequency", &priv->plat.clock);
@@ -333,22 +353,33 @@ static void ns16550_probe_dt(struct device_d *dev, struct ns16550_priv *priv)
priv->mmiobase += offset;
of_property_read_u32(np, "reg-shift", &priv->plat.shift);
of_property_read_u32(np, "reg-io-width", &width);
+ priv->rs485_rts_active_low =
+ of_property_read_bool(np, "rs485-rts-active-low");
+ priv->rs485_mode =
+ of_property_read_bool(np, "linux,rs485-enabled-at-boot-time");
+ priv->rs485_rx_during_tx =
+ of_property_read_bool(np, "rs485-rx-during-tx");
+
switch (width) {
case 1:
priv->read_reg = ns16550_read_reg_mmio_8;
priv->write_reg = ns16550_write_reg_mmio_8;
+ priv->access_type = "mmio";
break;
case 2:
priv->read_reg = ns16550_read_reg_mmio_16;
priv->write_reg = ns16550_write_reg_mmio_16;
+ priv->access_type = "mmio16";
break;
case 4:
if (of_device_is_big_endian(np)) {
priv->read_reg = ns16550_read_reg_mmio_32be;
priv->write_reg = ns16550_write_reg_mmio_32be;
+ priv->access_type = "mmio32be";
} else {
priv->read_reg = ns16550_read_reg_mmio_32;
priv->write_reg = ns16550_write_reg_mmio_32;
+ priv->access_type = "mmio32";
}
break;
default:
@@ -360,98 +391,101 @@ static void ns16550_probe_dt(struct device_d *dev, struct ns16550_priv *priv)
static struct ns16550_drvdata ns16450_drvdata = {
.init_port = ns16450_serial_init_port,
.linux_console_name = "ttyS",
+ .linux_earlycon_name = "uart8250",
};
static struct ns16550_drvdata ns16550_drvdata = {
.init_port = ns16550_serial_init_port,
.linux_console_name = "ttyS",
+ .linux_earlycon_name = "uart8250",
};
static __maybe_unused struct ns16550_drvdata omap_drvdata = {
.init_port = ns16550_omap_init_port,
.linux_console_name = "ttyO",
+ .linux_earlycon_name = "omap8250",
};
-static __maybe_unused struct ns16550_drvdata jz_drvdata = {
- .init_port = ns16550_jz_init_port,
+static __maybe_unused struct ns16550_drvdata omap_clk48m_drvdata = {
+ .init_port = ns16550_omap_init_port,
+ .linux_console_name = "ttyO",
+ .clk_default = 48000000,
};
-static __maybe_unused struct ns16550_drvdata tegra_drvdata = {
- .init_port = ns16550_serial_init_port,
- .linux_console_name = "ttyS",
+static __maybe_unused struct ns16550_drvdata jz_drvdata = {
+ .init_port = ns16550_jz_init_port,
+ .linux_earlycon_name = "jz4740_uart",
};
static __maybe_unused struct ns16550_drvdata rpi_drvdata = {
.init_port = rpi_init_port,
.linux_console_name = "ttyS",
+ .linux_earlycon_name = "bcm2835aux",
};
-static int ns16550_init_iomem(struct device_d *dev, struct ns16550_priv *priv)
+/**
+ * @return the requested resource to be properly released in case probe fail
+ */
+static struct resource *ns16550_init_iores(struct device *dev, struct ns16550_priv *priv)
{
- struct resource *iores;
struct resource *res;
- int width;
+ struct resource *iores;
+ unsigned long flags;
res = dev_get_resource(dev, IORESOURCE_MEM, 0);
if (IS_ERR(res))
- return PTR_ERR(res);
+ res = dev_get_resource(dev, IORESOURCE_IO, 0);
+ if (IS_ERR(res))
+ return res;
+
+ flags = res->flags & (IORESOURCE_MEM_TYPE_MASK | IORESOURCE_IO);
- iores = dev_request_mem_resource(dev, 0);
+ if (flags & IORESOURCE_IO)
+ iores = request_ioport_region(dev_name(dev), res->start, res->end);
+ else
+ iores = request_iomem_region(dev_name(dev), res->start, res->end);
if (IS_ERR(iores))
- return PTR_ERR(iores);
- priv->mmiobase = IOMEM(iores->start);
+ return iores;
- width = res->flags & IORESOURCE_MEM_TYPE_MASK;
- switch (width) {
+ if (flags & IORESOURCE_IO)
+ priv->iobase = iores->start;
+ else
+ priv->mmiobase = IOMEM(iores->start);
+
+ switch (flags) {
+ case IORESOURCE_IO | IORESOURCE_MEM_8BIT:
+ priv->read_reg = ns16550_read_reg_ioport_8;
+ priv->write_reg = ns16550_write_reg_ioport_8;
+ priv->access_type = "io";
+ break;
+ case IORESOURCE_IO | IORESOURCE_MEM_16BIT:
+ priv->read_reg = ns16550_read_reg_ioport_16;
+ priv->write_reg = ns16550_write_reg_ioport_16;
+ priv->access_type = "io";
+ break;
+ case IORESOURCE_IO | IORESOURCE_MEM_32BIT:
+ priv->read_reg = ns16550_read_reg_ioport_32;
+ priv->write_reg = ns16550_write_reg_ioport_32;
+ priv->access_type = "io";
+ break;
case IORESOURCE_MEM_8BIT:
priv->read_reg = ns16550_read_reg_mmio_8;
priv->write_reg = ns16550_write_reg_mmio_8;
+ priv->access_type = "mmio";
break;
case IORESOURCE_MEM_16BIT:
priv->read_reg = ns16550_read_reg_mmio_16;
priv->write_reg = ns16550_write_reg_mmio_16;
+ priv->access_type = "mmio16";
break;
case IORESOURCE_MEM_32BIT:
priv->read_reg = ns16550_read_reg_mmio_32;
priv->write_reg = ns16550_write_reg_mmio_32;
+ priv->access_type = "mmio32";
break;
}
- return 0;
-}
-
-static int ns16550_init_ioport(struct device_d *dev, struct ns16550_priv *priv)
-{
- struct resource *res;
- int width;
-
- res = dev_get_resource(dev, IORESOURCE_IO, 0);
- if (IS_ERR(res))
- return PTR_ERR(res);
-
- res = request_ioport_region(dev_name(dev), res->start, res->end);
- if (IS_ERR(res))
- return PTR_ERR(res);
-
- priv->iobase = res->start;
-
- width = res->flags & IORESOURCE_MEM_TYPE_MASK;
- switch (width) {
- case IORESOURCE_MEM_8BIT:
- priv->read_reg = ns16550_read_reg_ioport_8;
- priv->write_reg = ns16550_write_reg_ioport_8;
- break;
- case IORESOURCE_MEM_16BIT:
- priv->read_reg = ns16550_read_reg_ioport_16;
- priv->write_reg = ns16550_write_reg_ioport_16;
- break;
- case IORESOURCE_MEM_32BIT:
- priv->read_reg = ns16550_read_reg_ioport_32;
- priv->write_reg = ns16550_write_reg_ioport_32;
- break;
- }
-
- return 0;
+ return iores;
}
/**
@@ -463,45 +497,50 @@ static int ns16550_init_ioport(struct device_d *dev, struct ns16550_priv *priv)
* ENOMEM if calloc failed
* else return result of console_register
*/
-static int ns16550_probe(struct device_d *dev)
+static int ns16550_probe(struct device *dev)
{
struct ns16550_priv *priv;
struct console_device *cdev;
struct NS16550_plat *plat = (struct NS16550_plat *)dev->platform_data;
const struct ns16550_drvdata *devtype;
+ struct resource *iores;
int ret;
devtype = device_get_match_data(dev) ?: &ns16550_drvdata;
priv = xzalloc(sizeof(*priv));
- ret = ns16550_init_iomem(dev, priv);
- if (ret)
- ret = ns16550_init_ioport(dev, priv);
-
- if (ret)
- return ret;
+ iores = ns16550_init_iores(dev, priv);
+ if (IS_ERR(iores)) {
+ ret = PTR_ERR(iores);
+ goto err;
+ }
if (plat)
priv->plat = *plat;
else
ns16550_probe_dt(dev, priv);
+ if (devtype->clk_default && !priv->plat.clock)
+ priv->plat.clock = devtype->clk_default;
+
if (!priv->plat.clock) {
priv->clk = clk_get(dev, NULL);
if (IS_ERR(priv->clk)) {
ret = PTR_ERR(priv->clk);
dev_err(dev, "failed to get clk (%d)\n", ret);
- goto err;
+ goto release_region;
}
- clk_enable(priv->clk);
+ ret = clk_enable(priv->clk);
+ if (ret)
+ goto clk_put;
priv->plat.clock = clk_get_rate(priv->clk);
}
if (priv->plat.clock == 0) {
dev_err(dev, "no valid clockrate\n");
ret = -EINVAL;
- goto err;
+ goto clk_disable;
}
cdev = &priv->cdev;
@@ -512,13 +551,27 @@ static int ns16550_probe(struct device_d *dev)
cdev->setbrg = ns16550_setbaudrate;
cdev->flush = ns16550_flush;
cdev->linux_console_name = devtype->linux_console_name;
+ cdev->linux_earlycon_name = basprintf("%s,%s", devtype->linux_earlycon_name,
+ priv->access_type);
+ cdev->phys_base = !strcmp(priv->access_type, "io") ?
+ IOMEM((ulong)priv->iobase) : priv->mmiobase;
priv->fcrval = FCRVAL;
devtype->init_port(cdev);
- return console_register(cdev);
+ ret = console_register(cdev);
+ if (ret)
+ goto clk_disable;
+ return 0;
+
+clk_disable:
+ clk_disable(priv->clk);
+clk_put:
+ clk_put(priv->clk);
+release_region:
+ release_region(iores);
err:
free(priv);
@@ -531,14 +584,19 @@ static struct of_device_id ns16550_serial_dt_ids[] = {
.data = &ns16450_drvdata,
}, {
.compatible = "ns16550a",
- .data = &ns16550_drvdata,
}, {
.compatible = "snps,dw-apb-uart",
- .data = &ns16550_drvdata,
}, {
.compatible = "marvell,armada-38x-uart",
- .data = &ns16550_drvdata,
+ }, {
+ .compatible = "nvidia,tegra20-uart",
},
+#if IS_ENABLED(CONFIG_ARCH_K3)
+ {
+ .compatible = "ti,am654-uart",
+ .data = &omap_clk48m_drvdata,
+ },
+#endif
#if IS_ENABLED(CONFIG_ARCH_OMAP)
{
.compatible = "ti,omap2-uart",
@@ -549,12 +607,9 @@ static struct of_device_id ns16550_serial_dt_ids[] = {
}, {
.compatible = "ti,omap4-uart",
.data = &omap_drvdata,
- },
-#endif
-#if IS_ENABLED(CONFIG_ARCH_TEGRA)
- {
- .compatible = "nvidia,tegra20-uart",
- .data = &tegra_drvdata,
+ }, {
+ .compatible = "ti,am4372-uart",
+ .data = &omap_clk48m_drvdata,
},
#endif
#if IS_ENABLED(CONFIG_MACH_MIPS_XBURST)
@@ -573,11 +628,12 @@ static struct of_device_id ns16550_serial_dt_ids[] = {
/* sentinel */
},
};
+MODULE_DEVICE_TABLE(of, ns16550_serial_dt_ids);
static __maybe_unused struct platform_device_id ns16550_serial_ids[] = {
{
.name = "omap-uart",
- .driver_data = (unsigned long)&omap_drvdata,
+ .driver_data = (unsigned long)&omap_clk48m_drvdata,
}, {
/* sentinel */
},
@@ -586,7 +642,7 @@ static __maybe_unused struct platform_device_id ns16550_serial_ids[] = {
/**
* @brief Driver registration structure
*/
-static struct driver_d ns16550_serial_driver = {
+static struct driver ns16550_serial_driver = {
.name = "ns16550_serial",
.probe = ns16550_probe,
.of_compatible = DRV_OF_COMPAT(ns16550_serial_dt_ids),
diff --git a/drivers/serial/serial_ns16550.h b/drivers/serial/serial_ns16550.h
index c37d63ca9e..2d941cb8d1 100644
--- a/drivers/serial/serial_ns16550.h
+++ b/drivers/serial/serial_ns16550.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
/**
* @file
* @brief Serial NS16550 header
@@ -8,11 +9,6 @@
* Register definitions for NS16550 device
*/
/*
- * This file is licensed under
- * the terms of the GNU General Public License version 2. This program
- * is licensed "as is" without any warranty of any kind, whether express
- * or implied.
- *
* NS16550 Serial Port
* originally from linux source (arch/ppc/boot/ns16550.h)
* modified slightly to
@@ -40,6 +36,7 @@
#define lsr 5
#define msr 6
#define scr 7
+#define cntl 8
#define thr rbr
#define iir fcr
@@ -77,6 +74,12 @@
#define LSR_TEMT 0x40 /* Xmitter empty */
#define LSR_ERR 0x80 /* Error */
+/* Transmitter FIFO completely empty */
+#define LSR_EMPTY (LSR_THRE | LSR_TEMT)
+
+#define CNTL_RXEN 0x01
+#define CNTL_TXEN 0x02
+
/* useful defaults for LCR */
#define LCR_8N1 0x03
diff --git a/drivers/serial/serial_ns16550_pci.c b/drivers/serial/serial_ns16550_pci.c
index c29cfc5a75..f82b5797ce 100644
--- a/drivers/serial/serial_ns16550_pci.c
+++ b/drivers/serial/serial_ns16550_pci.c
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: GPL-2.0
+// SPDX-License-Identifier: GPL-2.0-only
/*
* Probe module for 8250/16550-type PCI serial ports.
*
@@ -1203,7 +1203,7 @@ static int pci_quatech_init(struct pci_dev *dev)
outl(inl(base + 0x38) | 0x00002000, base + 0x38);
tmp = inl(base + 0x3c);
outl(tmp | 0x01000000, base + 0x3c);
- outl(tmp &= ~0x01000000, base + 0x3c);
+ outl(tmp & ~0x01000000, base + 0x3c);
}
}
return 0;
@@ -3656,7 +3656,7 @@ pciserial_init_ports(struct pci_dev *dev, const struct pciserial_board *board)
uart.pdata->clock = board->base_baud * 16;
for (i = 0; i < nr_ports; i++) {
- struct device_d *ns16550_dev;
+ struct device *ns16550_dev;
struct resource *res;
rc = quirk->setup(priv, board, &uart, i);
diff --git a/drivers/serial/serial_omap4_usbboot.c b/drivers/serial/serial_omap4_usbboot.c
index 2ef026c24d..6592be4f35 100644
--- a/drivers/serial/serial_omap4_usbboot.c
+++ b/drivers/serial/serial_omap4_usbboot.c
@@ -1,20 +1,10 @@
-/*
- * 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, or (at your option) any later version.
- *
- * 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.
- */
+// SPDX-License-Identifier: GPL-2.0-or-later
#include <common.h>
#include <init.h>
#include <malloc.h>
#include <errno.h>
-#include <mach/omap4_rom_usb.h>
+#include <mach/omap/omap4_rom_usb.h>
struct serial_omap4_usbboot_priv {
struct console_device cdev;
@@ -56,9 +46,15 @@ static int serial_omap4_usbboot_getc(struct console_device *cdev)
return priv->val;
}
-static int serial_omap4_usbboot_probe(struct device_d *dev)
+static int serial_omap4_usbboot_probe(struct device *dev)
{
struct serial_omap4_usbboot_priv *priv;
+ int ret;
+
+ ret = omap4_usbboot_open();
+ if (ret)
+ return ret;
+
priv = xzalloc(sizeof(*priv));
priv->cdev.dev = dev;
@@ -70,7 +66,7 @@ static int serial_omap4_usbboot_probe(struct device_d *dev)
return console_register(&priv->cdev);
}
-static struct driver_d serial_omap4_usbboot_driver = {
+static struct driver serial_omap4_usbboot_driver = {
.name = "serial_omap4_usbboot",
.probe = serial_omap4_usbboot_probe,
};
diff --git a/drivers/serial/serial_pl010.c b/drivers/serial/serial_pl010.c
index f2cf944e8f..56b9e67610 100644
--- a/drivers/serial/serial_pl010.c
+++ b/drivers/serial/serial_pl010.c
@@ -115,7 +115,7 @@ static int pl010_tstc(struct console_device *cdev)
return !(readl(&pl010->flag) & UART_PL010_FR_RXFE);
}
-static int pl010_probe(struct device_d *dev)
+static int pl010_probe(struct device *dev)
{
struct resource *iores;
struct console_device *cdev;
@@ -138,7 +138,7 @@ static int pl010_probe(struct device_d *dev)
return 0;
}
-static struct driver_d pl010_driver = {
+static struct driver pl010_driver = {
.name = "pl010_serial",
.probe = pl010_probe,
};
diff --git a/drivers/serial/serial_pxa.c b/drivers/serial/serial_pxa.c
index a427437b5c..97342f923e 100644
--- a/drivers/serial/serial_pxa.c
+++ b/drivers/serial/serial_pxa.c
@@ -1,17 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
* (c) 2009 Sascha Hauer <s.hauer@pengutronix.de>
* 2010 by Marc Kleine-Budde <kernel@pengutronix.de>
- *
- * 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, or
- * (at your option) any later version.
- *
- * 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 <common.h>
@@ -19,7 +9,7 @@
#include <init.h>
#include <malloc.h>
-#include <mach/clock.h>
+#include <mach/pxa/clock.h>
#include <asm/io.h>
#define RBR 0x00 /* Receive Buffer Register (read only) */
@@ -159,7 +149,7 @@ static int pxa_serial_setbaudrate(struct console_device *cdev, int baudrate)
return 0;
}
-static int pxa_serial_probe(struct device_d *dev)
+static int pxa_serial_probe(struct device *dev)
{
struct resource *iores;
struct console_device *cdev;
@@ -185,7 +175,7 @@ static int pxa_serial_probe(struct device_d *dev)
return 0;
}
-static struct driver_d pxa_serial_driver = {
+static struct driver pxa_serial_driver = {
.name = "pxa_serial",
.probe = pxa_serial_probe,
};
diff --git a/drivers/serial/serial_s3c.c b/drivers/serial/serial_s3c.c
deleted file mode 100644
index 1945560723..0000000000
--- a/drivers/serial/serial_s3c.c
+++ /dev/null
@@ -1,209 +0,0 @@
-/*
- * (c) 2009...2011 Juergen Beisert <j.beisert@pengutronix.de>
- *
- * Based on code from:
- * (c) 2004 Sascha Hauer <sascha@saschahauer.de>
- *
- * 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, or
- * (at your option) any later version.
- *
- * 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 <common.h>
-#include <driver.h>
-#include <init.h>
-#include <malloc.h>
-#include <io.h>
-#include <mach/s3c-generic.h>
-#include <mach/s3c-iomap.h>
-
-/* Note: Offsets are for little endian access */
-#define ULCON 0x00 /* line control */
-#define UCON 0x04 /* UART control */
-# define UCON_SET_CLK_SRC(x) (((x) & 0x03) << 10)
-# define UCON_GET_CLK_SRC(x) (((x) >> 10) & 0x03)
-#define UFCON 0x08 /* FIFO control */
-#define UMCON 0x0c /* modem control */
-#define UTRSTAT 0x10 /* Rx/Tx status */
-#define UERSTAT 0x14 /* error status */
-#define UFSTAT 0x18 /* FIFO status */
-#define UMSTAT 0x1c /* modem status */
-#define UTXH 0x20 /* transmitt */
-#define URXH 0x24 /* receive */
-#define UBRDIV 0x28 /* baudrate generator */
-#define UBRDIVSLOT 0x2c /* baudrate slot generator */
-#define UINTM 0x38 /* interrupt mask register */
-
-struct s3c_uart {
- void __iomem *regs;
- struct console_device cdev;
-};
-
-#define to_s3c_uart(c) container_of(c, struct s3c_uart, cdev)
-
-/* each architecture has a preferred reference clock for its UARTs */
-static unsigned s3c_select_arch_input_clock(void)
-{
- /* S3C24xx: 0=2=PCLK, 1=UEXTCLK, 3=FCLK/n */
- if (IS_ENABLED(CONFIG_ARCH_S3C24xx))
- return 0; /* use the internal PCLK */
- /* S3C64xx: 0=2=PCLK, 1=UCLK0, 3=UCLK1 */
- if (IS_ENABLED(CONFIG_ARCH_S3C64xx))
- return 3; /* use the internal UCLK1 */
- /* S5PCxx: 0=PCLK, 1=SCLK_UART */
- if (IS_ENABLED(CONFIG_ARCH_S5PCxx))
- return 0; /* use the internal PCLK */
-}
-
-static unsigned s3c_get_arch_uart_input_clock(void __iomem *base)
-{
- unsigned reg = readw(base + UCON);
- return s3c_get_uart_clk(UCON_GET_CLK_SRC(reg));
-}
-
-/*
- * This table takes the fractional value of the baud divisor and gives
- * the recommended setting for the UDIVSLOT register. Refer the datasheet
- * for further details
- */
-static const uint16_t udivslot_table[] __maybe_unused = {
- 0x0000, 0x0080, 0x0808, 0x0888, 0x2222, 0x4924, 0x4A52, 0x54AA,
- 0x5555, 0xD555, 0xD5D5, 0xDDD5, 0xDDDD, 0xDFDD, 0xDFDF, 0xFFDF,
-};
-
-static int s3c_serial_setbaudrate(struct console_device *cdev, int baudrate)
-{
- struct s3c_uart *priv = to_s3c_uart(cdev);
- void __iomem *base = priv->regs;
- unsigned val;
-
- if (IS_ENABLED(CONFIG_DRIVER_SERIAL_S3C_IMPROVED)) {
- val = s3c_get_arch_uart_input_clock(base) / baudrate;
- writew(udivslot_table[val & 15], base + UBRDIVSLOT);
- }
-
- val = s3c_get_arch_uart_input_clock(base) / (16 * baudrate) - 1;
- writew(val, base + UBRDIV);
-
- return 0;
-}
-
-static int s3c_serial_init_port(struct console_device *cdev)
-{
- struct s3c_uart *priv = to_s3c_uart(cdev);
- void __iomem *base = priv->regs;
-
- /* FIFO enable, Tx/Rx FIFO clear */
- writeb(0x07, base + UFCON);
- writeb(0x00, base + UMCON);
-
- /* Normal,No parity,1 stop,8 bit */
- writeb(0x03, base + ULCON);
-
- /*
- * S3C2440 SoC:
- * - no clock divider
- * all SoCs:
- * - enable receive and transmit mode
- */
- writew(0x0005 | UCON_SET_CLK_SRC(s3c_select_arch_input_clock()),
- base + UCON);
-
- if (IS_ENABLED(CONFIG_DRIVER_SERIAL_S3C_IMPROVED))
- /* 'interrupt or polling mode' for both directions */
- writeb(0xf, base + UINTM);
-
- if (IS_ENABLED(CONFIG_DRIVER_SERIAL_S3C_AUTOSYNC))
- writeb(0x10, base + UMCON); /* enable auto flow control */
- else
- writeb(0x01, base + UMCON); /* RTS up */
-
- return 0;
-}
-
-static void s3c_serial_putc(struct console_device *cdev, char c)
-{
- struct s3c_uart *priv = to_s3c_uart(cdev);
- void __iomem *base = priv->regs;
-
- /* Wait for Tx FIFO not full */
- while (!(readb(base + UTRSTAT) & 0x2))
- ;
-
- writeb(c, base + UTXH);
-}
-
-static int s3c_serial_tstc(struct console_device *cdev)
-{
- struct s3c_uart *priv = to_s3c_uart(cdev);
- void __iomem *base = priv->regs;
-
- /* If receive fifo is empty, return false */
- if (readb(base + UTRSTAT) & 0x1)
- return 1;
-
- return 0;
-}
-
-static int s3c_serial_getc(struct console_device *cdev)
-{
- struct s3c_uart *priv = to_s3c_uart(cdev);
- void __iomem *base = priv->regs;
-
- /* wait for a character */
- while (!(readb(base + UTRSTAT) & 0x1))
- ;
-
- return readb(base + URXH);
-}
-
-static void s3c_serial_flush(struct console_device *cdev)
-{
- struct s3c_uart *priv = to_s3c_uart(cdev);
- void __iomem *base = priv->regs;
-
- while (!(readb(base + UTRSTAT) & 0x4))
- ;
-}
-
-static int s3c_serial_probe(struct device_d *dev)
-{
- struct resource *iores;
- struct s3c_uart *priv;
- struct console_device *cdev;
-
- priv = xzalloc(sizeof(struct s3c_uart));
- cdev = &priv->cdev;
- iores = dev_request_mem_resource(dev, 0);
- if (IS_ERR(iores))
- return PTR_ERR(iores);
- priv->regs = IOMEM(iores->start);
- dev->priv = priv;
- cdev->dev = dev;
- cdev->tstc = s3c_serial_tstc;
- cdev->putc = s3c_serial_putc;
- cdev->getc = s3c_serial_getc;
- cdev->flush = s3c_serial_flush;
- cdev->setbrg = s3c_serial_setbaudrate;
-
- s3c_serial_init_port(cdev);
-
- /* Enable UART */
- console_register(cdev);
-
- return 0;
-}
-
-static struct driver_d s3c_serial_driver = {
- .name = "s3c_serial",
- .probe = s3c_serial_probe,
-};
-console_platform_driver(s3c_serial_driver);
diff --git a/drivers/serial/serial_sbi.c b/drivers/serial/serial_sbi.c
index 2ea28fea5b..dd3eef41d1 100644
--- a/drivers/serial/serial_sbi.c
+++ b/drivers/serial/serial_sbi.c
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: GPL-2.0+
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (C) 2021 Marcelo Politzer <marcelo.politzer@cartesi.io>
*/
@@ -36,7 +36,7 @@ static int sbi_serial_tstc(struct console_device *cdev)
return priv->head != priv->tail;
}
-static int sbi_serial_probe(struct device_d *dev)
+static int sbi_serial_probe(struct device *dev)
{
struct sbi_serial_priv *priv;
@@ -51,7 +51,7 @@ static int sbi_serial_probe(struct device_d *dev)
return console_register(&priv->cdev);
}
-static struct driver_d serial_sbi_driver = {
+static struct driver serial_sbi_driver = {
.name = "riscv-serial-sbi",
.probe = sbi_serial_probe,
};
diff --git a/drivers/serial/serial_sifive.c b/drivers/serial/serial_sifive.c
index 45f7c2bc9a..f056233b4e 100644
--- a/drivers/serial/serial_sifive.c
+++ b/drivers/serial/serial_sifive.c
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: GPL-2.0+
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (C) 2018 Anup Patel <anup@brainfault.org>
*/
@@ -116,7 +116,7 @@ static void sifive_serial_flush(struct console_device *cdev)
;
}
-static int sifive_serial_probe(struct device_d *dev)
+static int sifive_serial_probe(struct device *dev)
{
struct sifive_serial_priv *priv;
struct resource *iores;
@@ -130,7 +130,8 @@ static int sifive_serial_probe(struct device_d *dev)
} else {
dev_dbg(dev, "failed to get clock. Fallback to device tree.\n");
- ret = of_property_read_u32(dev->device_node, "clock-frequency", &freq);
+ ret = of_property_read_u32(dev->of_node, "clock-frequency",
+ &freq);
if (ret) {
dev_warn(dev, "unknown clock frequency\n");
return ret;
@@ -162,8 +163,9 @@ static __maybe_unused struct of_device_id sifive_serial_dt_ids[] = {
{ .compatible = "sifive,uart0" },
{ /* sentinel */ }
};
+MODULE_DEVICE_TABLE(of, sifive_serial_dt_ids);
-static struct driver_d serial_sifive_driver = {
+static struct driver serial_sifive_driver = {
.name = "serial_sifive",
.probe = sifive_serial_probe,
.of_compatible = sifive_serial_dt_ids,
diff --git a/drivers/serial/serial_stm32.c b/drivers/serial/serial_stm32.c
index 4bbfb1eef7..3e18a2c152 100644
--- a/drivers/serial/serial_stm32.c
+++ b/drivers/serial/serial_stm32.c
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: GPL-2.0+
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (C) 2016, STMicroelectronics - All Rights Reserved
* Author(s): Vikas Manocha, <vikas.manocha@st.com> for STMicroelectronics.
@@ -41,6 +41,8 @@ static int stm32_serial_setbaudrate(struct console_device *cdev, int baudrate)
unsigned long clock_rate;
clock_rate = clk_get_rate(stm32->clk);
+ if (!clock_rate)
+ return -EINVAL;
int_div = DIV_ROUND_CLOSEST(clock_rate, baudrate);
@@ -136,7 +138,7 @@ static void stm32_serial_init(struct console_device *cdev)
writel(cr1, base + CR1_OFFSET(stm32f4));
}
-static int stm32_serial_probe(struct device_d *dev)
+static int stm32_serial_probe(struct device *dev)
{
int ret;
struct console_device *cdev;
@@ -163,7 +165,7 @@ static int stm32_serial_probe(struct device_d *dev)
stm32->stm32f4 = info->stm32f4;
stm32->uart_enable_bit = info->uart_enable_bit;
- stm32->clk = clk_get(dev, NULL);
+ stm32->clk = clk_get_for_console(dev, NULL);
if (IS_ERR(stm32->clk)) {
ret = PTR_ERR(stm32->clk);
dev_err(dev, "Failed to get UART clock %d\n", ret);
@@ -181,11 +183,11 @@ static int stm32_serial_probe(struct device_d *dev)
cdev->putc = stm32_serial_putc;
cdev->getc = stm32_serial_getc;
cdev->flush = stm32_serial_flush;
- cdev->setbrg = stm32_serial_setbaudrate;
+ cdev->setbrg = stm32->clk ? stm32_serial_setbaudrate : NULL;
cdev->linux_console_name = "ttySTM";
- if (dev->device_node) {
- devname = of_alias_get(dev->device_node);
+ if (dev->of_node) {
+ devname = of_alias_get(dev->of_node);
if (devname) {
cdev->devname = xstrdup(devname);
cdev->devid = DEVICE_ID_SINGLE;
@@ -238,8 +240,9 @@ static struct of_device_id stm32_serial_dt_ids[] = {
}, {
}
};
+MODULE_DEVICE_TABLE(of, stm32_serial_dt_ids);
-static struct driver_d stm32_serial_driver = {
+static struct driver stm32_serial_driver = {
.name = "stm32-serial",
.probe = stm32_serial_probe,
.of_compatible = DRV_OF_COMPAT(stm32_serial_dt_ids),
diff --git a/drivers/serial/serial_stm32.h b/drivers/serial/serial_stm32.h
index dd3e930c93..f519f2abac 100644
--- a/drivers/serial/serial_stm32.h
+++ b/drivers/serial/serial_stm32.h
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
+/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* Copyright (C) 2016, STMicroelectronics - All Rights Reserved
* Author(s): Vikas Manocha, <vikas.manocha@st.com> for STMicroelectronics.
diff --git a/drivers/serial/stm-serial.c b/drivers/serial/stm-serial.c
index a2c3dcf56e..af30bfa71d 100644
--- a/drivers/serial/stm-serial.c
+++ b/drivers/serial/stm-serial.c
@@ -1,21 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
* (C) Copyright 2010 Juergen Beisert - Pengutronix
*
* This code was inspired by some patches made for u-boot covered by:
* (c) 2007 Sascha Hauer <s.hauer@pengutronix.de>
* (C) Copyright 2009 Freescale Semiconductor, Inc.
- *
- * 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, or
- * (at your option) any later version.
- *
- * 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.
- *
- *
*/
/*
@@ -31,7 +20,6 @@
#include <malloc.h>
#include <linux/clk.h>
#include <linux/err.h>
-#include <mach/clock.h>
#define UARTDBGDR 0x00
#define UARTDBGFR 0x18
@@ -143,7 +131,7 @@ static int stm_serial_init_port(struct stm_priv *priv)
return 0;
}
-static int stm_serial_probe(struct device_d *dev)
+static int stm_serial_probe(struct device *dev)
{
struct resource *iores;
struct stm_priv *priv;
@@ -160,12 +148,14 @@ static int stm_serial_probe(struct device_d *dev)
cdev->setbrg = stm_serial_setbaudrate;
cdev->dev = dev;
cdev->linux_console_name = "ttyAMA";
+ cdev->linux_earlycon_name = "pl011";
dev->priv = priv;
iores = dev_request_mem_resource(dev, 0);
if (IS_ERR(iores))
return PTR_ERR(iores);
priv->base = IOMEM(iores->start);
+ cdev->phys_base = priv->base;
priv->clk = clk_get(dev, NULL);
if (IS_ERR(priv->clk))
return PTR_ERR(priv->clk);
@@ -190,8 +180,9 @@ static __maybe_unused struct of_device_id stm_serial_dt_ids[] = {
/* sentinel */
}
};
+MODULE_DEVICE_TABLE(of, stm_serial_dt_ids);
-static struct driver_d stm_serial_driver = {
+static struct driver stm_serial_driver = {
.name = "stm_serial",
.probe = stm_serial_probe,
.of_compatible = DRV_OF_COMPAT(stm_serial_dt_ids),