* Re: [PATCH v5 8/8] ARM: defconfig: Add a zx29 defconfig file
From: Arnd Bergmann @ 2026-04-24 8:54 UTC (permalink / raw)
To: Linus Walleij, Stefan Dösinger
Cc: Jonathan Corbet, Shuah Khan, Russell King, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Krzysztof Kozlowski,
Alexandre Belloni, Drew Fustini, Greg Kroah-Hartman, Jiri Slaby,
linux-doc, linux-kernel, linux-arm-kernel, devicetree, soc,
linux-serial
In-Reply-To: <CAD++jL=_eDY_mG_QBreSrZiho0hUrDSciedq=vrxXaTiMwrSyg@mail.gmail.com>
On Fri, Apr 24, 2026, at 09:13, Linus Walleij wrote:
> On Tue, Apr 21, 2026 at 10:24 PM Stefan Dösinger
> <stefandoesinger@gmail.com> wrote:
>
>> This enables existing drivers that already are (UART) or will be (USB,
>> GPIO) necessary to operate this board even if they aren't declared in
>> the DTS yet.
>>
>> Signed-off-by: Stefan Dösinger <stefandoesinger@gmail.com>
>
> *I* personally (as SoC maintainer) think that having a few more defconfigs
> is fine, even helpful.
>
> But I would defer this to the more senior SoC maintainers because I think
> their stance is something like:
>
> - We have multi_v7_defconfig for compile testing
>
> - We know that binary gets way to big for your system: it's for build
> testing and perhaps booting in QEMU or systems with many MB of
> RAM, not for actually running it on products.
>
> - You are encouraged to keep your own defconfig out-of-tree.
Right, we clearly need to do something better than what we are with
the general defconfigs, as I'm sure many of the existing ones are
never actually used for booting a machine, and are horribly out of
date with the Kconfig options.
I wouldn't object to adding another defconfig for a new (or revived)
soc family, but I don't want to have more per-board ones.
Overall, we have about 70 defconfigs and 55 soc families that have their
own mach-* directory (plus a few without code), and the number of
defconfigs alone makes it hard to keep them up to date.
> However I even challenged this myself by adding a defconfig for memory
> constrained Broadcoms a while back (NACKed/ignored ;) so if it was all
> up to me I would merge this.
I don't even remember that discussion ;-)
One idea might be to have a tiny base defconfig, plus platform
specific fragments that add drivers. The problem is agreeing
what bits are essential enough to still get enabled in the
tiny config.
Arnd
^ permalink raw reply
* Re: [PATCH] serial: 8250_fourport: fix reference leak on failed device registration
From: Guangshuo Li @ 2026-04-24 8:53 UTC (permalink / raw)
To: Greg Kroah-Hartman, Jiri Slaby, Guangshuo Li, Russell King,
linux-kernel, linux-serial
In-Reply-To: <20260415184839.3796326-1-lgs201920130244@gmail.com>
Hi,
Please disregard this patch.
On Thu, 16 Apr 2026 at 02:48, Guangshuo Li <lgs201920130244@gmail.com> wrote:
>
> When platform_device_register() fails in fourport_init(), the embedded
> struct device in fourport_device has already been initialized by
> device_initialize(), but the failure path returns the error without
> dropping the device reference for the current platform device:
>
> fourport_init()
> -> platform_device_register(&fourport_device)
> -> device_initialize(&fourport_device.dev)
> -> setup_pdev_dma_masks(&fourport_device)
> -> platform_device_add(&fourport_device)
>
> This leads to a reference leak when platform_device_register() fails.
> Fix this by calling platform_device_put() before returning the error.
>
> The issue was identified by a static analysis tool I developed and
> confirmed by manual review.
>
> Fixes: ec9f47cd6a14c ("[PATCH] Serial: Split 8250 port table")
> Cc: stable@vger.kernel.org
> Signed-off-by: Guangshuo Li <lgs201920130244@gmail.com>
> ---
> drivers/tty/serial/8250/8250_fourport.c | 8 +++++++-
> 1 file changed, 7 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/tty/serial/8250/8250_fourport.c b/drivers/tty/serial/8250/8250_fourport.c
> index 3215b9b7afde..a65bc7316655 100644
> --- a/drivers/tty/serial/8250/8250_fourport.c
> +++ b/drivers/tty/serial/8250/8250_fourport.c
> @@ -34,7 +34,13 @@ static struct platform_device fourport_device = {
>
> static int __init fourport_init(void)
> {
> - return platform_device_register(&fourport_device);
> + int ret;
> +
> + ret = platform_device_register(&fourport_device);
> + if (ret)
> + platform_device_put(&fourport_device);
> +
> + return ret;
> }
>
> module_init(fourport_init);
> --
> 2.43.0
>
After re-checking it, fourport_device is a static platform_device and it
does not provide a dev.release callback. Therefore calling
platform_device_put() on the platform_device_register() failure path is
not appropriate here and can trigger the missing release callback
warning.
This falls into the same static platform_device pattern pointed out in
the other reviews, so I will drop this patch.
Sorry for the noise.
Best regards,
Guangshuo Li
^ permalink raw reply
* Re: [PATCH] serial: 8250_exar_st16c554: fix reference leak on failed device registration
From: Guangshuo Li @ 2026-04-24 8:52 UTC (permalink / raw)
To: Greg Kroah-Hartman, Jiri Slaby, Guangshuo Li, Paul B Schroeder,
Andrew Morton, linux-kernel, linux-serial
In-Reply-To: <20260415184032.3776292-1-lgs201920130244@gmail.com>
Hi,
Please disregard this patch.
On Thu, 16 Apr 2026 at 02:40, Guangshuo Li <lgs201920130244@gmail.com> wrote:
>
> When platform_device_register() fails in exar_init(), the embedded
> struct device in exar_device has already been initialized by
> device_initialize(), but the failure path returns the error without
> dropping the device reference for the current platform device:
>
> exar_init()
> -> platform_device_register(&exar_device)
> -> device_initialize(&exar_device.dev)
> -> setup_pdev_dma_masks(&exar_device)
> -> platform_device_add(&exar_device)
>
> This leads to a reference leak when platform_device_register() fails.
> Fix this by calling platform_device_put() before returning the error.
>
> The issue was identified by a static analysis tool I developed and
> confirmed by manual review.
>
> Fixes: e0980dafa329d ("[PATCH] Exar quad port serial")
> Cc: stable@vger.kernel.org
> Signed-off-by: Guangshuo Li <lgs201920130244@gmail.com>
> ---
> drivers/tty/serial/8250/8250_exar_st16c554.c | 8 +++++++-
> 1 file changed, 7 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/tty/serial/8250/8250_exar_st16c554.c b/drivers/tty/serial/8250/8250_exar_st16c554.c
> index 933811ebfaac..b2c37f0c52aa 100644
> --- a/drivers/tty/serial/8250/8250_exar_st16c554.c
> +++ b/drivers/tty/serial/8250/8250_exar_st16c554.c
> @@ -30,7 +30,13 @@ static struct platform_device exar_device = {
>
> static int __init exar_init(void)
> {
> - return platform_device_register(&exar_device);
> + int ret;
> +
> + ret = platform_device_register(&exar_device);
> + if (ret)
> + platform_device_put(&exar_device);
> +
> + return ret;
> }
>
> module_init(exar_init);
> --
> 2.43.0
>
After re-checking it, exar_device is a static platform_device and it does
not provide a dev.release callback. Therefore calling
platform_device_put() on the platform_device_register() failure path is
not appropriate here and can trigger the missing release callback
warning.
This falls into the same static platform_device pattern pointed out in
the other reviews, so I will drop this patch.
Sorry for the noise.
Best regards,
Guangshuo Li
^ permalink raw reply
* Re: [PATCH] serial: 8250_boca: fix reference leak on failed device registration
From: Guangshuo Li @ 2026-04-24 8:50 UTC (permalink / raw)
To: Greg Kroah-Hartman, Jiri Slaby, Guangshuo Li, Russell King,
linux-kernel, linux-serial
In-Reply-To: <20260415183756.3770073-1-lgs201920130244@gmail.com>
Hi,
Please disregard this patch.
On Thu, 16 Apr 2026 at 02:38, Guangshuo Li <lgs201920130244@gmail.com> wrote:
>
> When platform_device_register() fails in boca_init(), the embedded
> struct device in boca_device has already been initialized by
> device_initialize(), but the failure path returns the error without
> dropping the device reference for the current platform device:
>
> boca_init()
> -> platform_device_register(&boca_device)
> -> device_initialize(&boca_device.dev)
> -> setup_pdev_dma_masks(&boca_device)
> -> platform_device_add(&boca_device)
>
> This leads to a reference leak when platform_device_register() fails.
> Fix this by calling platform_device_put() before returning the error.
>
> The issue was identified by a static analysis tool I developed and
> confirmed by manual review.
>
> Fixes: ec9f47cd6a14c ("[PATCH] Serial: Split 8250 port table")
> Cc: stable@vger.kernel.org
> Signed-off-by: Guangshuo Li <lgs201920130244@gmail.com>
> ---
> drivers/tty/serial/8250/8250_boca.c | 8 +++++++-
> 1 file changed, 7 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/tty/serial/8250/8250_boca.c b/drivers/tty/serial/8250/8250_boca.c
> index a9b97c034653..70ea8e30ae80 100644
> --- a/drivers/tty/serial/8250/8250_boca.c
> +++ b/drivers/tty/serial/8250/8250_boca.c
> @@ -39,7 +39,13 @@ static struct platform_device boca_device = {
>
> static int __init boca_init(void)
> {
> - return platform_device_register(&boca_device);
> + int ret;
> +
> + ret = platform_device_register(&boca_device);
> + if (ret)
> + platform_device_put(&boca_device);
> +
> + return ret;
> }
>
> module_init(boca_init);
> --
> 2.43.0
>
After re-checking it, boca_device is a static platform_device and it does
not provide a dev.release callback. Therefore calling
platform_device_put() on the platform_device_register() failure path is
not appropriate here and can trigger the missing release callback
warning.
This falls into the same static platform_device pattern pointed out in
the other reviews, so I will drop this patch.
Sorry for the noise.
Best regards,
Guangshuo Li
^ permalink raw reply
* Re: [PATCH] serial: 8250_accent: fix reference leak on failed device registration
From: Guangshuo Li @ 2026-04-24 8:49 UTC (permalink / raw)
To: Jiri Slaby
Cc: Greg Kroah-Hartman, Russell King, linux-kernel, linux-serial,
stable
In-Reply-To: <463cec4f-a038-4bd0-90df-76e0ef48381c@kernel.org>
Hi Jiri,
Please disregard this patch.
On Thu, 16 Apr 2026 at 14:14, Jiri Slaby <jirislaby@kernel.org> wrote:
>
> Hi,
>
> On 15. 04. 26, 20:34, Guangshuo Li wrote:
> > When platform_device_register() fails in accent_init(), the embedded
> > struct device in accent_device has already been initialized by
> > device_initialize(), but the failure path returns the error without
> > dropping the device reference for the current platform device:
> >
> > accent_init()
> > -> platform_device_register(&accent_device)
> > -> device_initialize(&accent_device.dev)
> > -> setup_pdev_dma_masks(&accent_device)
> > -> platform_device_add(&accent_device)
> >
> > This leads to a reference leak when platform_device_register() fails.
>
> What reference exactly?
>
> > Fix this by calling platform_device_put() before returning the error.
> >
> > The issue was identified by a static analysis tool I developed and
> > confirmed by manual review.
>
> How did you verify you did the right change?
>
> > Fixes: ec9f47cd6a14c ("[PATCH] Serial: Split 8250 port table")
> > Cc: stable@vger.kernel.org
> > Signed-off-by: Guangshuo Li <lgs201920130244@gmail.com>
> > ---
> > drivers/tty/serial/8250/8250_accent.c | 8 +++++++-
> > 1 file changed, 7 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/tty/serial/8250/8250_accent.c b/drivers/tty/serial/8250/8250_accent.c
> > index 1691f1a57f89..e9cf40268c0e 100644
> > --- a/drivers/tty/serial/8250/8250_accent.c
> > +++ b/drivers/tty/serial/8250/8250_accent.c
> > @@ -25,7 +25,13 @@ static struct platform_device accent_device = {
> >
> > static int __init accent_init(void)
> > {
> > - return platform_device_register(&accent_device);
> > + int ret;
> > +
> > + ret = platform_device_register(&accent_device);
> > + if (ret)
> > + platform_device_put(&accent_device);
>
> In particular, what does put_device() do on a static device, even
> initialized, ie. with no device::release? Try it...
>
> IMO, all the patches are bogus.
>
> thanks,
> --
> js
> suse labs
After re-checking it, accent_device is a static platform_device and it
does not provide a dev.release callback, so calling platform_device_put()
on the platform_device_register() failure path is not appropriate and can
trigger the missing release callback warning.
This falls into the same static platform_device pattern as the other
patches, so I will drop it.
Sorry for the noise.
Best regards,
Guangshuo Li
^ permalink raw reply
* Re: [PATCH v5 8/8] ARM: defconfig: Add a zx29 defconfig file
From: Arnd Bergmann @ 2026-04-24 7:48 UTC (permalink / raw)
To: Stefan Dösinger, Jonathan Corbet, Shuah Khan, Russell King,
Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Krzysztof Kozlowski, Alexandre Belloni, Linus Walleij,
Drew Fustini, Greg Kroah-Hartman, Jiri Slaby
Cc: linux-doc, linux-kernel, linux-arm-kernel, devicetree, soc,
linux-serial
In-Reply-To: <20260421-send-v5-8-ace038e63515@gmail.com>
On Tue, Apr 21, 2026, at 22:23, Stefan Dösinger wrote:
> This enables existing drivers that already are (UART) or will be (USB,
> GPIO) necessary to operate this board even if they aren't declared in
> the DTS yet.
>
> Signed-off-by: Stefan Dösinger <stefandoesinger@gmail.com>
I'll reply to Linus' comment as well, the defconfigs are generally
not in a great shape across many platforms, so we should come up
with some better policies there.
Either way, the patch description above should at least explain
why you think you need your own defconfig, as we don't normally
take those.
Some comments about the contents of this file:
> +++ b/arch/arm/configs/zx29_defconfig
> @@ -0,0 +1,89 @@
> +CONFIG_SYSVIPC=y
> +CONFIG_BLK_DEV_INITRD=y
> +# CONFIG_RD_BZIP2 is not set
> +# CONFIG_RD_LZMA is not set
> +# CONFIG_RD_XZ is not set
> +# CONFIG_RD_LZ4 is not set
> +CONFIG_EXPERT=y
What is the reason for CONFIG_EXPERT here? Can you avoid this?
> +CONFIG_CMDLINE="console=ttyAMA0 earlyprintk root=/dev/ram rw"
A definconfig should normall not rely on earlyprintk, just add
that when you actually need to debug the super-early boot
stages. With "earlycon" it should pick up the right console
from the stdout path and work almost as early.
> +CONFIG_BINFMT_FLAT=y
Are you actually using flat binaries? I wasn't aware that this
is still possible on MMU-enabled kernels.
> +CONFIG_BLK_DEV_RAM=y
> +CONFIG_BLK_DEV_RAM_COUNT=4
The old ramdisk boot is going away in the future, please use
initramfs instead. This should also save a good amount of RAM.
> +CONFIG_DEVTMPFS=y # FIXME: This is specific to my initrd. Remove
> before upstream
stale comment?
> +CONFIG_CONFIG_TMPFS=y
Typo?
Arnd
^ permalink raw reply
* Re: [PATCH v5 8/8] ARM: defconfig: Add a zx29 defconfig file
From: Linus Walleij @ 2026-04-24 7:13 UTC (permalink / raw)
To: Stefan Dösinger
Cc: Jonathan Corbet, Shuah Khan, Russell King, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Arnd Bergmann,
Krzysztof Kozlowski, Alexandre Belloni, Drew Fustini,
Greg Kroah-Hartman, Jiri Slaby, linux-doc, linux-kernel,
linux-arm-kernel, devicetree, soc, linux-serial
In-Reply-To: <20260421-send-v5-8-ace038e63515@gmail.com>
On Tue, Apr 21, 2026 at 10:24 PM Stefan Dösinger
<stefandoesinger@gmail.com> wrote:
> This enables existing drivers that already are (UART) or will be (USB,
> GPIO) necessary to operate this board even if they aren't declared in
> the DTS yet.
>
> Signed-off-by: Stefan Dösinger <stefandoesinger@gmail.com>
*I* personally (as SoC maintainer) think that having a few more defconfigs
is fine, even helpful.
But I would defer this to the more senior SoC maintainers because I think
their stance is something like:
- We have multi_v7_defconfig for compile testing
- We know that binary gets way to big for your system: it's for build
testing and perhaps booting in QEMU or systems with many MB of
RAM, not for actually running it on products.
- You are encouraged to keep your own defconfig out-of-tree.
However I even challenged this myself by adding a defconfig for memory
constrained Broadcoms a while back (NACKed/ignored ;) so if it was all
up to me I would merge this.
Yours,
Linus Walleij
^ permalink raw reply
* Re: [PATCH v5 4/8] ARM: zte: Add support for zx29 low level debug
From: Linus Walleij @ 2026-04-24 7:07 UTC (permalink / raw)
To: Stefan Dösinger
Cc: Jonathan Corbet, Shuah Khan, Russell King, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Arnd Bergmann,
Krzysztof Kozlowski, Alexandre Belloni, Drew Fustini,
Greg Kroah-Hartman, Jiri Slaby, linux-doc, linux-kernel,
linux-arm-kernel, devicetree, soc, linux-serial
In-Reply-To: <20260421-send-v5-4-ace038e63515@gmail.com>
On Tue, Apr 21, 2026 at 10:24 PM Stefan Dösinger
<stefandoesinger@gmail.com> wrote:
> This is based on the removed zx29 code. A separate (more complicated)
> patch will re-add the register map to the pl011 serial driver.
>
> Signed-off-by: Stefan Dösinger <stefandoesinger@gmail.com>
Reviewed-by: Linus Walleij <linusw@kernel.org>
Yours,
Linus Walleij
^ permalink raw reply
* Re: [PATCH v5 1/8] ARM: zte: Add zx297520v3 platform support
From: Linus Walleij @ 2026-04-24 7:06 UTC (permalink / raw)
To: Stefan Dösinger
Cc: Jonathan Corbet, Shuah Khan, Russell King, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Arnd Bergmann,
Krzysztof Kozlowski, Alexandre Belloni, Drew Fustini,
Greg Kroah-Hartman, Jiri Slaby, linux-doc, linux-kernel,
linux-arm-kernel, devicetree, soc, linux-serial
In-Reply-To: <20260421-send-v5-1-ace038e63515@gmail.com>
On Tue, Apr 21, 2026 at 10:24 PM Stefan Dösinger
<stefandoesinger@gmail.com> wrote:
> This SoC is used in low end LTE-to-WiFi routers, for example some D-Link
> DWR 932 revisions, ZTE K10, ZLT S10 4G, but also models that are branded
> and sold by ISPs themselves. They are widespread in Africa, China,
> Russia and Eastern Europe.
>
> This SoC is a relative of the zx296702 and zx296718 that had some
> upstream support until commit 89d4f98ae90d ("ARM: remove zte zx
> platform"). My eventual goal is to enable OpenWRT to run on these
> devices.
>
> Signed-off-by: Stefan Dösinger <stefandoesinger@gmail.com>
Didn't I review this already? I don't remember, anyway:
Reviewed-by: Linus Walleij <linusw@kernel.org>
Yours,
Linus Walleij
^ permalink raw reply
* Re: [PATCH v5 6/8] amba/serial: amba-pl011: Bring back zx29 UART support
From: Linus Walleij @ 2026-04-24 7:05 UTC (permalink / raw)
To: Stefan Dösinger
Cc: Jonathan Corbet, Shuah Khan, Russell King, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Arnd Bergmann,
Krzysztof Kozlowski, Alexandre Belloni, Drew Fustini,
Greg Kroah-Hartman, Jiri Slaby, linux-doc, linux-kernel,
linux-arm-kernel, devicetree, soc, linux-serial
In-Reply-To: <20260421-send-v5-6-ace038e63515@gmail.com>
On Tue, Apr 21, 2026 at 10:24 PM Stefan Dösinger
<stefandoesinger@gmail.com> wrote:
> This is based on code removed in commit 89d4f98ae90d ("ARM: remove zte
> zx platform"). I did not bring back the zx29-uart .compatible as the
> arm,primecell-periphid does the job.
>
> Signed-off-by: Stefan Dösinger <stefandoesinger@gmail.com>
I like this.
Reviewed-by: Linus Walleij <linusw@kernel.org>
Yours,
Linus Walleij
^ permalink raw reply
* [PATCH v4 4/4] serial: 8250_dw: Use a fixed CPR value for UltraRISC DP1000 UART
From: Jia Wang @ 2026-04-24 5:39 UTC (permalink / raw)
To: Ilpo Järvinen, Andy Shevchenko, Greg Kroah-Hartman,
Jiri Slaby, Paul Walmsley, Palmer Dabbelt, Albert Ou,
Alexandre Ghiti, Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: linux-kernel, linux-serial, linux-riscv, devicetree, Jia Wang
In-Reply-To: <20260424-ultrarisc-serial-v4-0-1765a0b4c4a0@ultrarisc.com>
The UltraRISC DP1000 UART does not provide the standard CPR register used
by 8250_dw to discover port capabilities.
Provide a fixed CPR value for the DP1000-specific compatible so the
driver can configure the port correctly.
Signed-off-by: Jia Wang <wangjia@ultrarisc.com>
---
drivers/tty/serial/8250/8250_dw.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/drivers/tty/serial/8250/8250_dw.c b/drivers/tty/serial/8250/8250_dw.c
index d3c2c9c84d9f..43e60b0fb9fd 100644
--- a/drivers/tty/serial/8250/8250_dw.c
+++ b/drivers/tty/serial/8250/8250_dw.c
@@ -959,6 +959,15 @@ static const struct dw8250_platform_data dw8250_intc10ee = {
.quirks = DW_UART_QUIRK_IER_KICK,
};
+static const struct dw8250_platform_data dw8250_ultrarisc_dp1000_data = {
+ .usr_reg = DW_UART_USR,
+ .cpr_value = FIELD_PREP_CONST(DW_UART_CPR_ABP_DATA_WIDTH, 2) |
+ DW_UART_CPR_THRE_MODE |
+ DW_UART_CPR_DMA_EXTRA |
+ FIELD_PREP_CONST(DW_UART_CPR_FIFO_MODE, 0x02),
+ .quirks = DW_UART_QUIRK_CPR_VALUE,
+};
+
static const struct of_device_id dw8250_of_match[] = {
{ .compatible = "snps,dw-apb-uart", .data = &dw8250_dw_apb },
{ .compatible = "cavium,octeon-3860-uart", .data = &dw8250_octeon_3860_data },
@@ -966,6 +975,7 @@ static const struct of_device_id dw8250_of_match[] = {
{ .compatible = "renesas,rzn1-uart", .data = &dw8250_renesas_rzn1_data },
{ .compatible = "sophgo,sg2044-uart", .data = &dw8250_skip_set_rate_data },
{ .compatible = "starfive,jh7100-uart", .data = &dw8250_skip_set_rate_data },
+ { .compatible = "ultrarisc,dp1000-uart", .data = &dw8250_ultrarisc_dp1000_data },
{ /* Sentinel */ }
};
MODULE_DEVICE_TABLE(of, dw8250_of_match);
--
2.34.1
^ permalink raw reply related
* [PATCH v4 3/4] dt-bindings: serial: snps-dw-apb-uart: Add UltraRISC DP1000 UART
From: Jia Wang @ 2026-04-24 5:39 UTC (permalink / raw)
To: Ilpo Järvinen, Andy Shevchenko, Greg Kroah-Hartman,
Jiri Slaby, Paul Walmsley, Palmer Dabbelt, Albert Ou,
Alexandre Ghiti, Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: linux-kernel, linux-serial, linux-riscv, devicetree, Jia Wang,
Conor Dooley
In-Reply-To: <20260424-ultrarisc-serial-v4-0-1765a0b4c4a0@ultrarisc.com>
UltraRISC DP1000 integrates a Synopsys DesignWare APB UART, but it does
not provide the standard CPR and UCV registers.
Signed-off-by: Jia Wang <wangjia@ultrarisc.com>
Acked-by: Conor Dooley <conor.dooley@microchip.com>
---
Documentation/devicetree/bindings/serial/snps-dw-apb-uart.yaml | 1 +
1 file changed, 1 insertion(+)
diff --git a/Documentation/devicetree/bindings/serial/snps-dw-apb-uart.yaml b/Documentation/devicetree/bindings/serial/snps-dw-apb-uart.yaml
index 6efe43089a74..f84600f66df8 100644
--- a/Documentation/devicetree/bindings/serial/snps-dw-apb-uart.yaml
+++ b/Documentation/devicetree/bindings/serial/snps-dw-apb-uart.yaml
@@ -77,6 +77,7 @@ properties:
- starfive,jh7100-hsuart
- starfive,jh7100-uart
- starfive,jh7110-uart
+ - ultrarisc,dp1000-uart
- const: snps,dw-apb-uart
- const: snps,dw-apb-uart
--
2.34.1
^ permalink raw reply related
* [PATCH v4 2/4] serial: 8250_dw: build Renesas RZN1 CPR value from DW_UART_CPR_* definitions
From: Jia Wang @ 2026-04-24 5:39 UTC (permalink / raw)
To: Ilpo Järvinen, Andy Shevchenko, Greg Kroah-Hartman,
Jiri Slaby, Paul Walmsley, Palmer Dabbelt, Albert Ou,
Alexandre Ghiti, Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: linux-kernel, linux-serial, linux-riscv, devicetree, Jia Wang
In-Reply-To: <20260424-ultrarisc-serial-v4-0-1765a0b4c4a0@ultrarisc.com>
Replace the magic CPR value for Renesas RZ/N1 with a composition using
DW_UART_CPR_* bit/field definitions and FIELD_PREP_CONST().
Signed-off-by: Jia Wang <wangjia@ultrarisc.com>
---
drivers/tty/serial/8250/8250_dw.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/drivers/tty/serial/8250/8250_dw.c b/drivers/tty/serial/8250/8250_dw.c
index 467755bf0092..d3c2c9c84d9f 100644
--- a/drivers/tty/serial/8250/8250_dw.c
+++ b/drivers/tty/serial/8250/8250_dw.c
@@ -937,7 +937,15 @@ static const struct dw8250_platform_data dw8250_armada_38x_data = {
static const struct dw8250_platform_data dw8250_renesas_rzn1_data = {
.usr_reg = DW_UART_USR,
- .cpr_value = 0x00012f32,
+ .cpr_value = FIELD_PREP_CONST(DW_UART_CPR_ABP_DATA_WIDTH, 2) |
+ DW_UART_CPR_AFCE_MODE |
+ DW_UART_CPR_THRE_MODE |
+ DW_UART_CPR_ADDITIONAL_FEATURES |
+ DW_UART_CPR_FIFO_ACCESS |
+ DW_UART_CPR_FIFO_STAT |
+ DW_UART_CPR_SHADOW |
+ DW_UART_CPR_DMA_EXTRA |
+ FIELD_PREP_CONST(DW_UART_CPR_FIFO_MODE, 0x01),
.quirks = DW_UART_QUIRK_CPR_VALUE | DW_UART_QUIRK_IS_DMA_FC,
};
--
2.34.1
^ permalink raw reply related
* [PATCH v4 0/4] serial: 8250_dw: Add support for UltraRISC DP1000 UART
From: Jia Wang @ 2026-04-24 5:39 UTC (permalink / raw)
To: Ilpo Järvinen, Andy Shevchenko, Greg Kroah-Hartman,
Jiri Slaby, Paul Walmsley, Palmer Dabbelt, Albert Ou,
Alexandre Ghiti, Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: linux-kernel, linux-serial, linux-riscv, devicetree, Jia Wang,
Conor Dooley
This patch series adds support for the UltraRISC DP1000 UART controller.
The series includes four patches. The first two are preparatory cleanups;
the last two add the DP1000 compatible and fixed CPR handling.
The patches have been tested on an UltraRISC DP1000 development board with
Linux v7.0-rc7, verifying basic UART functionality.
Signed-off-by: Jia Wang <wangjia@ultrarisc.com>
---
Changes in v4:
- Added two preparatory patches before the original series, shifting patch
numbers (former 1/2 -> now 3/4).
- Patch 1:
* Move all DesignWare UART register/field definitions into 8250_dwlib.h
for shared use with 8250_dw.
- Patch 2:
* Converted the Renesas RZ/N1 CPR magic value to use DW_UART_CPR_* macros
and FIELD_PREP_CONST().
- Patch 4:
* Converted the UltraRISC DP1000 CPR magic value to use
DW_UART_CPR_* macros and FIELD_PREP_CONST() (value unchanged).
- Link to v3: https://patch.msgid.link/20260421-ultrarisc-serial-v3-0-3d7f09c2420e@ultrarisc.com
Changes in v3:
- Rebased on Linux v7.0-rc7.
- Patch 1:
* Removed separate `items` entry for DP1000, merging it into the
existing `enum` to comply with the schema.
* Updated commit message to describe DP1000 UART hardware differences.
- Patch 2:
* Drop the custom quirk for missing CPR register.
* Switch to using DW_UART_QUIRK_CPR_VALUE to provide a fixed CPR value.
- Link to v2: https://patch.msgid.link/20260316-ultrarisc-serial-v2-0-6ab3e7fa891c@ultrarisc.com
Changes in v2:
- Rebased on Linux v7.0-rc4 (previously on v7.0-rc2).
- Reordered patch series: DT binding patch comes before driver changes.
- Updated commit message for DT binding patch.
- Link to v1: https://patch.msgid.link/20260316-ultrarisc-serial-v1-0-c464f3e933a5@ultrarisc.com
---
Jia Wang (4):
serial: 8250_dwlib: move DesignWare register definitions to header
serial: 8250_dw: build Renesas RZN1 CPR value from DW_UART_CPR_* definitions
dt-bindings: serial: snps-dw-apb-uart: Add UltraRISC DP1000 UART
serial: 8250_dw: Use a fixed CPR value for UltraRISC DP1000 UART
.../bindings/serial/snps-dw-apb-uart.yaml | 1 +
drivers/tty/serial/8250/8250_dw.c | 31 ++++++-----
drivers/tty/serial/8250/8250_dwlib.c | 49 -----------------
drivers/tty/serial/8250/8250_dwlib.h | 63 ++++++++++++++++++++++
4 files changed, 83 insertions(+), 61 deletions(-)
---
base-commit: e774d5f1bc27a85f858bce7688509e866f8e8a4e
change-id: 20260309-ultrarisc-serial-64ff637edf26
Best regards,
--
Jia Wang <wangjia@ultrarisc.com>
^ permalink raw reply
* [PATCH v4 1/4] serial: 8250_dwlib: move DesignWare register definitions to header
From: Jia Wang @ 2026-04-24 5:39 UTC (permalink / raw)
To: Ilpo Järvinen, Andy Shevchenko, Greg Kroah-Hartman,
Jiri Slaby, Paul Walmsley, Palmer Dabbelt, Albert Ou,
Alexandre Ghiti, Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: linux-kernel, linux-serial, linux-riscv, devicetree, Jia Wang
In-Reply-To: <20260424-ultrarisc-serial-v4-0-1765a0b4c4a0@ultrarisc.com>
Move the DW_UART_* register offsets and CPR bit/field definitions from
8250_dwlib.c into 8250_dwlib.h so they can be shared by 8250_dw and
8250_dwlib users.
Add an include guard for 8250_dwlib.h.
Signed-off-by: Jia Wang <wangjia@ultrarisc.com>
---
drivers/tty/serial/8250/8250_dw.c | 11 -------
drivers/tty/serial/8250/8250_dwlib.c | 49 ----------------------------
drivers/tty/serial/8250/8250_dwlib.h | 63 ++++++++++++++++++++++++++++++++++++
3 files changed, 63 insertions(+), 60 deletions(-)
diff --git a/drivers/tty/serial/8250/8250_dw.c b/drivers/tty/serial/8250/8250_dw.c
index 94beadb4024d..467755bf0092 100644
--- a/drivers/tty/serial/8250/8250_dw.c
+++ b/drivers/tty/serial/8250/8250_dw.c
@@ -34,22 +34,11 @@
#include "8250_dwlib.h"
-/* Offsets for the DesignWare specific registers */
-#define DW_UART_USR 0x1f /* UART Status Register */
-#define DW_UART_DMASA 0xa8 /* DMA Software Ack */
-
#define OCTEON_UART_USR 0x27 /* UART Status Register */
#define RZN1_UART_TDMACR 0x10c /* DMA Control Register Transmit Mode */
#define RZN1_UART_RDMACR 0x110 /* DMA Control Register Receive Mode */
-/* DesignWare specific register fields */
-#define DW_UART_IIR_IID GENMASK(3, 0)
-
-#define DW_UART_MCR_SIRE BIT(6)
-
-#define DW_UART_USR_BUSY BIT(0)
-
/* Renesas specific register fields */
#define RZN1_UART_xDMACR_DMA_EN BIT(0)
#define RZN1_UART_xDMACR_1_WORD_BURST (0 << 1)
diff --git a/drivers/tty/serial/8250/8250_dwlib.c b/drivers/tty/serial/8250/8250_dwlib.c
index b055d89cfb39..8859e66d2d71 100644
--- a/drivers/tty/serial/8250/8250_dwlib.c
+++ b/drivers/tty/serial/8250/8250_dwlib.c
@@ -13,55 +13,6 @@
#include "8250_dwlib.h"
-/* Offsets for the DesignWare specific registers */
-#define DW_UART_TCR 0xac /* Transceiver Control Register (RS485) */
-#define DW_UART_DE_EN 0xb0 /* Driver Output Enable Register */
-#define DW_UART_RE_EN 0xb4 /* Receiver Output Enable Register */
-#define DW_UART_DLF 0xc0 /* Divisor Latch Fraction Register */
-#define DW_UART_RAR 0xc4 /* Receive Address Register */
-#define DW_UART_TAR 0xc8 /* Transmit Address Register */
-#define DW_UART_LCR_EXT 0xcc /* Line Extended Control Register */
-#define DW_UART_CPR 0xf4 /* Component Parameter Register */
-#define DW_UART_UCV 0xf8 /* UART Component Version */
-
-/* Receive / Transmit Address Register bits */
-#define DW_UART_ADDR_MASK GENMASK(7, 0)
-
-/* Line Status Register bits */
-#define DW_UART_LSR_ADDR_RCVD BIT(8)
-
-/* Transceiver Control Register bits */
-#define DW_UART_TCR_RS485_EN BIT(0)
-#define DW_UART_TCR_RE_POL BIT(1)
-#define DW_UART_TCR_DE_POL BIT(2)
-#define DW_UART_TCR_XFER_MODE GENMASK(4, 3)
-#define DW_UART_TCR_XFER_MODE_DE_DURING_RE FIELD_PREP(DW_UART_TCR_XFER_MODE, 0)
-#define DW_UART_TCR_XFER_MODE_SW_DE_OR_RE FIELD_PREP(DW_UART_TCR_XFER_MODE, 1)
-#define DW_UART_TCR_XFER_MODE_DE_OR_RE FIELD_PREP(DW_UART_TCR_XFER_MODE, 2)
-
-/* Line Extended Control Register bits */
-#define DW_UART_LCR_EXT_DLS_E BIT(0)
-#define DW_UART_LCR_EXT_ADDR_MATCH BIT(1)
-#define DW_UART_LCR_EXT_SEND_ADDR BIT(2)
-#define DW_UART_LCR_EXT_TRANSMIT_MODE BIT(3)
-
-/* Component Parameter Register bits */
-#define DW_UART_CPR_ABP_DATA_WIDTH GENMASK(1, 0)
-#define DW_UART_CPR_AFCE_MODE BIT(4)
-#define DW_UART_CPR_THRE_MODE BIT(5)
-#define DW_UART_CPR_SIR_MODE BIT(6)
-#define DW_UART_CPR_SIR_LP_MODE BIT(7)
-#define DW_UART_CPR_ADDITIONAL_FEATURES BIT(8)
-#define DW_UART_CPR_FIFO_ACCESS BIT(9)
-#define DW_UART_CPR_FIFO_STAT BIT(10)
-#define DW_UART_CPR_SHADOW BIT(11)
-#define DW_UART_CPR_ENCODED_PARMS BIT(12)
-#define DW_UART_CPR_DMA_EXTRA BIT(13)
-#define DW_UART_CPR_FIFO_MODE GENMASK(23, 16)
-
-/* Helper for FIFO size calculation */
-#define DW_UART_CPR_FIFO_SIZE(a) (FIELD_GET(DW_UART_CPR_FIFO_MODE, (a)) * 16)
-
/*
* divisor = div(I) + div(F)
* "I" means integer, "F" means fractional
diff --git a/drivers/tty/serial/8250/8250_dwlib.h b/drivers/tty/serial/8250/8250_dwlib.h
index 7dd2a8e7b780..5026a123cf42 100644
--- a/drivers/tty/serial/8250/8250_dwlib.h
+++ b/drivers/tty/serial/8250/8250_dwlib.h
@@ -1,11 +1,72 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/* Synopsys DesignWare 8250 library header file. */
+#ifndef _SERIAL_8250_DWLIB_H_
+#define _SERIAL_8250_DWLIB_H_
+
+#include <linux/bitfield.h>
+#include <linux/bits.h>
#include <linux/io.h>
#include <linux/types.h>
#include "8250.h"
+/* Offsets for the DesignWare specific registers */
+#define DW_UART_USR 0x1f /* UART Status Register */
+#define DW_UART_DMASA 0xa8 /* DMA Software Ack */
+#define DW_UART_TCR 0xac /* Transceiver Control Register (RS485) */
+#define DW_UART_DE_EN 0xb0 /* Driver Output Enable Register */
+#define DW_UART_RE_EN 0xb4 /* Receiver Output Enable Register */
+#define DW_UART_DLF 0xc0 /* Divisor Latch Fraction Register */
+#define DW_UART_RAR 0xc4 /* Receive Address Register */
+#define DW_UART_TAR 0xc8 /* Transmit Address Register */
+#define DW_UART_LCR_EXT 0xcc /* Line Extended Control Register */
+#define DW_UART_CPR 0xf4 /* Component Parameter Register */
+#define DW_UART_UCV 0xf8 /* UART Component Version */
+
+/* Receive / Transmit Address Register bits */
+#define DW_UART_ADDR_MASK GENMASK(7, 0)
+
+/* Line Status Register bits */
+#define DW_UART_LSR_ADDR_RCVD BIT(8)
+
+/* Transceiver Control Register bits */
+#define DW_UART_TCR_RS485_EN BIT(0)
+#define DW_UART_TCR_RE_POL BIT(1)
+#define DW_UART_TCR_DE_POL BIT(2)
+#define DW_UART_TCR_XFER_MODE GENMASK(4, 3)
+#define DW_UART_TCR_XFER_MODE_DE_DURING_RE FIELD_PREP(DW_UART_TCR_XFER_MODE, 0)
+#define DW_UART_TCR_XFER_MODE_SW_DE_OR_RE FIELD_PREP(DW_UART_TCR_XFER_MODE, 1)
+#define DW_UART_TCR_XFER_MODE_DE_OR_RE FIELD_PREP(DW_UART_TCR_XFER_MODE, 2)
+
+/* Line Extended Control Register bits */
+#define DW_UART_LCR_EXT_DLS_E BIT(0)
+#define DW_UART_LCR_EXT_ADDR_MATCH BIT(1)
+#define DW_UART_LCR_EXT_SEND_ADDR BIT(2)
+#define DW_UART_LCR_EXT_TRANSMIT_MODE BIT(3)
+
+/* Component Parameter Register bits */
+#define DW_UART_CPR_ABP_DATA_WIDTH GENMASK(1, 0)
+#define DW_UART_CPR_AFCE_MODE BIT(4)
+#define DW_UART_CPR_THRE_MODE BIT(5)
+#define DW_UART_CPR_SIR_MODE BIT(6)
+#define DW_UART_CPR_SIR_LP_MODE BIT(7)
+#define DW_UART_CPR_ADDITIONAL_FEATURES BIT(8)
+#define DW_UART_CPR_FIFO_ACCESS BIT(9)
+#define DW_UART_CPR_FIFO_STAT BIT(10)
+#define DW_UART_CPR_SHADOW BIT(11)
+#define DW_UART_CPR_ENCODED_PARMS BIT(12)
+#define DW_UART_CPR_DMA_EXTRA BIT(13)
+#define DW_UART_CPR_FIFO_MODE GENMASK(23, 16)
+
+/* DesignWare specific register fields */
+#define DW_UART_IIR_IID GENMASK(3, 0)
+#define DW_UART_MCR_SIRE BIT(6)
+#define DW_UART_USR_BUSY BIT(0)
+
+/* Helper for FIFO size calculation */
+#define DW_UART_CPR_FIFO_SIZE(a) (FIELD_GET(DW_UART_CPR_FIFO_MODE, (a)) * 16)
+
struct dw8250_port_data {
/* Port properties */
int line;
@@ -38,3 +99,5 @@ static inline void dw8250_writel_ext(struct uart_port *p, int offset, u32 reg)
else
writel(reg, p->membase + offset);
}
+
+#endif /* _SERIAL_8250_DWLIB_H_ */
--
2.34.1
^ permalink raw reply related
* [PATCH 9/9] serial: max3100: use new UPIO_BUS as iotype
From: Hugo Villeneuve @ 2026-04-23 20:15 UTC (permalink / raw)
To: Greg Kroah-Hartman, Jiri Slaby
Cc: hugo, ilpo.jarvinen, linux-kernel, linux-serial, Hugo Villeneuve
In-Reply-To: <20260423-tty-upio-v1-0-baf82d3b86d1@dimonoff.com>
From: Hugo Villeneuve <hvilleneuve@dimonoff.com>
Now that we have a new UPIO_BUS I/O type, use it to register our serial
port. This allows the driver to work properly when using DT where
membase/iobase are not set.
Signed-off-by: Hugo Villeneuve <hvilleneuve@dimonoff.com>
---
drivers/tty/serial/max3100.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/tty/serial/max3100.c b/drivers/tty/serial/max3100.c
index 475b0a6efce4bec36aa4b94ccff83934dbdf9246..17a2ff410305142798ddbbb22b46f18eadce91aa 100644
--- a/drivers/tty/serial/max3100.c
+++ b/drivers/tty/serial/max3100.c
@@ -725,6 +725,7 @@ static int max3100_probe(struct spi_device *spi)
max3100s[i]->port.ops = &max3100_ops;
max3100s[i]->port.flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF;
max3100s[i]->port.line = i;
+ max3100s[i]->port.iotype = UPIO_BUS;
max3100s[i]->port.type = PORT_MAX3100;
max3100s[i]->port.dev = &spi->dev;
--
2.47.3
^ permalink raw reply related
* [PATCH 7/9] serial: sc16is7xx: use new UPIO_BUS as iotype
From: Hugo Villeneuve @ 2026-04-23 20:15 UTC (permalink / raw)
To: Greg Kroah-Hartman, Jiri Slaby
Cc: hugo, ilpo.jarvinen, linux-kernel, linux-serial, Hugo Villeneuve
In-Reply-To: <20260423-tty-upio-v1-0-baf82d3b86d1@dimonoff.com>
From: Hugo Villeneuve <hvilleneuve@dimonoff.com>
Now that we have a new UPIO_BUS I/O type, use it to register our serial
port and remove ambiguous membase/iobase workaround.
Note that commit 5da6b1c079e6 ("sc16is7xx: Set iobase to device index")
used the iobase field as an index within the device to allow infering
the order through sysfs, but this is no longer needed since
commit 1ef2c2df1199 ("serial: core: Fix serial core controller port name
to show controller id").
Signed-off-by: Hugo Villeneuve <hvilleneuve@dimonoff.com>
---
This means that displaying iomem_base will now always be zero:
cat /sys/class/tty/ttySC0/iomem_base
0x0
cat /sys/class/tty/ttySC1/iomem_base
0x0
...
But the index can be properly displayed with this instead (example with two
sc16is7xx devices):
$> ls -al /sys/class/tty/ttySC*/device
... /sys/class/tty/ttySC0/device -> ../../../spi1.0:0.0
... /sys/class/tty/ttySC1/device -> ../../../spi1.0:0.1
... /sys/class/tty/ttySC2/device -> ../../../spi3.0:0.0
... /sys/class/tty/ttySC3/device -> ../../../spi3.0:0.1
---
drivers/tty/serial/sc16is7xx.c | 9 +--------
1 file changed, 1 insertion(+), 8 deletions(-)
diff --git a/drivers/tty/serial/sc16is7xx.c b/drivers/tty/serial/sc16is7xx.c
index 1fd64a47341d8263c82fcadd90a4c2e549193e19..4b638e69f36f2d20253d8de31f52ecfe349aa39f 100644
--- a/drivers/tty/serial/sc16is7xx.c
+++ b/drivers/tty/serial/sc16is7xx.c
@@ -1472,14 +1472,7 @@ static int sc16is7xx_setup_channel(struct sc16is7xx_one *one, int i,
port->type = PORT_SC16IS7XX;
port->fifosize = SC16IS7XX_FIFO_SIZE;
port->flags = UPF_FIXED_TYPE | UPF_LOW_LATENCY;
- port->iobase = i;
- /*
- * Use all ones as membase to make sure uart_configure_port() in
- * serial_core.c does not abort for SPI/I2C devices where the
- * membase address is not applicable.
- */
- port->membase = (void __iomem *)~0;
- port->iotype = UPIO_PORT;
+ port->iotype = UPIO_BUS;
port->rs485_config = sc16is7xx_config_rs485;
port->rs485_supported = sc16is7xx_rs485_supported;
port->ops = &sc16is7xx_ops;
--
2.47.3
^ permalink raw reply related
* [PATCH 8/9] serial: max310x: use new UPIO_BUS as iotype
From: Hugo Villeneuve @ 2026-04-23 20:15 UTC (permalink / raw)
To: Greg Kroah-Hartman, Jiri Slaby
Cc: hugo, ilpo.jarvinen, linux-kernel, linux-serial, Hugo Villeneuve
In-Reply-To: <20260423-tty-upio-v1-0-baf82d3b86d1@dimonoff.com>
From: Hugo Villeneuve <hvilleneuve@dimonoff.com>
Now that we have a new UPIO_BUS I/O type, use it to register our serial
port and remove obscure membase/iobase workaround.
Signed-off-by: Hugo Villeneuve <hvilleneuve@dimonoff.com>
---
drivers/tty/serial/max310x.c | 9 +--------
1 file changed, 1 insertion(+), 8 deletions(-)
diff --git a/drivers/tty/serial/max310x.c b/drivers/tty/serial/max310x.c
index ac7d3f197c3a5ce3531d5607f48e21a807314021..cd0496e307091dae1f53911abf86726f52d5770d 100644
--- a/drivers/tty/serial/max310x.c
+++ b/drivers/tty/serial/max310x.c
@@ -1380,14 +1380,7 @@ static int max310x_probe(struct device *dev, const struct max310x_devtype *devty
s->p[i].port.type = PORT_MAX310X;
s->p[i].port.fifosize = MAX310X_FIFO_SIZE;
s->p[i].port.flags = UPF_FIXED_TYPE | UPF_LOW_LATENCY;
- s->p[i].port.iotype = UPIO_PORT;
- s->p[i].port.iobase = i;
- /*
- * Use all ones as membase to make sure uart_configure_port() in
- * serial_core.c does not abort for SPI/I2C devices where the
- * membase address is not applicable.
- */
- s->p[i].port.membase = (void __iomem *)~0;
+ s->p[i].port.iotype = UPIO_BUS;
s->p[i].port.uartclk = uartclk;
s->p[i].port.rs485_config = max310x_rs485_config;
s->p[i].port.rs485_supported = max310x_rs485_supported;
--
2.47.3
^ permalink raw reply related
* [PATCH 0/9] serial: add new I/O type for SPI and I2C bus devices
From: Hugo Villeneuve @ 2026-04-23 20:15 UTC (permalink / raw)
To: Greg Kroah-Hartman, Jiri Slaby
Cc: hugo, ilpo.jarvinen, linux-kernel, linux-serial, Hugo Villeneuve
Hello,
this patch series add a new I/O type for serial devices on a SPI/I2C bus.
These changes are based on a suggestion [1] made by Ilpo Järvinen during
past sc16is7xx driver patches review.
I decided to use UPIO_BUS/SERIAL_IO_BUS names but maybe other names would
be more appropriate:
UPIO_SBUS / SERIAL_IO_SBUS
UPIO_SERBUS / SERIAL_IO_SERBUS
UPIO_EXT / SERIAL_IO_EXT
UPIO_CUSTOM / SERIAL_IO_CUSTOM
UPIO_REGMAP / SERIAL_IO_REGMAP /* Maybe not always true in future? */
...
Tested on a imx6 board with two SC16is752 using SPI mode, and a dummy
device-tree entry for a MAX3100:
dmesg -t | grep "base_baud"
2020000.serial: ttymxc0 at MMIO 0x2020000 (irq = 197, base_baud = 5000000) is a IMX
21e8000.serial: ttymxc1 at MMIO 0x21e8000 (irq = 198, base_baud = 5000000) is a IMX
spi1.0: ttySC0 (irq = 165, base_baud = 1500000) is a SC16IS752
spi1.0: ttySC1 (irq = 165, base_baud = 1500000) is a SC16IS752
spi3.0: ttySC2 (irq = 37, base_baud = 1500000) is a SC16IS752
spi3.0: ttySC3 (irq = 37, base_baud = 1500000) is a SC16IS752
spi3.1: ttyMAX0 (irq = 0, base_baud = 0) is a MAX3100
Note that before these patches, max3100 silently failed in uart_configure_port()
because membase/iobase/mapbase were zero.
For max310x and SC16is7xx in i2c mode, tested only that driver is properly
registered by using i2c-stub.
Also tested on a custom board with a Renesas RZ/G2L cpu (sh-sci driver) to
confirm there is no regression:
dmesg -t | grep "base_baud"
1004b800.serial: ttySC0 at MMIO 0x1004b800 (irq = 35, base_baud = 0) is a scif
1004bc00.serial: ttySC1 at MMIO 0x1004bc00 (irq = 40, base_baud = 0) is a scif
Maybe some of the patches could be merged together, but for now I decided
to keep them separate to help the review process.
Thank you.
[1] https://lore.kernel.org/lkml/2936e18f-44ea-faed-9fa0-2ddefe7c3194@linux.intel.com/raw
---
Hugo Villeneuve (9):
serial: core: add uart_iotype_mmio/legacy_io helper functions
serial: core: use uart_iotype_*() to simplify code
serial: 8250: use uart_iotype_*() to simplify code
serial: core: fix indentation/alignment
serial: core: add new I/O type for SPI and I2C bus devices
serial: core: prevent irrelevant I/O infos display for UPIO_BUS
serial: sc16is7xx: use new UPIO_BUS as iotype
serial: max310x: use new UPIO_BUS as iotype
serial: max3100: use new UPIO_BUS as iotype
drivers/tty/serial/8250/8250_port.c | 33 ++--------
drivers/tty/serial/max3100.c | 1 +
drivers/tty/serial/max310x.c | 9 +--
drivers/tty/serial/sc16is7xx.c | 9 +--
drivers/tty/serial/serial_core.c | 121 ++++++++++++++++++++----------------
include/linux/serial_core.h | 5 ++
include/uapi/linux/serial.h | 1 +
7 files changed, 83 insertions(+), 96 deletions(-)
---
base-commit: 2e68039281932e6dc37718a1ea7cbb8e2cda42e6
change-id: 20260423-tty-upio-c8b66a0a593e
Best regards,
--
Hugo Villeneuve <hvilleneuve@dimonoff.com>
^ permalink raw reply
* [PATCH 6/9] serial: core: prevent irrelevant I/O infos display for UPIO_BUS
From: Hugo Villeneuve @ 2026-04-23 20:15 UTC (permalink / raw)
To: Greg Kroah-Hartman, Jiri Slaby
Cc: hugo, ilpo.jarvinen, linux-kernel, linux-serial, Hugo Villeneuve
In-Reply-To: <20260423-tty-upio-v1-0-baf82d3b86d1@dimonoff.com>
From: Hugo Villeneuve <hvilleneuve@dimonoff.com>
It doesn't make sense to display irrelevant MMIO or legacy I/O information
for serial devices on I2C or SPI busses. Now that we have a separate I/O
type for these types of devices, prevent display of I/O information for
them. Using uart_iotype_*() functions to do so also addresses the now
invalid check for "iotype >= UPIO_MEM".
Signed-off-by: Hugo Villeneuve <hvilleneuve@dimonoff.com>
---
drivers/tty/serial/serial_core.c | 50 ++++++++++++++++++----------------------
1 file changed, 22 insertions(+), 28 deletions(-)
diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c
index 0bfdb69817e4259681fbc4658c9a68200aa2b65f..42559eda6fc134de77c3a7b850d565ebdc89e216 100644
--- a/drivers/tty/serial/serial_core.c
+++ b/drivers/tty/serial/serial_core.c
@@ -2011,13 +2011,18 @@ static void uart_line_info(struct seq_file *m, struct uart_state *state)
if (!uport)
return;
- mmio = uport->iotype >= UPIO_MEM;
- seq_printf(m, "%u: uart:%s %s%08llX irq:%u",
- uport->line, uart_type(uport),
- mmio ? "mmio:0x" : "port:",
- mmio ? (unsigned long long)uport->mapbase
- : (unsigned long long)uport->iobase,
- uport->irq);
+ seq_printf(m, "%u: uart:%s", uport->line, uart_type(uport));
+
+ mmio = uart_iotype_mmio(uport->iotype);
+
+ if (mmio || uart_iotype_legacy_io(uport->iotype)) {
+ seq_printf(m, " %s%08llX",
+ mmio ? "mmio:0x" : "port:",
+ mmio ? (unsigned long long)uport->mapbase
+ : (unsigned long long)uport->iobase);
+ }
+
+ seq_printf(m, "irq:%u", uport->irq);
if (uport->type == PORT_UNKNOWN) {
seq_putc(m, '\n');
@@ -2482,31 +2487,20 @@ EXPORT_SYMBOL(uart_resume_port);
static inline void
uart_report_port(struct uart_driver *drv, struct uart_port *port)
{
- char address[64];
+ char address[64] = "";
- switch (port->iotype) {
- case UPIO_PORT:
- snprintf(address, sizeof(address), "I/O 0x%lx", port->iobase);
- break;
- case UPIO_HUB6:
+ if (uart_iotype_mmio(port->iotype))
snprintf(address, sizeof(address),
- "I/O 0x%lx offset 0x%x", port->iobase, port->hub6);
- break;
- case UPIO_MEM:
- case UPIO_MEM16:
- case UPIO_MEM32:
- case UPIO_MEM32BE:
- case UPIO_AU:
- case UPIO_TSI:
- snprintf(address, sizeof(address),
- "MMIO 0x%llx", (unsigned long long)port->mapbase);
- break;
- default:
- strscpy(address, "*unknown*", sizeof(address));
- break;
+ " at MMIO 0x%llx", (unsigned long long)port->mapbase);
+ else if (uart_iotype_legacy_io(port->iotype)) {
+ if (port->iotype == UPIO_PORT)
+ snprintf(address, sizeof(address), " at I/O 0x%lx", port->iobase);
+ else if (port->iotype == UPIO_HUB6)
+ snprintf(address, sizeof(address),
+ " at I/O 0x%lx offset 0x%x", port->iobase, port->hub6);
}
- pr_info("%s%s%s at %s (irq = %u, base_baud = %u) is a %s\n",
+ pr_info("%s%s%s%s (irq = %u, base_baud = %u) is a %s\n",
port->dev ? dev_name(port->dev) : "",
port->dev ? ": " : "",
port->name,
--
2.47.3
^ permalink raw reply related
* [PATCH 3/9] serial: 8250: use uart_iotype_*() to simplify code
From: Hugo Villeneuve @ 2026-04-23 20:15 UTC (permalink / raw)
To: Greg Kroah-Hartman, Jiri Slaby
Cc: hugo, ilpo.jarvinen, linux-kernel, linux-serial, Hugo Villeneuve
In-Reply-To: <20260423-tty-upio-v1-0-baf82d3b86d1@dimonoff.com>
From: Hugo Villeneuve <hvilleneuve@dimonoff.com>
Make use of new functions uart_iotype_mmio() and uart_iotype_legacy_io()
to simplify and improve code readability.
Signed-off-by: Hugo Villeneuve <hvilleneuve@dimonoff.com>
---
drivers/tty/serial/8250/8250_port.c | 33 +++++----------------------------
1 file changed, 5 insertions(+), 28 deletions(-)
diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c
index af78cc02f38e719573becd0aea226f7790555a3e..48ff4cad028ff0b6a9c7167ea8d793b3cb0f32da 100644
--- a/drivers/tty/serial/8250/8250_port.c
+++ b/drivers/tty/serial/8250/8250_port.c
@@ -2863,13 +2863,7 @@ static int serial8250_request_std_resource(struct uart_8250_port *up)
unsigned int size = serial8250_port_size(up);
struct uart_port *port = &up->port;
- switch (port->iotype) {
- case UPIO_AU:
- case UPIO_TSI:
- case UPIO_MEM32:
- case UPIO_MEM32BE:
- case UPIO_MEM16:
- case UPIO_MEM:
+ if (uart_iotype_mmio(port->iotype)) {
if (!port->mapbase)
return -EINVAL;
@@ -2883,14 +2877,9 @@ static int serial8250_request_std_resource(struct uart_8250_port *up)
return -ENOMEM;
}
}
- return 0;
- case UPIO_HUB6:
- case UPIO_PORT:
+ } else if (uart_iotype_legacy_io(port->iotype)) {
if (!request_region(port->iobase, size, "serial"))
return -EBUSY;
- return 0;
- case UPIO_UNKNOWN:
- break;
}
return 0;
@@ -2901,15 +2890,9 @@ static void serial8250_release_std_resource(struct uart_8250_port *up)
unsigned int size = serial8250_port_size(up);
struct uart_port *port = &up->port;
- switch (port->iotype) {
- case UPIO_AU:
- case UPIO_TSI:
- case UPIO_MEM32:
- case UPIO_MEM32BE:
- case UPIO_MEM16:
- case UPIO_MEM:
+ if (uart_iotype_mmio(port->iotype)) {
if (!port->mapbase)
- break;
+ return;
if (port->flags & UPF_IOREMAP) {
iounmap(port->membase);
@@ -2917,14 +2900,8 @@ static void serial8250_release_std_resource(struct uart_8250_port *up)
}
release_mem_region(port->mapbase, size);
- break;
-
- case UPIO_HUB6:
- case UPIO_PORT:
+ } else if (uart_iotype_legacy_io(port->iotype)) {
release_region(port->iobase, size);
- break;
- case UPIO_UNKNOWN:
- break;
}
}
--
2.47.3
^ permalink raw reply related
* [PATCH 5/9] serial: core: add new I/O type for SPI and I2C bus devices
From: Hugo Villeneuve @ 2026-04-23 20:15 UTC (permalink / raw)
To: Greg Kroah-Hartman, Jiri Slaby
Cc: hugo, ilpo.jarvinen, linux-kernel, linux-serial, Hugo Villeneuve
In-Reply-To: <20260423-tty-upio-v1-0-baf82d3b86d1@dimonoff.com>
From: Hugo Villeneuve <hvilleneuve@dimonoff.com>
I2C/SPI serial drivers don't use the following struct uart_port variables:
port->membase
port->mapbase
port->iobase
However, they are forced to set membase to a non-zero value so that
uart_configure_port() will succeed because of the following check:
/* If there isn't a port here, don't do anything further. */
if (!port->iobase && !port->mapbase && !port->membase)
return;
Add a new I/O type for SPI and I2C bus devices to remove the need to
implement the kind of above-mentioned ambiguous workarounds to make them
work.
Signed-off-by: Hugo Villeneuve <hvilleneuve@dimonoff.com>
---
With this change, uart_match_port() will always return true for UPIO_BUS
types, and this function is not used by any of the SPI/I2C drivers.
---
drivers/tty/serial/serial_core.c | 11 ++++++-----
include/linux/serial_core.h | 1 +
include/uapi/linux/serial.h | 1 +
3 files changed, 8 insertions(+), 5 deletions(-)
diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c
index cb5da344305e397b42f47bdbc2c053fc487ed784..0bfdb69817e4259681fbc4658c9a68200aa2b65f 100644
--- a/drivers/tty/serial/serial_core.c
+++ b/drivers/tty/serial/serial_core.c
@@ -2527,11 +2527,10 @@ uart_configure_port(struct uart_driver *drv, struct uart_state *state,
{
unsigned int flags;
- /*
- * If there isn't a port here, don't do anything further.
- */
- if (!port->iobase && !port->mapbase && !port->membase)
- return;
+ /* If there isn't a port here, don't do anything further. */
+ if (uart_iotype_mmio(port->iotype) || uart_iotype_legacy_io(port->iotype))
+ if (!port->iobase && !port->mapbase && !port->membase)
+ return;
/*
* Now do the auto configuration stuff. Note that config_port
@@ -3230,6 +3229,8 @@ bool uart_match_port(const struct uart_port *port1,
return false;
else
return true;
+ else if (port1->iotype == UPIO_BUS)
+ return true;
else
return false;
}
diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h
index fc3f5ebe389658c197ffc105ce4ac11cacef59bb..626dd939c53c9f920d71aadd360ec0ea0bacce0d 100644
--- a/include/linux/serial_core.h
+++ b/include/linux/serial_core.h
@@ -437,6 +437,7 @@ enum uart_iotype {
UPIO_TSI = SERIAL_IO_TSI, /* Tsi108/109 type IO */
UPIO_MEM32BE = SERIAL_IO_MEM32BE, /* 32b big endian */
UPIO_MEM16 = SERIAL_IO_MEM16, /* 16b little endian */
+ UPIO_BUS = SERIAL_IO_BUS, /* Serial bus I/O access (ex: SPI, I2C) */
};
struct uart_port {
diff --git a/include/uapi/linux/serial.h b/include/uapi/linux/serial.h
index de9b4733607e6b61b08ff7089ff90070168ff4a2..e6f61538fc2837a264d27942afaaf3f12e743445 100644
--- a/include/uapi/linux/serial.h
+++ b/include/uapi/linux/serial.h
@@ -72,6 +72,7 @@ struct serial_struct {
#define SERIAL_IO_TSI 5
#define SERIAL_IO_MEM32BE 6
#define SERIAL_IO_MEM16 7
+#define SERIAL_IO_BUS 8
#define UART_CLEAR_FIFO 0x01
#define UART_USE_FIFO 0x02
--
2.47.3
^ permalink raw reply related
* [PATCH 2/9] serial: core: use uart_iotype_*() to simplify code
From: Hugo Villeneuve @ 2026-04-23 20:15 UTC (permalink / raw)
To: Greg Kroah-Hartman, Jiri Slaby
Cc: hugo, ilpo.jarvinen, linux-kernel, linux-serial, Hugo Villeneuve
In-Reply-To: <20260423-tty-upio-v1-0-baf82d3b86d1@dimonoff.com>
From: Hugo Villeneuve <hvilleneuve@dimonoff.com>
Make use of new functions uart_iotype_mmio() and uart_iotype_legacy_io()
to simplify and improve code readability.
Signed-off-by: Hugo Villeneuve <hvilleneuve@dimonoff.com>
---
drivers/tty/serial/serial_core.c | 24 +++++++++---------------
1 file changed, 9 insertions(+), 15 deletions(-)
diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c
index b1cf45a8fc854cd97e349ff077d83b42e3ef8b16..fc273f8f9e75de89dca1ac1aca3589567bcf8a18 100644
--- a/drivers/tty/serial/serial_core.c
+++ b/drivers/tty/serial/serial_core.c
@@ -3221,23 +3221,17 @@ bool uart_match_port(const struct uart_port *port1,
{
if (port1->iotype != port2->iotype)
return false;
-
- switch (port1->iotype) {
- case UPIO_PORT:
- return port1->iobase == port2->iobase;
- case UPIO_HUB6:
- return port1->iobase == port2->iobase &&
- port1->hub6 == port2->hub6;
- case UPIO_MEM:
- case UPIO_MEM16:
- case UPIO_MEM32:
- case UPIO_MEM32BE:
- case UPIO_AU:
- case UPIO_TSI:
+ else if (uart_iotype_mmio(port1->iotype))
return port1->mapbase == port2->mapbase;
- default:
+ else if (uart_iotype_legacy_io(port1->iotype))
+ if (port1->iobase != port2->iobase)
+ return false;
+ else if (port1->iotype == UPIO_HUB6 && port1->hub6 != port2->hub6)
+ return false;
+ else
+ return true;
+ else
return false;
- }
}
EXPORT_SYMBOL(uart_match_port);
--
2.47.3
^ permalink raw reply related
* [PATCH 1/9] serial: core: add uart_iotype_mmio/legacy_io helper functions
From: Hugo Villeneuve @ 2026-04-23 20:15 UTC (permalink / raw)
To: Greg Kroah-Hartman, Jiri Slaby
Cc: hugo, ilpo.jarvinen, linux-kernel, linux-serial, Hugo Villeneuve
In-Reply-To: <20260423-tty-upio-v1-0-baf82d3b86d1@dimonoff.com>
From: Hugo Villeneuve <hvilleneuve@dimonoff.com>
To help simplify code that check on the io type mode of the port.
Signed-off-by: Hugo Villeneuve <hvilleneuve@dimonoff.com>
---
Will also be used by future commit that add UPIO_BUS.
---
drivers/tty/serial/serial_core.c | 28 ++++++++++++++++++++++++++++
include/linux/serial_core.h | 4 ++++
2 files changed, 32 insertions(+)
diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c
index 89cebdd278410a5a97f3f5ee1b9c171715145067..b1cf45a8fc854cd97e349ff077d83b42e3ef8b16 100644
--- a/drivers/tty/serial/serial_core.c
+++ b/drivers/tty/serial/serial_core.c
@@ -1966,6 +1966,34 @@ static const char *uart_type(struct uart_port *port)
return str;
}
+bool uart_iotype_mmio(enum uart_iotype iotype)
+{
+ switch (iotype) {
+ case UPIO_MEM:
+ case UPIO_MEM32:
+ case UPIO_AU:
+ case UPIO_TSI:
+ case UPIO_MEM32BE:
+ case UPIO_MEM16:
+ return true;
+ default:
+ return false;
+ }
+}
+EXPORT_SYMBOL_GPL(uart_iotype_mmio);
+
+bool uart_iotype_legacy_io(enum uart_iotype iotype)
+{
+ switch (iotype) {
+ case UPIO_PORT:
+ case UPIO_HUB6:
+ return true;
+ default:
+ return false;
+ }
+}
+EXPORT_SYMBOL_GPL(uart_iotype_legacy_io);
+
#ifdef CONFIG_PROC_FS
static void uart_line_info(struct seq_file *m, struct uart_state *state)
diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h
index 666430b4789977ae19641442b369eb1c773233f4..fc3f5ebe389658c197ffc105ce4ac11cacef59bb 100644
--- a/include/linux/serial_core.h
+++ b/include/linux/serial_core.h
@@ -1306,4 +1306,8 @@ static inline int uart_handle_break(struct uart_port *port)
!((cflag) & CLOCAL))
int uart_get_rs485_mode(struct uart_port *port);
+
+bool uart_iotype_mmio(enum uart_iotype iotype);
+bool uart_iotype_legacy_io(enum uart_iotype iotype);
+
#endif /* LINUX_SERIAL_CORE_H */
--
2.47.3
^ permalink raw reply related
* [PATCH 4/9] serial: core: fix indentation/alignment
From: Hugo Villeneuve @ 2026-04-23 20:15 UTC (permalink / raw)
To: Greg Kroah-Hartman, Jiri Slaby
Cc: hugo, ilpo.jarvinen, linux-kernel, linux-serial, Hugo Villeneuve
In-Reply-To: <20260423-tty-upio-v1-0-baf82d3b86d1@dimonoff.com>
From: Hugo Villeneuve <hvilleneuve@dimonoff.com>
Fixes the following checkpatch warnings:
CHECK: Alignment should match open parenthesis
Signed-off-by: Hugo Villeneuve <hvilleneuve@dimonoff.com>
---
Without this, the next patch will have a checkpatch warning.
---
drivers/tty/serial/serial_core.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c
index fc273f8f9e75de89dca1ac1aca3589567bcf8a18..cb5da344305e397b42f47bdbc2c053fc487ed784 100644
--- a/drivers/tty/serial/serial_core.c
+++ b/drivers/tty/serial/serial_core.c
@@ -2507,10 +2507,10 @@ uart_report_port(struct uart_driver *drv, struct uart_port *port)
}
pr_info("%s%s%s at %s (irq = %u, base_baud = %u) is a %s\n",
- port->dev ? dev_name(port->dev) : "",
- port->dev ? ": " : "",
- port->name,
- address, port->irq, port->uartclk / 16, uart_type(port));
+ port->dev ? dev_name(port->dev) : "",
+ port->dev ? ": " : "",
+ port->name,
+ address, port->irq, port->uartclk / 16, uart_type(port));
/* The magic multiplier feature is a bit obscure, so report it too. */
if (port->flags & UPF_MAGIC_MULTIPLIER)
--
2.47.3
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox