* [PATCH v5 0/3] uart: Introduce uart driver for the Loongson family
@ 2025-09-24 6:29 Binbin Zhou
2025-09-24 6:29 ` [PATCH v5 1/3] dt-bindings: serial: 8250: Add Loongson uart compatible Binbin Zhou
` (2 more replies)
0 siblings, 3 replies; 16+ messages in thread
From: Binbin Zhou @ 2025-09-24 6:29 UTC (permalink / raw)
To: Binbin Zhou, Huacai Chen, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Greg Kroah-Hartman, Jiri Slaby, Haowei Zheng
Cc: Huacai Chen, Xuerui Wang, loongarch, devicetree, linux-serial,
Binbin Zhou
Hi all:
For various reasons, I will be taking over from Haowei and continuing to
push forward with this patch set. Thanks to Haowei for his efforts so
far.
This patchset introduce a generic UART framework driver for Loongson family.
It can be found on Loongson3 series cpus, Loongson-2K series cpus and Loongson
LS7A bridge chips.
Thanks.
------
V5:
Patch-1:
- Since the Loongson UART is NS8250A-compatible, simply add ls2k* compatible
to 8250.yaml.
Sorry for the DTS{i} check error that appeared in the V3 patchset. I've fixed
this issue. Thanks to Krzysztof.
Link to V4:
https://lore.kernel.org/all/cover.1757318368.git.zhoubinbin@loongson.cn/
V4:
Patch-1:
- Rename binding name from loongson,uart.yaml to
loongson,ls2k0500-uart.yaml;
- Drop ls7a compatible;
- According to the manual, ls3a and ls2k uart are the same, so merge their
compatible.
Patch-2:
- Format code;
- Add the LOONGSON_UART_DLF macro definition to avoid magic numbers;
- Simplify the code, merge flags and quirks, and remove struct
loongson_uart_config;
- Use DEFINE_SIMPLE_DEV_PM_OPS;
- Drop loongson,ls7a-uart compatible.
Patch-3:
- Add ls2k* compatible string, and ns16550a as the fallback
compatible.
Link to V3:
https://lore.kernel.org/all/20240826024705.55474-1-zhenghaowei@loongson.cn/
Binbin Zhou (3):
dt-bindings: serial: 8250: Add Loongson uart compatible
serial: 8250: Add Loongson uart driver support
LoongArch: dts: Add uart new compatible string
.../devicetree/bindings/serial/8250.yaml | 14 ++
arch/loongarch/boot/dts/loongson-2k0500.dtsi | 2 +-
arch/loongarch/boot/dts/loongson-2k1000.dtsi | 2 +-
arch/loongarch/boot/dts/loongson-2k2000.dtsi | 2 +-
drivers/tty/serial/8250/8250_loongson.c | 202 ++++++++++++++++++
drivers/tty/serial/8250/8250_port.c | 8 +
drivers/tty/serial/8250/Kconfig | 10 +
drivers/tty/serial/8250/Makefile | 1 +
include/uapi/linux/serial_core.h | 1 +
9 files changed, 239 insertions(+), 3 deletions(-)
create mode 100644 drivers/tty/serial/8250/8250_loongson.c
base-commit: f4abab350840d58d69814c6993736f03ac27df83
--
2.47.3
^ permalink raw reply [flat|nested] 16+ messages in thread* [PATCH v5 1/3] dt-bindings: serial: 8250: Add Loongson uart compatible 2025-09-24 6:29 [PATCH v5 0/3] uart: Introduce uart driver for the Loongson family Binbin Zhou @ 2025-09-24 6:29 ` Binbin Zhou 2025-09-24 19:19 ` Conor Dooley 2025-09-24 6:29 ` [PATCH v5 2/3] serial: 8250: Add Loongson uart driver support Binbin Zhou 2025-09-24 6:29 ` [PATCH v5 3/3] LoongArch: dts: Add uart new compatible string Binbin Zhou 2 siblings, 1 reply; 16+ messages in thread From: Binbin Zhou @ 2025-09-24 6:29 UTC (permalink / raw) To: Binbin Zhou, Huacai Chen, Rob Herring, Krzysztof Kozlowski, Conor Dooley, Greg Kroah-Hartman, Jiri Slaby, Haowei Zheng Cc: Huacai Chen, Xuerui Wang, loongarch, devicetree, linux-serial, Binbin Zhou The Loongson family have a mostly NS16550A-compatible UART and High-Speed UART hardware with the exception of custom frequency divider latch settings register. Co-developed-by: Haowei Zheng <zhenghaowei@loongson.cn> Signed-off-by: Haowei Zheng <zhenghaowei@loongson.cn> Signed-off-by: Binbin Zhou <zhoubinbin@loongson.cn> --- Documentation/devicetree/bindings/serial/8250.yaml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/Documentation/devicetree/bindings/serial/8250.yaml b/Documentation/devicetree/bindings/serial/8250.yaml index b243afa69a1a..167ddcbd8800 100644 --- a/Documentation/devicetree/bindings/serial/8250.yaml +++ b/Documentation/devicetree/bindings/serial/8250.yaml @@ -125,6 +125,8 @@ properties: - nxp,lpc1850-uart - opencores,uart16550-rtlsvn105 - ti,da830-uart + - loongson,ls2k0500-uart + - loongson,ls2k1500-uart - const: ns16550a - items: - enum: @@ -169,6 +171,18 @@ properties: - nvidia,tegra194-uart - nvidia,tegra234-uart - const: nvidia,tegra20-uart + - items: + - enum: + - loongson,ls2k1000-uart + - const: loongson,ls2k0500-uart + - const: ns16550a + - items: + - enum: + - loongson,ls3a5000-uart + - loongson,ls3a6000-uart + - loongson,ls2k2000-uart + - const: loongson,ls2k1500-uart + - const: ns16550a reg: maxItems: 1 -- 2.47.3 ^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [PATCH v5 1/3] dt-bindings: serial: 8250: Add Loongson uart compatible 2025-09-24 6:29 ` [PATCH v5 1/3] dt-bindings: serial: 8250: Add Loongson uart compatible Binbin Zhou @ 2025-09-24 19:19 ` Conor Dooley 0 siblings, 0 replies; 16+ messages in thread From: Conor Dooley @ 2025-09-24 19:19 UTC (permalink / raw) To: Binbin Zhou Cc: Binbin Zhou, Huacai Chen, Rob Herring, Krzysztof Kozlowski, Conor Dooley, Greg Kroah-Hartman, Jiri Slaby, Haowei Zheng, Huacai Chen, Xuerui Wang, loongarch, devicetree, linux-serial [-- Attachment #1: Type: text/plain, Size: 52 bytes --] Acked-by: Conor Dooley <conor.dooley@microchip.com> [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 228 bytes --] ^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH v5 2/3] serial: 8250: Add Loongson uart driver support 2025-09-24 6:29 [PATCH v5 0/3] uart: Introduce uart driver for the Loongson family Binbin Zhou 2025-09-24 6:29 ` [PATCH v5 1/3] dt-bindings: serial: 8250: Add Loongson uart compatible Binbin Zhou @ 2025-09-24 6:29 ` Binbin Zhou 2025-09-24 10:22 ` Greg Kroah-Hartman ` (2 more replies) 2025-09-24 6:29 ` [PATCH v5 3/3] LoongArch: dts: Add uart new compatible string Binbin Zhou 2 siblings, 3 replies; 16+ messages in thread From: Binbin Zhou @ 2025-09-24 6:29 UTC (permalink / raw) To: Binbin Zhou, Huacai Chen, Rob Herring, Krzysztof Kozlowski, Conor Dooley, Greg Kroah-Hartman, Jiri Slaby, Haowei Zheng Cc: Huacai Chen, Xuerui Wang, loongarch, devicetree, linux-serial, Binbin Zhou Add the driver for on-chip UART used on Loongson family chips. The hardware is similar to 8250, but there are the following differences: - Some chips (such as Loongson-2K2000) have added a fractional division register to obtain the required baud rate accurately, so the {get,set}_divisor callback is overridden. - Due to hardware defects, quirk handling is required for UART_MCR/UART_MSR. Co-developed-by: Haowei Zheng <zhenghaowei@loongson.cn> Signed-off-by: Haowei Zheng <zhenghaowei@loongson.cn> Signed-off-by: Binbin Zhou <zhoubinbin@loongson.cn> --- drivers/tty/serial/8250/8250_loongson.c | 202 ++++++++++++++++++++++++ drivers/tty/serial/8250/8250_port.c | 8 + drivers/tty/serial/8250/Kconfig | 10 ++ drivers/tty/serial/8250/Makefile | 1 + include/uapi/linux/serial_core.h | 1 + 5 files changed, 222 insertions(+) create mode 100644 drivers/tty/serial/8250/8250_loongson.c diff --git a/drivers/tty/serial/8250/8250_loongson.c b/drivers/tty/serial/8250/8250_loongson.c new file mode 100644 index 000000000000..a114b4e6d5c3 --- /dev/null +++ b/drivers/tty/serial/8250/8250_loongson.c @@ -0,0 +1,202 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Serial Port driver for Loongson family chips + * + * Copyright (C) 2020-2025 Loongson Technology Corporation Limited + */ + +#include <linux/bitfield.h> +#include <linux/module.h> +#include <linux/property.h> +#include <linux/mod_devicetable.h> +#include <linux/reset.h> + +#include "8250.h" + +/* Divisor Latch Fraction Register */ +#define LOONGSON_UART_DLF 0x2 + +/* Flags */ +#define LOONGSON_UART_HAS_FRAC BIT(0) +#define LOONGSON_UART_QUIRK_MCR BIT(1) +#define LOONGSON_UART_QUIRK_MSR BIT(2) + +#define LS2K0500_UART_FLAG (LOONGSON_UART_QUIRK_MCR | LOONGSON_UART_QUIRK_MSR) +#define LS2K1500_UART_FLAG (LOONGSON_UART_HAS_FRAC | LOONGSON_UART_QUIRK_MCR) + +struct loongson_uart_data { + int line; + int mcr_invert; + int msr_invert; + struct reset_control *rst; +}; + +static unsigned int serial_fixup(struct uart_port *p, unsigned int offset, unsigned int val) +{ + struct loongson_uart_data *ddata = p->private_data; + + if (offset == UART_MCR) + val ^= ddata->mcr_invert; + + if (offset == UART_MSR) + val ^= ddata->msr_invert; + + return val; +} + +static u32 loongson_serial_in(struct uart_port *p, unsigned int offset) +{ + unsigned int val; + + val = readb(p->membase + (offset << p->regshift)); + + return serial_fixup(p, offset, val); +} + +static void loongson_serial_out(struct uart_port *p, unsigned int offset, unsigned int value) +{ + offset <<= p->regshift; + writeb(serial_fixup(p, offset, value), p->membase + offset); +} + +static unsigned int loongson_frac_get_divisor(struct uart_port *port, unsigned int baud, + unsigned int *frac) +{ + unsigned int quot; + + quot = DIV_ROUND_CLOSEST((port->uartclk << 4), baud); + *frac = FIELD_GET(GENMASK(7, 0), quot); + + return FIELD_GET(GENMASK(15, 8), quot); +} + +static void loongson_frac_set_divisor(struct uart_port *port, unsigned int baud, + unsigned int quot, unsigned int quot_frac) +{ + struct uart_8250_port *up = up_to_u8250p(port); + + serial_port_out(port, UART_LCR, up->lcr | UART_LCR_DLAB); + serial_dl_write(up, quot); + serial_port_out(port, LOONGSON_UART_DLF, quot_frac); +} + +static int loongson_uart_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct uart_8250_port uart = {}; + struct loongson_uart_data *ddata; + struct resource *res; + unsigned int flags; + int ret; + + ddata = devm_kzalloc(dev, sizeof(*ddata), GFP_KERNEL); + if (!ddata) + return -ENOMEM; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) + return -ENODEV; + + uart.port.irq = platform_get_irq(pdev, 0); + if (uart.port.irq < 0) + return -EINVAL; + + device_property_read_u32(dev, "clock-frequency", &uart.port.uartclk); + + spin_lock_init(&uart.port.lock); + uart.port.flags = UPF_SHARE_IRQ | UPF_FIXED_PORT | UPF_FIXED_TYPE | UPF_IOREMAP; + uart.port.iotype = UPIO_MEM; + uart.port.regshift = 0; + uart.port.dev = dev; + uart.port.type = PORT_LOONGSON; + uart.port.private_data = ddata; + + uart.port.mapbase = res->start; + uart.port.mapsize = resource_size(res); + uart.port.serial_in = loongson_serial_in; + uart.port.serial_out = loongson_serial_out; + + flags = (uintptr_t)device_get_match_data(dev); + + if (flags & LOONGSON_UART_HAS_FRAC) { + uart.port.get_divisor = loongson_frac_get_divisor; + uart.port.set_divisor = loongson_frac_set_divisor; + } + + if (flags & LOONGSON_UART_QUIRK_MCR) + ddata->mcr_invert |= (UART_MCR_RTS | UART_MCR_DTR); + + if (flags & LOONGSON_UART_QUIRK_MSR) + ddata->msr_invert |= (UART_MSR_CTS | UART_MSR_DSR); + + ddata->rst = devm_reset_control_get_optional_shared(dev, NULL); + if (IS_ERR(ddata->rst)) + return PTR_ERR(ddata->rst); + + ret = reset_control_deassert(ddata->rst); + if (ret) + return ret; + + ret = serial8250_register_8250_port(&uart); + if (ret < 0) { + reset_control_assert(ddata->rst); + return ret; + } + + ddata->line = ret; + platform_set_drvdata(pdev, ddata); + + return 0; +} + +static void loongson_uart_remove(struct platform_device *pdev) +{ + struct loongson_uart_data *ddata = platform_get_drvdata(pdev); + + serial8250_unregister_port(ddata->line); + reset_control_assert(ddata->rst); +} + +static int loongson_uart_suspend(struct device *dev) +{ + struct loongson_uart_data *ddata = dev_get_drvdata(dev); + + serial8250_suspend_port(ddata->line); + + return 0; +} + +static int loongson_uart_resume(struct device *dev) +{ + struct loongson_uart_data *data = dev_get_drvdata(dev); + + serial8250_resume_port(data->line); + + return 0; +} + +static DEFINE_SIMPLE_DEV_PM_OPS(loongson_uart_pm_ops, loongson_uart_suspend, + loongson_uart_resume); + +static const struct of_device_id loongson_uart_of_ids[] = { + { .compatible = "loongson,ls2k0500-uart", .data = (void *)LS2K0500_UART_FLAG }, + { .compatible = "loongson,ls2k1500-uart", .data = (void *)LS2K1500_UART_FLAG }, + { /* sentinel */ }, +}; +MODULE_DEVICE_TABLE(of, loongson_uart_of_ids); + +static struct platform_driver loongson_uart_driver = { + .probe = loongson_uart_probe, + .remove = loongson_uart_remove, + .driver = { + .name = "loongson-uart", + .pm = pm_ptr(&loongson_uart_pm_ops), + .of_match_table = loongson_uart_of_ids, + }, +}; + +module_platform_driver(loongson_uart_driver); + +MODULE_DESCRIPTION("Loongson UART driver"); +MODULE_AUTHOR("Loongson Technology Corporation Limited."); +MODULE_LICENSE("GPL"); diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c index 719faf92aa8a..53efe841656f 100644 --- a/drivers/tty/serial/8250/8250_port.c +++ b/drivers/tty/serial/8250/8250_port.c @@ -310,6 +310,14 @@ static const struct serial8250_config uart_config[] = { .rxtrig_bytes = {1, 8, 16, 30}, .flags = UART_CAP_FIFO | UART_CAP_AFE, }, + [PORT_LOONGSON] = { + .name = "Loongson", + .fifo_size = 16, + .tx_loadsz = 16, + .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, + .rxtrig_bytes = {1, 4, 8, 14}, + .flags = UART_CAP_FIFO, + }, }; /* Uart divisor latch read */ diff --git a/drivers/tty/serial/8250/Kconfig b/drivers/tty/serial/8250/Kconfig index f64ef0819cd4..98236b3bec10 100644 --- a/drivers/tty/serial/8250/Kconfig +++ b/drivers/tty/serial/8250/Kconfig @@ -468,6 +468,16 @@ config SERIAL_8250_OMAP_TTYO_FIXUP not booting kernel because the serial console remains silent in case they forgot to update the command line. +config SERIAL_8250_LOONGSON + tristate "Loongson 8250 based serial port" + depends on SERIAL_8250 + depends on LOONGARCH || COMPILE_TEST + help + If you have a machine based on LoongArch CPU you can enable + its onboard serial ports by enabling this option. The option + is applicable to both devicetree and ACPI, say Y to this option. + If unsure, say N. + config SERIAL_8250_LPC18XX tristate "NXP LPC18xx/43xx serial port support" depends on SERIAL_8250 && OF && (ARCH_LPC18XX || COMPILE_TEST) diff --git a/drivers/tty/serial/8250/Makefile b/drivers/tty/serial/8250/Makefile index 513a0941c284..e318a3240789 100644 --- a/drivers/tty/serial/8250/Makefile +++ b/drivers/tty/serial/8250/Makefile @@ -38,6 +38,7 @@ obj-$(CONFIG_SERIAL_8250_HP300) += 8250_hp300.o obj-$(CONFIG_SERIAL_8250_HUB6) += 8250_hub6.o obj-$(CONFIG_SERIAL_8250_INGENIC) += 8250_ingenic.o obj-$(CONFIG_SERIAL_8250_IOC3) += 8250_ioc3.o +obj-$(CONFIG_SERIAL_8250_LOONGSON) += 8250_loongson.o obj-$(CONFIG_SERIAL_8250_LPC18XX) += 8250_lpc18xx.o obj-$(CONFIG_SERIAL_8250_LPSS) += 8250_lpss.o obj-$(CONFIG_SERIAL_8250_MEN_MCB) += 8250_men_mcb.o diff --git a/include/uapi/linux/serial_core.h b/include/uapi/linux/serial_core.h index 9c007a106330..607cf060a72a 100644 --- a/include/uapi/linux/serial_core.h +++ b/include/uapi/linux/serial_core.h @@ -31,6 +31,7 @@ #define PORT_ALTR_16550_F128 28 /* Altera 16550 UART with 128 FIFOs */ #define PORT_RT2880 29 /* Ralink RT2880 internal UART */ #define PORT_16550A_FSL64 30 /* Freescale 16550 UART with 64 FIFOs */ +#define PORT_LOONGSON 31 /* Loongson 16550 UART */ /* * ARM specific type numbers. These are not currently guaranteed -- 2.47.3 ^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [PATCH v5 2/3] serial: 8250: Add Loongson uart driver support 2025-09-24 6:29 ` [PATCH v5 2/3] serial: 8250: Add Loongson uart driver support Binbin Zhou @ 2025-09-24 10:22 ` Greg Kroah-Hartman 2025-09-28 2:48 ` Binbin Zhou 2025-09-29 6:26 ` Jiri Slaby 2025-09-30 11:58 ` Ilpo Järvinen 2 siblings, 1 reply; 16+ messages in thread From: Greg Kroah-Hartman @ 2025-09-24 10:22 UTC (permalink / raw) To: Binbin Zhou Cc: Binbin Zhou, Huacai Chen, Rob Herring, Krzysztof Kozlowski, Conor Dooley, Jiri Slaby, Haowei Zheng, Huacai Chen, Xuerui Wang, loongarch, devicetree, linux-serial On Wed, Sep 24, 2025 at 02:29:37PM +0800, Binbin Zhou wrote: > --- a/include/uapi/linux/serial_core.h > +++ b/include/uapi/linux/serial_core.h > @@ -31,6 +31,7 @@ > #define PORT_ALTR_16550_F128 28 /* Altera 16550 UART with 128 FIFOs */ > #define PORT_RT2880 29 /* Ralink RT2880 internal UART */ > #define PORT_16550A_FSL64 30 /* Freescale 16550 UART with 64 FIFOs */ > +#define PORT_LOONGSON 31 /* Loongson 16550 UART */ Why does userspace need to have this value exported? thanks, greg k-h ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v5 2/3] serial: 8250: Add Loongson uart driver support 2025-09-24 10:22 ` Greg Kroah-Hartman @ 2025-09-28 2:48 ` Binbin Zhou 2025-09-29 6:19 ` Jiri Slaby 0 siblings, 1 reply; 16+ messages in thread From: Binbin Zhou @ 2025-09-28 2:48 UTC (permalink / raw) To: Greg Kroah-Hartman Cc: Binbin Zhou, Huacai Chen, Rob Herring, Krzysztof Kozlowski, Conor Dooley, Jiri Slaby, Haowei Zheng, Huacai Chen, Xuerui Wang, loongarch, devicetree, linux-serial Hi Greg: Thanks for your reply. On Wed, Sep 24, 2025 at 6:22 PM Greg Kroah-Hartman <gregkh@linuxfoundation.org> wrote: > > On Wed, Sep 24, 2025 at 02:29:37PM +0800, Binbin Zhou wrote: > > --- a/include/uapi/linux/serial_core.h > > +++ b/include/uapi/linux/serial_core.h > > @@ -31,6 +31,7 @@ > > #define PORT_ALTR_16550_F128 28 /* Altera 16550 UART with 128 FIFOs */ > > #define PORT_RT2880 29 /* Ralink RT2880 internal UART */ > > #define PORT_16550A_FSL64 30 /* Freescale 16550 UART with 64 FIFOs */ > > +#define PORT_LOONGSON 31 /* Loongson 16550 UART */ > > Why does userspace need to have this value exported? Sorry, this was a cheap mistake. It should follow the existing latest macro definition as follows: diff --git a/include/uapi/linux/serial_core.h b/include/uapi/linux/serial_core.h index 9c007a106330..5221d86d592a 100644 --- a/include/uapi/linux/serial_core.h +++ b/include/uapi/linux/serial_core.h @@ -231,6 +231,9 @@ /* Sunplus UART */ #define PORT_SUNPLUS 123 +/* Loongson UART */ +#define PORT_LOONGSON 124 I'll double-check and test it again in the next version. > > thanks, > > greg k-h -- Thanks. Binbin ^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [PATCH v5 2/3] serial: 8250: Add Loongson uart driver support 2025-09-28 2:48 ` Binbin Zhou @ 2025-09-29 6:19 ` Jiri Slaby 2025-09-30 3:03 ` Binbin Zhou 0 siblings, 1 reply; 16+ messages in thread From: Jiri Slaby @ 2025-09-29 6:19 UTC (permalink / raw) To: Binbin Zhou, Greg Kroah-Hartman Cc: Binbin Zhou, Huacai Chen, Rob Herring, Krzysztof Kozlowski, Conor Dooley, Haowei Zheng, Huacai Chen, Xuerui Wang, loongarch, devicetree, linux-serial Hi, On 28. 09. 25, 4:48, Binbin Zhou wrote: > Hi Greg: > > Thanks for your reply. > > On Wed, Sep 24, 2025 at 6:22 PM Greg Kroah-Hartman > <gregkh@linuxfoundation.org> wrote: >> >> On Wed, Sep 24, 2025 at 02:29:37PM +0800, Binbin Zhou wrote: >>> --- a/include/uapi/linux/serial_core.h >>> +++ b/include/uapi/linux/serial_core.h >>> @@ -31,6 +31,7 @@ >>> #define PORT_ALTR_16550_F128 28 /* Altera 16550 UART with 128 FIFOs */ >>> #define PORT_RT2880 29 /* Ralink RT2880 internal UART */ >>> #define PORT_16550A_FSL64 30 /* Freescale 16550 UART with 64 FIFOs */ >>> +#define PORT_LOONGSON 31 /* Loongson 16550 UART */ >> >> Why does userspace need to have this value exported? > > Sorry, this was a cheap mistake. > It should follow the existing latest macro definition as follows: That was not the point. The point was why do you need that at all? -- js suse labs ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v5 2/3] serial: 8250: Add Loongson uart driver support 2025-09-29 6:19 ` Jiri Slaby @ 2025-09-30 3:03 ` Binbin Zhou 2025-10-08 12:16 ` Greg Kroah-Hartman 0 siblings, 1 reply; 16+ messages in thread From: Binbin Zhou @ 2025-09-30 3:03 UTC (permalink / raw) To: Jiri Slaby Cc: Greg Kroah-Hartman, Binbin Zhou, Huacai Chen, Rob Herring, Krzysztof Kozlowski, Conor Dooley, Haowei Zheng, Huacai Chen, Xuerui Wang, loongarch, devicetree, linux-serial Hi Jiri: Thanks for your reply. On Mon, Sep 29, 2025 at 2:19 PM Jiri Slaby <jirislaby@kernel.org> wrote: > > Hi, > > On 28. 09. 25, 4:48, Binbin Zhou wrote: > > Hi Greg: > > > > Thanks for your reply. > > > > On Wed, Sep 24, 2025 at 6:22 PM Greg Kroah-Hartman > > <gregkh@linuxfoundation.org> wrote: > >> > >> On Wed, Sep 24, 2025 at 02:29:37PM +0800, Binbin Zhou wrote: > >>> --- a/include/uapi/linux/serial_core.h > >>> +++ b/include/uapi/linux/serial_core.h > >>> @@ -31,6 +31,7 @@ > >>> #define PORT_ALTR_16550_F128 28 /* Altera 16550 UART with 128 FIFOs */ > >>> #define PORT_RT2880 29 /* Ralink RT2880 internal UART */ > >>> #define PORT_16550A_FSL64 30 /* Freescale 16550 UART with 64 FIFOs */ > >>> +#define PORT_LOONGSON 31 /* Loongson 16550 UART */ > >> > >> Why does userspace need to have this value exported? > > > > Sorry, this was a cheap mistake. > > It should follow the existing latest macro definition as follows: > > That was not the point. The point was why do you need that at all? Emm... We attempted to define Loongson UART as a new `uart_config` entry. Therefore, `PORT_LOONGSON` is referenced as follows: diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c index 719faf92aa8a..53efe841656f 100644 --- a/drivers/tty/serial/8250/8250_port.c +++ b/drivers/tty/serial/8250/8250_port.c @@ -310,6 +310,14 @@ static const struct serial8250_config uart_config[] = { .rxtrig_bytes = {1, 8, 16, 30}, .flags = UART_CAP_FIFO | UART_CAP_AFE, }, + [PORT_LOONGSON] = { + .name = "Loongson", + .fifo_size = 16, + .tx_loadsz = 16, + .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, + .rxtrig_bytes = {1, 4, 8, 14}, + .flags = UART_CAP_FIFO, + }, }; /* Uart divisor latch read */ Additionally, `uart.port.type` will also be assigned the value `PORT_LOONGSON`. > > -- > js > suse labs -- Thanks. Binbin ^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [PATCH v5 2/3] serial: 8250: Add Loongson uart driver support 2025-09-30 3:03 ` Binbin Zhou @ 2025-10-08 12:16 ` Greg Kroah-Hartman 0 siblings, 0 replies; 16+ messages in thread From: Greg Kroah-Hartman @ 2025-10-08 12:16 UTC (permalink / raw) To: Binbin Zhou Cc: Jiri Slaby, Binbin Zhou, Huacai Chen, Rob Herring, Krzysztof Kozlowski, Conor Dooley, Haowei Zheng, Huacai Chen, Xuerui Wang, loongarch, devicetree, linux-serial On Tue, Sep 30, 2025 at 11:03:29AM +0800, Binbin Zhou wrote: > Hi Jiri: > > Thanks for your reply. > > On Mon, Sep 29, 2025 at 2:19 PM Jiri Slaby <jirislaby@kernel.org> wrote: > > > > Hi, > > > > On 28. 09. 25, 4:48, Binbin Zhou wrote: > > > Hi Greg: > > > > > > Thanks for your reply. > > > > > > On Wed, Sep 24, 2025 at 6:22 PM Greg Kroah-Hartman > > > <gregkh@linuxfoundation.org> wrote: > > >> > > >> On Wed, Sep 24, 2025 at 02:29:37PM +0800, Binbin Zhou wrote: > > >>> --- a/include/uapi/linux/serial_core.h > > >>> +++ b/include/uapi/linux/serial_core.h > > >>> @@ -31,6 +31,7 @@ > > >>> #define PORT_ALTR_16550_F128 28 /* Altera 16550 UART with 128 FIFOs */ > > >>> #define PORT_RT2880 29 /* Ralink RT2880 internal UART */ > > >>> #define PORT_16550A_FSL64 30 /* Freescale 16550 UART with 64 FIFOs */ > > >>> +#define PORT_LOONGSON 31 /* Loongson 16550 UART */ > > >> > > >> Why does userspace need to have this value exported? > > > > > > Sorry, this was a cheap mistake. > > > It should follow the existing latest macro definition as follows: > > > > That was not the point. The point was why do you need that at all? > > Emm... > We attempted to define Loongson UART as a new `uart_config` entry. > Therefore, `PORT_LOONGSON` is referenced as follows: > > diff --git a/drivers/tty/serial/8250/8250_port.c > b/drivers/tty/serial/8250/8250_port.c > index 719faf92aa8a..53efe841656f 100644 > --- a/drivers/tty/serial/8250/8250_port.c > +++ b/drivers/tty/serial/8250/8250_port.c > @@ -310,6 +310,14 @@ static const struct serial8250_config uart_config[] = { > .rxtrig_bytes = {1, 8, 16, 30}, > .flags = UART_CAP_FIFO | UART_CAP_AFE, > }, > + [PORT_LOONGSON] = { > + .name = "Loongson", > + .fifo_size = 16, > + .tx_loadsz = 16, > + .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, > + .rxtrig_bytes = {1, 4, 8, 14}, > + .flags = UART_CAP_FIFO, > + }, > }; > > /* Uart divisor latch read */ > > Additionally, `uart.port.type` will also be assigned the value `PORT_LOONGSON`. Yes, but that is the same exact value as PORT_PXA, which means this code will not really work properly, right? You can not just redefine an already used user/kernel value. thanks, greg k-h ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v5 2/3] serial: 8250: Add Loongson uart driver support 2025-09-24 6:29 ` [PATCH v5 2/3] serial: 8250: Add Loongson uart driver support Binbin Zhou 2025-09-24 10:22 ` Greg Kroah-Hartman @ 2025-09-29 6:26 ` Jiri Slaby 2025-09-30 3:07 ` Binbin Zhou 2025-09-30 12:01 ` Ilpo Järvinen 2025-09-30 11:58 ` Ilpo Järvinen 2 siblings, 2 replies; 16+ messages in thread From: Jiri Slaby @ 2025-09-29 6:26 UTC (permalink / raw) To: Binbin Zhou, Binbin Zhou, Huacai Chen, Rob Herring, Krzysztof Kozlowski, Conor Dooley, Greg Kroah-Hartman, Haowei Zheng Cc: Huacai Chen, Xuerui Wang, loongarch, devicetree, linux-serial On 24. 09. 25, 8:29, Binbin Zhou wrote: > Add the driver for on-chip UART used on Loongson family chips. > > The hardware is similar to 8250, but there are the following > differences: > - Some chips (such as Loongson-2K2000) have added a fractional division > register to obtain the required baud rate accurately, so the > {get,set}_divisor callback is overridden. > - Due to hardware defects, quirk handling is required for > UART_MCR/UART_MSR. So how hard would be to implement this in 8250 using existing (or new) callbacks+quirks? > --- /dev/null > +++ b/drivers/tty/serial/8250/8250_loongson.c > @@ -0,0 +1,202 @@ ... > +struct loongson_uart_data { > + int line; > + int mcr_invert; > + int msr_invert; These two should be unsigned. They should be u8, actually. > + struct reset_control *rst; > +}; > + > +static unsigned int serial_fixup(struct uart_port *p, unsigned int offset, unsigned int val) Both 'val' and ret type should be u8. > +{ > + struct loongson_uart_data *ddata = p->private_data; > + > + if (offset == UART_MCR) > + val ^= ddata->mcr_invert; > + > + if (offset == UART_MSR) > + val ^= ddata->msr_invert; > + > + return val; > +} > + > +static u32 loongson_serial_in(struct uart_port *p, unsigned int offset) > +{ > + unsigned int val; u8 > + > + val = readb(p->membase + (offset << p->regshift)); > + > + return serial_fixup(p, offset, val); > +} thanks, -- js suse labs ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v5 2/3] serial: 8250: Add Loongson uart driver support 2025-09-29 6:26 ` Jiri Slaby @ 2025-09-30 3:07 ` Binbin Zhou 2025-09-30 12:01 ` Ilpo Järvinen 1 sibling, 0 replies; 16+ messages in thread From: Binbin Zhou @ 2025-09-30 3:07 UTC (permalink / raw) To: Jiri Slaby Cc: Binbin Zhou, Huacai Chen, Rob Herring, Krzysztof Kozlowski, Conor Dooley, Greg Kroah-Hartman, Haowei Zheng, Huacai Chen, Xuerui Wang, loongarch, devicetree, linux-serial Hi Jiri: Thanks for your review. On Mon, Sep 29, 2025 at 2:27 PM Jiri Slaby <jirislaby@kernel.org> wrote: > > On 24. 09. 25, 8:29, Binbin Zhou wrote: > > Add the driver for on-chip UART used on Loongson family chips. > > > > The hardware is similar to 8250, but there are the following > > differences: > > - Some chips (such as Loongson-2K2000) have added a fractional division > > register to obtain the required baud rate accurately, so the > > {get,set}_divisor callback is overridden. > > - Due to hardware defects, quirk handling is required for > > UART_MCR/UART_MSR. > > So how hard would be to implement this in 8250 using existing (or new) > callbacks+quirks? Initially, we attempted to directly add Loongson UART support to the existing 8250 driver. The critical section is as follows: diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c index aa4de6907f77..6754f496a95c 100644 --- a/drivers/tty/serial/8250/8250_port.c +++ b/drivers/tty/serial/8250/8250_port.c @@ -395,14 +404,36 @@ static void hub6_serial_out(struct uart_port *p, int offset, int value) outb(value, p->iobase + 1); } static unsigned int mem_serial_in(struct uart_port *p, int offset) { + unsigned int val, offset0 = offset; offset = offset << p->regshift; - return readb(p->membase + offset); + val = readb(p->membase + offset); + if (p->type == PORT_LOONGSON) + val = serial_in_fixup(p, offset0, val); + return val; } static void mem_serial_out(struct uart_port *p, int offset, int value) { + if (p->type == PORT_LOONGSON) + value = serial_out_fixup(p, offset, value); offset = offset << p->regshift; writeb(value, p->membase + offset); } This made the code difficult to read, so I concluded it was not a good solution. Therefore, I separated it into a standalone driver. > > > --- /dev/null > > +++ b/drivers/tty/serial/8250/8250_loongson.c > > @@ -0,0 +1,202 @@ > ... > > +struct loongson_uart_data { > > + int line; > > + int mcr_invert; > > + int msr_invert; > > These two should be unsigned. They should be u8, actually. OK.... > > > + struct reset_control *rst; > > +}; > > + > > +static unsigned int serial_fixup(struct uart_port *p, unsigned int offset, unsigned int val) > > Both 'val' and ret type should be u8. OK... I will check twice. > > > +{ > > + struct loongson_uart_data *ddata = p->private_data; > > + > > + if (offset == UART_MCR) > > + val ^= ddata->mcr_invert; > > + > > + if (offset == UART_MSR) > > + val ^= ddata->msr_invert; > > + > > + return val; > > +} > > + > > +static u32 loongson_serial_in(struct uart_port *p, unsigned int offset) > > +{ > > + unsigned int val; > > u8 > > > + > > + val = readb(p->membase + (offset << p->regshift)); > > + > > + return serial_fixup(p, offset, val); > > +} > > thanks, > -- > js > suse labs -- Thanks. Binbin ^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [PATCH v5 2/3] serial: 8250: Add Loongson uart driver support 2025-09-29 6:26 ` Jiri Slaby 2025-09-30 3:07 ` Binbin Zhou @ 2025-09-30 12:01 ` Ilpo Järvinen 1 sibling, 0 replies; 16+ messages in thread From: Ilpo Järvinen @ 2025-09-30 12:01 UTC (permalink / raw) To: Jiri Slaby Cc: Binbin Zhou, Binbin Zhou, Huacai Chen, Rob Herring, Krzysztof Kozlowski, Conor Dooley, Greg Kroah-Hartman, Haowei Zheng, Huacai Chen, Xuerui Wang, loongarch, devicetree, linux-serial On Mon, 29 Sep 2025, Jiri Slaby wrote: > On 24. 09. 25, 8:29, Binbin Zhou wrote: > > Add the driver for on-chip UART used on Loongson family chips. > > > > The hardware is similar to 8250, but there are the following > > differences: > > - Some chips (such as Loongson-2K2000) have added a fractional division > > register to obtain the required baud rate accurately, so the > > {get,set}_divisor callback is overridden. > > - Due to hardware defects, quirk handling is required for > > UART_MCR/UART_MSR. > > So how hard would be to implement this in 8250 using existing (or new) > callbacks+quirks? ?? Isn't it exactly what this submission did? It implements custom in/out functions which handle the xor for the relevant bits? -- i. > > --- /dev/null > > +++ b/drivers/tty/serial/8250/8250_loongson.c > > @@ -0,0 +1,202 @@ > ... > > +struct loongson_uart_data { > > + int line; > > + int mcr_invert; > > + int msr_invert; > > These two should be unsigned. They should be u8, actually. > > > + struct reset_control *rst; > > +}; > > + > > +static unsigned int serial_fixup(struct uart_port *p, unsigned int offset, > > unsigned int val) > > Both 'val' and ret type should be u8. > > > +{ > > + struct loongson_uart_data *ddata = p->private_data; > > + > > + if (offset == UART_MCR) > > + val ^= ddata->mcr_invert; > > + > > + if (offset == UART_MSR) > > + val ^= ddata->msr_invert; > > + > > + return val; > > +} > > + > > +static u32 loongson_serial_in(struct uart_port *p, unsigned int offset) > > +{ > > + unsigned int val; > > u8 > > > + > > + val = readb(p->membase + (offset << p->regshift)); > > + > > + return serial_fixup(p, offset, val); > > +} > > thanks, > ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v5 2/3] serial: 8250: Add Loongson uart driver support 2025-09-24 6:29 ` [PATCH v5 2/3] serial: 8250: Add Loongson uart driver support Binbin Zhou 2025-09-24 10:22 ` Greg Kroah-Hartman 2025-09-29 6:26 ` Jiri Slaby @ 2025-09-30 11:58 ` Ilpo Järvinen 2025-10-09 2:52 ` Binbin Zhou 2 siblings, 1 reply; 16+ messages in thread From: Ilpo Järvinen @ 2025-09-30 11:58 UTC (permalink / raw) To: Binbin Zhou Cc: Binbin Zhou, Huacai Chen, Rob Herring, Krzysztof Kozlowski, Conor Dooley, Greg Kroah-Hartman, Jiri Slaby, Haowei Zheng, Huacai Chen, Xuerui Wang, loongarch, devicetree, linux-serial On Wed, 24 Sep 2025, Binbin Zhou wrote: > Add the driver for on-chip UART used on Loongson family chips. > > The hardware is similar to 8250, but there are the following > differences: > - Some chips (such as Loongson-2K2000) have added a fractional division > register to obtain the required baud rate accurately, so the > {get,set}_divisor callback is overridden. > - Due to hardware defects, quirk handling is required for > UART_MCR/UART_MSR. > > Co-developed-by: Haowei Zheng <zhenghaowei@loongson.cn> > Signed-off-by: Haowei Zheng <zhenghaowei@loongson.cn> > Signed-off-by: Binbin Zhou <zhoubinbin@loongson.cn> > --- > drivers/tty/serial/8250/8250_loongson.c | 202 ++++++++++++++++++++++++ > drivers/tty/serial/8250/8250_port.c | 8 + > drivers/tty/serial/8250/Kconfig | 10 ++ > drivers/tty/serial/8250/Makefile | 1 + > include/uapi/linux/serial_core.h | 1 + > 5 files changed, 222 insertions(+) > create mode 100644 drivers/tty/serial/8250/8250_loongson.c > > diff --git a/drivers/tty/serial/8250/8250_loongson.c b/drivers/tty/serial/8250/8250_loongson.c > new file mode 100644 > index 000000000000..a114b4e6d5c3 > --- /dev/null > +++ b/drivers/tty/serial/8250/8250_loongson.c > @@ -0,0 +1,202 @@ > +// SPDX-License-Identifier: GPL-2.0-or-later > +/* > + * Serial Port driver for Loongson family chips > + * > + * Copyright (C) 2020-2025 Loongson Technology Corporation Limited > + */ > + > +#include <linux/bitfield.h> > +#include <linux/module.h> > +#include <linux/property.h> > +#include <linux/mod_devicetable.h> > +#include <linux/reset.h> > + > +#include "8250.h" > + > +/* Divisor Latch Fraction Register */ > +#define LOONGSON_UART_DLF 0x2 > + > +/* Flags */ > +#define LOONGSON_UART_HAS_FRAC BIT(0) > +#define LOONGSON_UART_QUIRK_MCR BIT(1) > +#define LOONGSON_UART_QUIRK_MSR BIT(2) > + > +#define LS2K0500_UART_FLAG (LOONGSON_UART_QUIRK_MCR | LOONGSON_UART_QUIRK_MSR) > +#define LS2K1500_UART_FLAG (LOONGSON_UART_HAS_FRAC | LOONGSON_UART_QUIRK_MCR) > + > +struct loongson_uart_data { > + int line; > + int mcr_invert; > + int msr_invert; > + struct reset_control *rst; > +}; > + > +static unsigned int serial_fixup(struct uart_port *p, unsigned int offset, unsigned int val) > +{ > + struct loongson_uart_data *ddata = p->private_data; > + > + if (offset == UART_MCR) > + val ^= ddata->mcr_invert; > + > + if (offset == UART_MSR) > + val ^= ddata->msr_invert; > + > + return val; > +} > + > +static u32 loongson_serial_in(struct uart_port *p, unsigned int offset) > +{ > + unsigned int val; > + > + val = readb(p->membase + (offset << p->regshift)); > + > + return serial_fixup(p, offset, val); > +} > + > +static void loongson_serial_out(struct uart_port *p, unsigned int offset, unsigned int value) > +{ > + offset <<= p->regshift; > + writeb(serial_fixup(p, offset, value), p->membase + offset); This would be cleaner if you do that serial_fixup() on a preceeding line. Include for writeb()? > +} > + > +static unsigned int loongson_frac_get_divisor(struct uart_port *port, unsigned int baud, > + unsigned int *frac) > +{ > + unsigned int quot; > + > + quot = DIV_ROUND_CLOSEST((port->uartclk << 4), baud); Missing include. > + *frac = FIELD_GET(GENMASK(7, 0), quot); > + > + return FIELD_GET(GENMASK(15, 8), quot); Please name the fields properly with defines. You're also missing #include for GENMASK(). > +} > + > +static void loongson_frac_set_divisor(struct uart_port *port, unsigned int baud, > + unsigned int quot, unsigned int quot_frac) > +{ > + struct uart_8250_port *up = up_to_u8250p(port); > + > + serial_port_out(port, UART_LCR, up->lcr | UART_LCR_DLAB); > + serial_dl_write(up, quot); > + serial_port_out(port, LOONGSON_UART_DLF, quot_frac); > +} > + > +static int loongson_uart_probe(struct platform_device *pdev) > +{ > + struct device *dev = &pdev->dev; > + struct uart_8250_port uart = {}; > + struct loongson_uart_data *ddata; > + struct resource *res; > + unsigned int flags; > + int ret; > + > + ddata = devm_kzalloc(dev, sizeof(*ddata), GFP_KERNEL); > + if (!ddata) > + return -ENOMEM; > + > + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); > + if (!res) > + return -ENODEV; > + > + uart.port.irq = platform_get_irq(pdev, 0); > + if (uart.port.irq < 0) > + return -EINVAL; > + > + device_property_read_u32(dev, "clock-frequency", &uart.port.uartclk); > + > + spin_lock_init(&uart.port.lock); > + uart.port.flags = UPF_SHARE_IRQ | UPF_FIXED_PORT | UPF_FIXED_TYPE | UPF_IOREMAP; > + uart.port.iotype = UPIO_MEM; > + uart.port.regshift = 0; > + uart.port.dev = dev; > + uart.port.type = PORT_LOONGSON; > + uart.port.private_data = ddata; > + > + uart.port.mapbase = res->start; > + uart.port.mapsize = resource_size(res); > + uart.port.serial_in = loongson_serial_in; > + uart.port.serial_out = loongson_serial_out; > + > + flags = (uintptr_t)device_get_match_data(dev); Perhaps flags should be unsigned long? > + if (flags & LOONGSON_UART_HAS_FRAC) { > + uart.port.get_divisor = loongson_frac_get_divisor; > + uart.port.set_divisor = loongson_frac_set_divisor; > + } > + > + if (flags & LOONGSON_UART_QUIRK_MCR) > + ddata->mcr_invert |= (UART_MCR_RTS | UART_MCR_DTR); > + > + if (flags & LOONGSON_UART_QUIRK_MSR) > + ddata->msr_invert |= (UART_MSR_CTS | UART_MSR_DSR); I think it would be better to put these invert masks directly into a struct which is then put into .data. LOONGSON_UART_HAS_FRAC can be bool in that struct. > + ddata->rst = devm_reset_control_get_optional_shared(dev, NULL); > + if (IS_ERR(ddata->rst)) > + return PTR_ERR(ddata->rst); > + > + ret = reset_control_deassert(ddata->rst); > + if (ret) > + return ret; > + > + ret = serial8250_register_8250_port(&uart); > + if (ret < 0) { > + reset_control_assert(ddata->rst); > + return ret; > + } > + > + ddata->line = ret; > + platform_set_drvdata(pdev, ddata); > + > + return 0; > +} > + > +static void loongson_uart_remove(struct platform_device *pdev) > +{ > + struct loongson_uart_data *ddata = platform_get_drvdata(pdev); > + > + serial8250_unregister_port(ddata->line); > + reset_control_assert(ddata->rst); > +} > + > +static int loongson_uart_suspend(struct device *dev) > +{ > + struct loongson_uart_data *ddata = dev_get_drvdata(dev); > + > + serial8250_suspend_port(ddata->line); > + > + return 0; > +} > + > +static int loongson_uart_resume(struct device *dev) > +{ > + struct loongson_uart_data *data = dev_get_drvdata(dev); > + > + serial8250_resume_port(data->line); > + > + return 0; > +} > + > +static DEFINE_SIMPLE_DEV_PM_OPS(loongson_uart_pm_ops, loongson_uart_suspend, > + loongson_uart_resume); Include? Please check if you miss even more includes beyond those I've highlighted here. > +static const struct of_device_id loongson_uart_of_ids[] = { > + { .compatible = "loongson,ls2k0500-uart", .data = (void *)LS2K0500_UART_FLAG }, > + { .compatible = "loongson,ls2k1500-uart", .data = (void *)LS2K1500_UART_FLAG }, > + { /* sentinel */ }, Nit, no need for comma in the terminator entry. > +}; > +MODULE_DEVICE_TABLE(of, loongson_uart_of_ids); > + > +static struct platform_driver loongson_uart_driver = { > + .probe = loongson_uart_probe, > + .remove = loongson_uart_remove, > + .driver = { > + .name = "loongson-uart", > + .pm = pm_ptr(&loongson_uart_pm_ops), > + .of_match_table = loongson_uart_of_ids, > + }, > +}; > + > +module_platform_driver(loongson_uart_driver); > + > +MODULE_DESCRIPTION("Loongson UART driver"); > +MODULE_AUTHOR("Loongson Technology Corporation Limited."); > +MODULE_LICENSE("GPL"); > diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c > index 719faf92aa8a..53efe841656f 100644 > --- a/drivers/tty/serial/8250/8250_port.c > +++ b/drivers/tty/serial/8250/8250_port.c > @@ -310,6 +310,14 @@ static const struct serial8250_config uart_config[] = { > .rxtrig_bytes = {1, 8, 16, 30}, > .flags = UART_CAP_FIFO | UART_CAP_AFE, > }, > + [PORT_LOONGSON] = { > + .name = "Loongson", > + .fifo_size = 16, > + .tx_loadsz = 16, > + .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, > + .rxtrig_bytes = {1, 4, 8, 14}, > + .flags = UART_CAP_FIFO, > + }, This is exactly identical to PORT_16550A. Just use PORT_16550A instead of adding a new one unnecessarily. -- i. > }; > > /* Uart divisor latch read */ > diff --git a/drivers/tty/serial/8250/Kconfig b/drivers/tty/serial/8250/Kconfig > index f64ef0819cd4..98236b3bec10 100644 > --- a/drivers/tty/serial/8250/Kconfig > +++ b/drivers/tty/serial/8250/Kconfig > @@ -468,6 +468,16 @@ config SERIAL_8250_OMAP_TTYO_FIXUP > not booting kernel because the serial console remains silent in case > they forgot to update the command line. > > +config SERIAL_8250_LOONGSON > + tristate "Loongson 8250 based serial port" > + depends on SERIAL_8250 > + depends on LOONGARCH || COMPILE_TEST > + help > + If you have a machine based on LoongArch CPU you can enable > + its onboard serial ports by enabling this option. The option > + is applicable to both devicetree and ACPI, say Y to this option. > + If unsure, say N. > + > config SERIAL_8250_LPC18XX > tristate "NXP LPC18xx/43xx serial port support" > depends on SERIAL_8250 && OF && (ARCH_LPC18XX || COMPILE_TEST) > diff --git a/drivers/tty/serial/8250/Makefile b/drivers/tty/serial/8250/Makefile > index 513a0941c284..e318a3240789 100644 > --- a/drivers/tty/serial/8250/Makefile > +++ b/drivers/tty/serial/8250/Makefile > @@ -38,6 +38,7 @@ obj-$(CONFIG_SERIAL_8250_HP300) += 8250_hp300.o > obj-$(CONFIG_SERIAL_8250_HUB6) += 8250_hub6.o > obj-$(CONFIG_SERIAL_8250_INGENIC) += 8250_ingenic.o > obj-$(CONFIG_SERIAL_8250_IOC3) += 8250_ioc3.o > +obj-$(CONFIG_SERIAL_8250_LOONGSON) += 8250_loongson.o > obj-$(CONFIG_SERIAL_8250_LPC18XX) += 8250_lpc18xx.o > obj-$(CONFIG_SERIAL_8250_LPSS) += 8250_lpss.o > obj-$(CONFIG_SERIAL_8250_MEN_MCB) += 8250_men_mcb.o > diff --git a/include/uapi/linux/serial_core.h b/include/uapi/linux/serial_core.h > index 9c007a106330..607cf060a72a 100644 > --- a/include/uapi/linux/serial_core.h > +++ b/include/uapi/linux/serial_core.h > @@ -31,6 +31,7 @@ > #define PORT_ALTR_16550_F128 28 /* Altera 16550 UART with 128 FIFOs */ > #define PORT_RT2880 29 /* Ralink RT2880 internal UART */ > #define PORT_16550A_FSL64 30 /* Freescale 16550 UART with 64 FIFOs */ > +#define PORT_LOONGSON 31 /* Loongson 16550 UART */ > > /* > * ARM specific type numbers. These are not currently guaranteed > ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v5 2/3] serial: 8250: Add Loongson uart driver support 2025-09-30 11:58 ` Ilpo Järvinen @ 2025-10-09 2:52 ` Binbin Zhou 2025-10-09 11:46 ` Ilpo Järvinen 0 siblings, 1 reply; 16+ messages in thread From: Binbin Zhou @ 2025-10-09 2:52 UTC (permalink / raw) To: Ilpo Järvinen Cc: Binbin Zhou, Huacai Chen, Rob Herring, Krzysztof Kozlowski, Conor Dooley, Greg Kroah-Hartman, Jiri Slaby, Haowei Zheng, Huacai Chen, Xuerui Wang, loongarch, devicetree, linux-serial Hi Ilpo: Sorry for the late reply and thanks for your detailed review. On Tue, Sep 30, 2025 at 7:58 PM Ilpo Järvinen <ilpo.jarvinen@linux.intel.com> wrote: > > On Wed, 24 Sep 2025, Binbin Zhou wrote: > > > Add the driver for on-chip UART used on Loongson family chips. > > > > The hardware is similar to 8250, but there are the following > > differences: > > - Some chips (such as Loongson-2K2000) have added a fractional division > > register to obtain the required baud rate accurately, so the > > {get,set}_divisor callback is overridden. > > - Due to hardware defects, quirk handling is required for > > UART_MCR/UART_MSR. > > > > Co-developed-by: Haowei Zheng <zhenghaowei@loongson.cn> > > Signed-off-by: Haowei Zheng <zhenghaowei@loongson.cn> > > Signed-off-by: Binbin Zhou <zhoubinbin@loongson.cn> > > --- > > drivers/tty/serial/8250/8250_loongson.c | 202 ++++++++++++++++++++++++ > > drivers/tty/serial/8250/8250_port.c | 8 + > > drivers/tty/serial/8250/Kconfig | 10 ++ > > drivers/tty/serial/8250/Makefile | 1 + > > include/uapi/linux/serial_core.h | 1 + > > 5 files changed, 222 insertions(+) > > create mode 100644 drivers/tty/serial/8250/8250_loongson.c > > > > diff --git a/drivers/tty/serial/8250/8250_loongson.c b/drivers/tty/serial/8250/8250_loongson.c > > new file mode 100644 > > index 000000000000..a114b4e6d5c3 > > --- /dev/null > > +++ b/drivers/tty/serial/8250/8250_loongson.c > > @@ -0,0 +1,202 @@ > > +// SPDX-License-Identifier: GPL-2.0-or-later > > +/* > > + * Serial Port driver for Loongson family chips > > + * > > + * Copyright (C) 2020-2025 Loongson Technology Corporation Limited > > + */ > > + > > +#include <linux/bitfield.h> > > +#include <linux/module.h> > > +#include <linux/property.h> > > +#include <linux/mod_devicetable.h> > > +#include <linux/reset.h> > > + > > +#include "8250.h" > > + > > +/* Divisor Latch Fraction Register */ > > +#define LOONGSON_UART_DLF 0x2 > > + > > +/* Flags */ > > +#define LOONGSON_UART_HAS_FRAC BIT(0) > > +#define LOONGSON_UART_QUIRK_MCR BIT(1) > > +#define LOONGSON_UART_QUIRK_MSR BIT(2) > > + > > +#define LS2K0500_UART_FLAG (LOONGSON_UART_QUIRK_MCR | LOONGSON_UART_QUIRK_MSR) > > +#define LS2K1500_UART_FLAG (LOONGSON_UART_HAS_FRAC | LOONGSON_UART_QUIRK_MCR) > > + > > +struct loongson_uart_data { > > + int line; > > + int mcr_invert; > > + int msr_invert; > > + struct reset_control *rst; > > +}; > > + > > +static unsigned int serial_fixup(struct uart_port *p, unsigned int offset, unsigned int val) > > +{ > > + struct loongson_uart_data *ddata = p->private_data; > > + > > + if (offset == UART_MCR) > > + val ^= ddata->mcr_invert; > > + > > + if (offset == UART_MSR) > > + val ^= ddata->msr_invert; > > + > > + return val; > > +} > > + > > +static u32 loongson_serial_in(struct uart_port *p, unsigned int offset) > > +{ > > + unsigned int val; > > + > > + val = readb(p->membase + (offset << p->regshift)); > > + > > + return serial_fixup(p, offset, val); > > +} > > + > > +static void loongson_serial_out(struct uart_port *p, unsigned int offset, unsigned int value) > > +{ > > + offset <<= p->regshift; > > + writeb(serial_fixup(p, offset, value), p->membase + offset); > > This would be cleaner if you do that serial_fixup() on a preceeding line. ok. I will split serial_fixup() on a preceding line. > > Include for writeb()? #include <linux/io.h> > > > +} > > + > > +static unsigned int loongson_frac_get_divisor(struct uart_port *port, unsigned int baud, > > + unsigned int *frac) > > +{ > > + unsigned int quot; > > + > > + quot = DIV_ROUND_CLOSEST((port->uartclk << 4), baud); > > Missing include. #include <linux/math.h> > > > + *frac = FIELD_GET(GENMASK(7, 0), quot); > > + > > + return FIELD_GET(GENMASK(15, 8), quot); > > Please name the fields properly with defines. > > You're also missing #include for GENMASK(). #include <linux/bits.h> > > > +} > > + > > +static void loongson_frac_set_divisor(struct uart_port *port, unsigned int baud, > > + unsigned int quot, unsigned int quot_frac) > > +{ > > + struct uart_8250_port *up = up_to_u8250p(port); > > + > > + serial_port_out(port, UART_LCR, up->lcr | UART_LCR_DLAB); > > + serial_dl_write(up, quot); > > + serial_port_out(port, LOONGSON_UART_DLF, quot_frac); > > +} > > + > > +static int loongson_uart_probe(struct platform_device *pdev) > > +{ > > + struct device *dev = &pdev->dev; > > + struct uart_8250_port uart = {}; > > + struct loongson_uart_data *ddata; > > + struct resource *res; > > + unsigned int flags; > > + int ret; > > + > > + ddata = devm_kzalloc(dev, sizeof(*ddata), GFP_KERNEL); > > + if (!ddata) > > + return -ENOMEM; > > + > > + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); > > + if (!res) > > + return -ENODEV; > > + > > + uart.port.irq = platform_get_irq(pdev, 0); > > + if (uart.port.irq < 0) > > + return -EINVAL; > > + > > + device_property_read_u32(dev, "clock-frequency", &uart.port.uartclk); > > + > > + spin_lock_init(&uart.port.lock); > > + uart.port.flags = UPF_SHARE_IRQ | UPF_FIXED_PORT | UPF_FIXED_TYPE | UPF_IOREMAP; > > + uart.port.iotype = UPIO_MEM; > > + uart.port.regshift = 0; > > + uart.port.dev = dev; > > + uart.port.type = PORT_LOONGSON; > > + uart.port.private_data = ddata; > > + > > + uart.port.mapbase = res->start; > > + uart.port.mapsize = resource_size(res); > > + uart.port.serial_in = loongson_serial_in; > > + uart.port.serial_out = loongson_serial_out; > > + > > + flags = (uintptr_t)device_get_match_data(dev); > > Perhaps flags should be unsigned long? > > > + if (flags & LOONGSON_UART_HAS_FRAC) { > > + uart.port.get_divisor = loongson_frac_get_divisor; > > + uart.port.set_divisor = loongson_frac_set_divisor; > > + } > > + > > + if (flags & LOONGSON_UART_QUIRK_MCR) > > + ddata->mcr_invert |= (UART_MCR_RTS | UART_MCR_DTR); > > + > > + if (flags & LOONGSON_UART_QUIRK_MSR) > > + ddata->msr_invert |= (UART_MSR_CTS | UART_MSR_DSR); > > I think it would be better to put these invert masks directly into a > struct which is then put into .data. LOONGSON_UART_HAS_FRAC can be bool > in that struct. I attempted the following refactoring: struct loongson_uart_ddata { bool has_frac; u8 mcr_invert; u8 msr_invert; }; static const struct loongson_uart_ddata ls2k0500_uart_data { .has_frac = false, .mcr_invert = UART_MCR_RTS | UART_MCR_DTR, .msr_invert = UART_MSR_CTS | UART_MSR_DSR, }; static const struct loongson_uart_ddata ls2k1500_uart_data { .has_frac = true, .mcr_invert = UART_MCR_RTS | UART_MCR_DTR, .msr_invert = 0, }; struct loongson_uart_priv { int line; struct clk *clk; struct resource *res; struct reset_control *rst; struct loongson_uart_ddata *ddata; }; ............. In loongson_uart_probe(): priv->ddata = device_get_match_data(dev); if (priv->ddata->has_frac) { port->get_divisor = loongson_frac_get_divisor; port->set_divisor = loongson_frac_set_divisor; } ............. static const struct of_device_id loongson_uart_of_ids[] = { { .compatible = "loongson,ls2k0500-uart", .data = ls2k0500_uart_data }, { .compatible = "loongson,ls2k1500-uart", .data = ls2k1500_uart_data }, { }, }; > > > + ddata->rst = devm_reset_control_get_optional_shared(dev, NULL); > > + if (IS_ERR(ddata->rst)) > > + return PTR_ERR(ddata->rst); > > + > > + ret = reset_control_deassert(ddata->rst); > > + if (ret) > > + return ret; > > + > > + ret = serial8250_register_8250_port(&uart); > > + if (ret < 0) { > > + reset_control_assert(ddata->rst); > > + return ret; > > + } > > + > > + ddata->line = ret; > > + platform_set_drvdata(pdev, ddata); > > + > > + return 0; > > +} > > + > > +static void loongson_uart_remove(struct platform_device *pdev) > > +{ > > + struct loongson_uart_data *ddata = platform_get_drvdata(pdev); > > + > > + serial8250_unregister_port(ddata->line); > > + reset_control_assert(ddata->rst); > > +} > > + > > +static int loongson_uart_suspend(struct device *dev) > > +{ > > + struct loongson_uart_data *ddata = dev_get_drvdata(dev); > > + > > + serial8250_suspend_port(ddata->line); > > + > > + return 0; > > +} > > + > > +static int loongson_uart_resume(struct device *dev) > > +{ > > + struct loongson_uart_data *data = dev_get_drvdata(dev); > > + > > + serial8250_resume_port(data->line); > > + > > + return 0; > > +} > > + > > +static DEFINE_SIMPLE_DEV_PM_OPS(loongson_uart_pm_ops, loongson_uart_suspend, > > + loongson_uart_resume); > > Include? Please check if you miss even more includes beyond those I've > highlighted here. #include <linux/pm.h> I will check all missed include files. > > > +static const struct of_device_id loongson_uart_of_ids[] = { > > + { .compatible = "loongson,ls2k0500-uart", .data = (void *)LS2K0500_UART_FLAG }, > > + { .compatible = "loongson,ls2k1500-uart", .data = (void *)LS2K1500_UART_FLAG }, > > + { /* sentinel */ }, > > Nit, no need for comma in the terminator entry. ok.. > > > +}; > > +MODULE_DEVICE_TABLE(of, loongson_uart_of_ids); > > + > > +static struct platform_driver loongson_uart_driver = { > > + .probe = loongson_uart_probe, > > + .remove = loongson_uart_remove, > > + .driver = { > > + .name = "loongson-uart", > > + .pm = pm_ptr(&loongson_uart_pm_ops), > > + .of_match_table = loongson_uart_of_ids, > > + }, > > +}; > > + > > +module_platform_driver(loongson_uart_driver); > > + > > +MODULE_DESCRIPTION("Loongson UART driver"); > > +MODULE_AUTHOR("Loongson Technology Corporation Limited."); > > +MODULE_LICENSE("GPL"); > > diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c > > index 719faf92aa8a..53efe841656f 100644 > > --- a/drivers/tty/serial/8250/8250_port.c > > +++ b/drivers/tty/serial/8250/8250_port.c > > @@ -310,6 +310,14 @@ static const struct serial8250_config uart_config[] = { > > .rxtrig_bytes = {1, 8, 16, 30}, > > .flags = UART_CAP_FIFO | UART_CAP_AFE, > > }, > > + [PORT_LOONGSON] = { > > + .name = "Loongson", > > + .fifo_size = 16, > > + .tx_loadsz = 16, > > + .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, > > + .rxtrig_bytes = {1, 4, 8, 14}, > > + .flags = UART_CAP_FIFO, > > + }, > > This is exactly identical to PORT_16550A. Just use PORT_16550A instead of > adding a new one unnecessarily. OK. I will drop this part and use PORT_16550A in 8250_loongson driver. > > -- > i. > > > }; > > > > /* Uart divisor latch read */ > > diff --git a/drivers/tty/serial/8250/Kconfig b/drivers/tty/serial/8250/Kconfig > > index f64ef0819cd4..98236b3bec10 100644 > > --- a/drivers/tty/serial/8250/Kconfig > > +++ b/drivers/tty/serial/8250/Kconfig > > @@ -468,6 +468,16 @@ config SERIAL_8250_OMAP_TTYO_FIXUP > > not booting kernel because the serial console remains silent in case > > they forgot to update the command line. > > > > +config SERIAL_8250_LOONGSON > > + tristate "Loongson 8250 based serial port" > > + depends on SERIAL_8250 > > + depends on LOONGARCH || COMPILE_TEST > > + help > > + If you have a machine based on LoongArch CPU you can enable > > + its onboard serial ports by enabling this option. The option > > + is applicable to both devicetree and ACPI, say Y to this option. > > + If unsure, say N. > > + > > config SERIAL_8250_LPC18XX > > tristate "NXP LPC18xx/43xx serial port support" > > depends on SERIAL_8250 && OF && (ARCH_LPC18XX || COMPILE_TEST) > > diff --git a/drivers/tty/serial/8250/Makefile b/drivers/tty/serial/8250/Makefile > > index 513a0941c284..e318a3240789 100644 > > --- a/drivers/tty/serial/8250/Makefile > > +++ b/drivers/tty/serial/8250/Makefile > > @@ -38,6 +38,7 @@ obj-$(CONFIG_SERIAL_8250_HP300) += 8250_hp300.o > > obj-$(CONFIG_SERIAL_8250_HUB6) += 8250_hub6.o > > obj-$(CONFIG_SERIAL_8250_INGENIC) += 8250_ingenic.o > > obj-$(CONFIG_SERIAL_8250_IOC3) += 8250_ioc3.o > > +obj-$(CONFIG_SERIAL_8250_LOONGSON) += 8250_loongson.o > > obj-$(CONFIG_SERIAL_8250_LPC18XX) += 8250_lpc18xx.o > > obj-$(CONFIG_SERIAL_8250_LPSS) += 8250_lpss.o > > obj-$(CONFIG_SERIAL_8250_MEN_MCB) += 8250_men_mcb.o > > diff --git a/include/uapi/linux/serial_core.h b/include/uapi/linux/serial_core.h > > index 9c007a106330..607cf060a72a 100644 > > --- a/include/uapi/linux/serial_core.h > > +++ b/include/uapi/linux/serial_core.h > > @@ -31,6 +31,7 @@ > > #define PORT_ALTR_16550_F128 28 /* Altera 16550 UART with 128 FIFOs */ > > #define PORT_RT2880 29 /* Ralink RT2880 internal UART */ > > #define PORT_16550A_FSL64 30 /* Freescale 16550 UART with 64 FIFOs */ > > +#define PORT_LOONGSON 31 /* Loongson 16550 UART */ > > > > /* > > * ARM specific type numbers. These are not currently guaranteed > > -- Thanks. Binbin ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v5 2/3] serial: 8250: Add Loongson uart driver support 2025-10-09 2:52 ` Binbin Zhou @ 2025-10-09 11:46 ` Ilpo Järvinen 0 siblings, 0 replies; 16+ messages in thread From: Ilpo Järvinen @ 2025-10-09 11:46 UTC (permalink / raw) To: Binbin Zhou Cc: Binbin Zhou, Huacai Chen, Rob Herring, Krzysztof Kozlowski, Conor Dooley, Greg Kroah-Hartman, Jiri Slaby, Haowei Zheng, Huacai Chen, Xuerui Wang, loongarch, devicetree, linux-serial [-- Attachment #1: Type: text/plain, Size: 3608 bytes --] On Thu, 9 Oct 2025, Binbin Zhou wrote: > Hi Ilpo: > > Sorry for the late reply and thanks for your detailed review. > > On Tue, Sep 30, 2025 at 7:58 PM Ilpo Järvinen > <ilpo.jarvinen@linux.intel.com> wrote: > > > > On Wed, 24 Sep 2025, Binbin Zhou wrote: > > > > > Add the driver for on-chip UART used on Loongson family chips. > > > > > > The hardware is similar to 8250, but there are the following > > > differences: > > > - Some chips (such as Loongson-2K2000) have added a fractional division > > > register to obtain the required baud rate accurately, so the > > > {get,set}_divisor callback is overridden. > > > - Due to hardware defects, quirk handling is required for > > > UART_MCR/UART_MSR. > > > > > > Co-developed-by: Haowei Zheng <zhenghaowei@loongson.cn> > > > Signed-off-by: Haowei Zheng <zhenghaowei@loongson.cn> > > > Signed-off-by: Binbin Zhou <zhoubinbin@loongson.cn> > > > --- > > > +static unsigned int serial_fixup(struct uart_port *p, unsigned int offset, unsigned int val) > > > +{ > > > + struct loongson_uart_data *ddata = p->private_data; > > > + > > > + if (offset == UART_MCR) > > > + val ^= ddata->mcr_invert; > > > + > > > + if (offset == UART_MSR) > > > + val ^= ddata->msr_invert; One additional thing, this could use switch/case. I'd just do: ... case UART_MSR: return val ^ ddata->msr_invert; default: return val; } That way you don't need to use breaks. > > > + if (flags & LOONGSON_UART_HAS_FRAC) { > > > + uart.port.get_divisor = loongson_frac_get_divisor; > > > + uart.port.set_divisor = loongson_frac_set_divisor; > > > + } > > > + > > > + if (flags & LOONGSON_UART_QUIRK_MCR) > > > + ddata->mcr_invert |= (UART_MCR_RTS | UART_MCR_DTR); > > > + > > > + if (flags & LOONGSON_UART_QUIRK_MSR) > > > + ddata->msr_invert |= (UART_MSR_CTS | UART_MSR_DSR); > > > > I think it would be better to put these invert masks directly into a > > struct which is then put into .data. LOONGSON_UART_HAS_FRAC can be bool > > in that struct. > > I attempted the following refactoring: > > struct loongson_uart_ddata { > bool has_frac; > u8 mcr_invert; > u8 msr_invert; > }; > > static const struct loongson_uart_ddata ls2k0500_uart_data { > .has_frac = false, > .mcr_invert = UART_MCR_RTS | UART_MCR_DTR, > .msr_invert = UART_MSR_CTS | UART_MSR_DSR, > }; > > static const struct loongson_uart_ddata ls2k1500_uart_data { > .has_frac = true, > .mcr_invert = UART_MCR_RTS | UART_MCR_DTR, > .msr_invert = 0, > }; > > struct loongson_uart_priv { > int line; > struct clk *clk; > struct resource *res; > struct reset_control *rst; > struct loongson_uart_ddata *ddata; This can and should be const struct as well as those underlying data structs are const too. > }; > > ............. > In loongson_uart_probe(): > priv->ddata = device_get_match_data(dev); > > if (priv->ddata->has_frac) { > port->get_divisor = loongson_frac_get_divisor; > port->set_divisor = loongson_frac_set_divisor; > } > > > ............. > static const struct of_device_id loongson_uart_of_ids[] = { > { .compatible = "loongson,ls2k0500-uart", .data = ls2k0500_uart_data }, > { .compatible = "loongson,ls2k1500-uart", .data = ls2k1500_uart_data }, > { }, > }; -- i. ^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH v5 3/3] LoongArch: dts: Add uart new compatible string 2025-09-24 6:29 [PATCH v5 0/3] uart: Introduce uart driver for the Loongson family Binbin Zhou 2025-09-24 6:29 ` [PATCH v5 1/3] dt-bindings: serial: 8250: Add Loongson uart compatible Binbin Zhou 2025-09-24 6:29 ` [PATCH v5 2/3] serial: 8250: Add Loongson uart driver support Binbin Zhou @ 2025-09-24 6:29 ` Binbin Zhou 2 siblings, 0 replies; 16+ messages in thread From: Binbin Zhou @ 2025-09-24 6:29 UTC (permalink / raw) To: Binbin Zhou, Huacai Chen, Rob Herring, Krzysztof Kozlowski, Conor Dooley, Greg Kroah-Hartman, Jiri Slaby, Haowei Zheng Cc: Huacai Chen, Xuerui Wang, loongarch, devicetree, linux-serial, Binbin Zhou Add loongson,ls2k*-uart compatible string on uarts. Co-developed-by: Haowei Zheng <zhenghaowei@loongson.cn> Signed-off-by: Haowei Zheng <zhenghaowei@loongson.cn> Signed-off-by: Binbin Zhou <zhoubinbin@loongson.cn> --- arch/loongarch/boot/dts/loongson-2k0500.dtsi | 2 +- arch/loongarch/boot/dts/loongson-2k1000.dtsi | 2 +- arch/loongarch/boot/dts/loongson-2k2000.dtsi | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/loongarch/boot/dts/loongson-2k0500.dtsi b/arch/loongarch/boot/dts/loongson-2k0500.dtsi index 588ebc3bded4..357de4ca7555 100644 --- a/arch/loongarch/boot/dts/loongson-2k0500.dtsi +++ b/arch/loongarch/boot/dts/loongson-2k0500.dtsi @@ -380,7 +380,7 @@ tsensor: thermal-sensor@1fe11500 { }; uart0: serial@1ff40800 { - compatible = "ns16550a"; + compatible = "loongson,ls2k0500-uart", "ns16550a"; reg = <0x0 0x1ff40800 0x0 0x10>; clock-frequency = <100000000>; interrupt-parent = <&eiointc>; diff --git a/arch/loongarch/boot/dts/loongson-2k1000.dtsi b/arch/loongarch/boot/dts/loongson-2k1000.dtsi index d8e01e2534dd..60ab425f793f 100644 --- a/arch/loongarch/boot/dts/loongson-2k1000.dtsi +++ b/arch/loongarch/boot/dts/loongson-2k1000.dtsi @@ -297,7 +297,7 @@ dma-controller@1fe00c40 { }; uart0: serial@1fe20000 { - compatible = "ns16550a"; + compatible = "loongson,ls2k1000-uart", "loongson,ls2k0500-uart", "ns16550a"; reg = <0x0 0x1fe20000 0x0 0x10>; clock-frequency = <125000000>; interrupt-parent = <&liointc0>; diff --git a/arch/loongarch/boot/dts/loongson-2k2000.dtsi b/arch/loongarch/boot/dts/loongson-2k2000.dtsi index 00cc485b753b..6c77b86ee06c 100644 --- a/arch/loongarch/boot/dts/loongson-2k2000.dtsi +++ b/arch/loongarch/boot/dts/loongson-2k2000.dtsi @@ -250,7 +250,7 @@ i2c@1fe00130 { }; uart0: serial@1fe001e0 { - compatible = "ns16550a"; + compatible = "loongson,ls2k2000-uart", "loongson,ls2k1500-uart", "ns16550a"; reg = <0x0 0x1fe001e0 0x0 0x10>; clock-frequency = <100000000>; interrupt-parent = <&liointc>; -- 2.47.3 ^ permalink raw reply related [flat|nested] 16+ messages in thread
end of thread, other threads:[~2025-10-09 11:46 UTC | newest] Thread overview: 16+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2025-09-24 6:29 [PATCH v5 0/3] uart: Introduce uart driver for the Loongson family Binbin Zhou 2025-09-24 6:29 ` [PATCH v5 1/3] dt-bindings: serial: 8250: Add Loongson uart compatible Binbin Zhou 2025-09-24 19:19 ` Conor Dooley 2025-09-24 6:29 ` [PATCH v5 2/3] serial: 8250: Add Loongson uart driver support Binbin Zhou 2025-09-24 10:22 ` Greg Kroah-Hartman 2025-09-28 2:48 ` Binbin Zhou 2025-09-29 6:19 ` Jiri Slaby 2025-09-30 3:03 ` Binbin Zhou 2025-10-08 12:16 ` Greg Kroah-Hartman 2025-09-29 6:26 ` Jiri Slaby 2025-09-30 3:07 ` Binbin Zhou 2025-09-30 12:01 ` Ilpo Järvinen 2025-09-30 11:58 ` Ilpo Järvinen 2025-10-09 2:52 ` Binbin Zhou 2025-10-09 11:46 ` Ilpo Järvinen 2025-09-24 6:29 ` [PATCH v5 3/3] LoongArch: dts: Add uart new compatible string Binbin Zhou
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).