* [PATCH 0/3] tty: serial: Add Cortina-Access UART driver and platform support
@ 2026-06-10 11:28 Jason Li
2026-06-10 11:28 ` Jason Li
` (3 more replies)
0 siblings, 4 replies; 12+ messages in thread
From: Jason Li @ 2026-06-10 11:28 UTC (permalink / raw)
To: jason.li, Greg Kroah-Hartman, Jiri Slaby
Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Catalin Marinas,
Will Deacon, Arnd Bergmann, linux-serial, linux-arm-kernel,
devicetree, linux-kernel
Patch 1 adds the DT binding schema for the UART controller and the
top-level ARM board binding document for the Cortina-Access SoC family,
along with the vendor prefix.
Patch 2 introduces the serial driver (serial_cortina-access.c). The
UART IP has a simple FIFO-based design with a single interrupt line.
The driver uses uart_port_tx() for TX, handles earlycon initialisation
when the bootloader leaves the UART disabled, and provides a TX FIFO
kick-start in start_tx() to work around edge-triggered interrupt
behaviour. Clock frequency is obtained exclusively via the clk
framework.
Patch 3 adds the device tree sources for the CA8289 SoC and its
engineering board, covering the minimal hardware description needed to
boot a kernel with an INITRD rootfs.
Tested on CA8289 engineering board; console and earlycon both verified
at 115200 baud.
Any feedback or comments are highly appreciated.
Jason Li (3):
dt-bindings: serial: Add binding for Cortina-Access UART
tty: serial: Add UART driver for Cortina-Access platform
arm64: dts: cortina-access: Add DTS for CA8289 SoC and Venus board
.../bindings/arm/cortina-access.yaml | 29 +
.../serial/cortina-access,serial.yaml | 46 ++
.../devicetree/bindings/vendor-prefixes.yaml | 2 +
MAINTAINERS | 14 +
arch/arm64/Kconfig.platforms | 10 +
arch/arm64/boot/dts/Makefile | 1 +
arch/arm64/boot/dts/cortina-access/Makefile | 2 +
.../dts/cortina-access/ca8289-engboard.dts | 31 +
.../boot/dts/cortina-access/ca8289-soc.dtsi | 118 +++
drivers/tty/serial/Kconfig | 21 +
drivers/tty/serial/Makefile | 1 +
drivers/tty/serial/serial_cortina-access.c | 755 ++++++++++++++++++
12 files changed, 1030 insertions(+)
create mode 100644 Documentation/devicetree/bindings/arm/cortina-access.yaml
create mode 100644 Documentation/devicetree/bindings/serial/cortina-access,serial.yaml
create mode 100644 arch/arm64/boot/dts/cortina-access/Makefile
create mode 100644 arch/arm64/boot/dts/cortina-access/ca8289-engboard.dts
create mode 100644 arch/arm64/boot/dts/cortina-access/ca8289-soc.dtsi
create mode 100644 drivers/tty/serial/serial_cortina-access.c
--
2.39.5
^ permalink raw reply [flat|nested] 12+ messages in thread* [PATCH 0/3] tty: serial: Add Cortina-Access UART driver and platform support 2026-06-10 11:28 [PATCH 0/3] tty: serial: Add Cortina-Access UART driver and platform support Jason Li @ 2026-06-10 11:28 ` Jason Li 2026-06-10 12:50 ` Arnd Bergmann 2026-06-10 11:28 ` [PATCH 1/3] dt-bindings: serial: Add binding for Cortina-Access UART Jason Li ` (2 subsequent siblings) 3 siblings, 1 reply; 12+ messages in thread From: Jason Li @ 2026-06-10 11:28 UTC (permalink / raw) To: jason.li, Greg Kroah-Hartman, Jiri Slaby Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Catalin Marinas, Will Deacon, Arnd Bergmann, linux-serial, linux-arm-kernel, devicetree, linux-kernel This series adds Linux kernel support for the UART controller integrated in Cortina-Access SoCs, with CA8289 (Venus) as the first supported device. Patch 1 adds the DT binding schema for the UART controller and the top-level ARM board binding document for the Cortina-Access SoC family, along with the vendor prefix. Patch 2 introduces the serial driver (serial_cortina-access.c). The UART IP has a simple FIFO-based design with a single interrupt line. The driver uses uart_port_tx() for TX, handles earlycon initialisation when the bootloader leaves the UART disabled, and provides a TX FIFO kick-start in start_tx() to work around edge-triggered interrupt behaviour. Clock frequency is obtained exclusively via the clk framework. Patch 3 adds the device tree sources for the CA8289 SoC and its engineering board, covering the minimal hardware description needed to boot a kernel with an INITRD rootfs. Tested on CA8289 engineering board; console and earlycon both verified at 115200 baud. Jason Li (3): dt-bindings: serial: Add binding for Cortina-Access UART tty: serial: Add UART driver for Cortina-Access platform arm64: dts: cortina-access: Add DTS for CA8289 SoC and Venus board .../bindings/arm/cortina-access.yaml | 29 + .../serial/cortina-access,serial.yaml | 46 ++ .../devicetree/bindings/vendor-prefixes.yaml | 2 + MAINTAINERS | 14 + arch/arm64/Kconfig.platforms | 10 + arch/arm64/boot/dts/Makefile | 1 + arch/arm64/boot/dts/cortina-access/Makefile | 2 + .../dts/cortina-access/ca8289-engboard.dts | 31 + .../boot/dts/cortina-access/ca8289-soc.dtsi | 118 +++ drivers/tty/serial/Kconfig | 21 + drivers/tty/serial/Makefile | 1 + drivers/tty/serial/serial_cortina-access.c | 755 ++++++++++++++++++ 12 files changed, 1030 insertions(+) create mode 100644 Documentation/devicetree/bindings/arm/cortina-access.yaml create mode 100644 Documentation/devicetree/bindings/serial/cortina-access,serial.yaml create mode 100644 arch/arm64/boot/dts/cortina-access/Makefile create mode 100644 arch/arm64/boot/dts/cortina-access/ca8289-engboard.dts create mode 100644 arch/arm64/boot/dts/cortina-access/ca8289-soc.dtsi create mode 100644 drivers/tty/serial/serial_cortina-access.c -- 2.39.5 ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 0/3] tty: serial: Add Cortina-Access UART driver and platform support 2026-06-10 11:28 ` Jason Li @ 2026-06-10 12:50 ` Arnd Bergmann 0 siblings, 0 replies; 12+ messages in thread From: Arnd Bergmann @ 2026-06-10 12:50 UTC (permalink / raw) To: Jason Li, jason.li, Greg Kroah-Hartman, Jiri Slaby Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Catalin Marinas, Will Deacon, linux-serial, linux-arm-kernel, devicetree, linux-kernel On Wed, Jun 10, 2026, at 13:28, Jason Li wrote: > This series adds Linux kernel support for the UART controller integrated > in Cortina-Access SoCs, with CA8289 (Venus) as the first supported device. Hi Jason, Thanks a lot for your submission! I'm glad to see Cortina Access is getting back to upstreaming this support, I see that you first tries this in 2021 but didn't get very far at the time. The last submission was v4, so it would make sense to cound this one as v5 and continue with v6 next time. You have already received a number of comments, so I'll skip looking at the details for the moment and let you work through them. Regarding how to split up the patch series between uart and soc, I think sending them together during the review phase as you do here makes sense, but as they are loosely coupled, I think we will likely merge them separately. For simplicity, I would then just put the MAINTAINERS entry and the bindings for the vendor and board into the series for the soc tree. It would also help me if you could add some more context about the SoC into the patch description for the patch that adds the arm64 platform, in particular: - is this the only one you are planning to upstream at this point, or do you already have plans for other SoCs in this family? - do you expect to see full support for actual end-user products using these chips? - is there any shared lineage with the cortina-systems (storlink/storm, now marvell) gemini 32-bit chips that we already support, or with any of the Realtek SoCs that are also being upstreamed now? Arnd ^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH 1/3] dt-bindings: serial: Add binding for Cortina-Access UART 2026-06-10 11:28 [PATCH 0/3] tty: serial: Add Cortina-Access UART driver and platform support Jason Li 2026-06-10 11:28 ` Jason Li @ 2026-06-10 11:28 ` Jason Li 2026-06-10 11:36 ` sashiko-bot ` (2 more replies) 2026-06-10 11:28 ` [PATCH 2/3] tty: serial: Add UART driver for Cortina-Access platform Jason Li 2026-06-10 11:28 ` [PATCH 3/3] arm64: dts: cortina-access: Add DTS for CA8289 SoC and Venus board Jason Li 3 siblings, 3 replies; 12+ messages in thread From: Jason Li @ 2026-06-10 11:28 UTC (permalink / raw) To: jason.li, Greg Kroah-Hartman, Jiri Slaby Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Catalin Marinas, Will Deacon, Arnd Bergmann, linux-serial, linux-arm-kernel, devicetree, linux-kernel Add DT binding schema for the Cortina-Access UART controller. This IP is integrated into most CAXXXX SoC family members. Also add the vendor prefix for Cortina Access, Inc. and the top-level ARM board binding document for the CA8289 (Venus) SoC. Signed-off-by: Jason Li <jason.li@cortina-access.com> Assisted-by: Claude:claude-opus-4-8 --- .../bindings/arm/cortina-access.yaml | 29 ++++++++++++ .../serial/cortina-access,serial.yaml | 46 +++++++++++++++++++ .../devicetree/bindings/vendor-prefixes.yaml | 2 + MAINTAINERS | 7 +++ 4 files changed, 84 insertions(+) create mode 100644 Documentation/devicetree/bindings/arm/cortina-access.yaml create mode 100644 Documentation/devicetree/bindings/serial/cortina-access,serial.yaml diff --git a/Documentation/devicetree/bindings/arm/cortina-access.yaml b/Documentation/devicetree/bindings/arm/cortina-access.yaml new file mode 100644 index 000000000000..ec0320ed0c0b --- /dev/null +++ b/Documentation/devicetree/bindings/arm/cortina-access.yaml @@ -0,0 +1,29 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/arm/cortina-access.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Cortina-Access SoC boards + +maintainers: + - Jason Li <jason.li@cortina-access.com> + +description: + Boards based on Cortina-Access ARMv8 SoCs targeting networking and + access applications. + +properties: + $nodename: + const: / + compatible: + oneOf: + - description: Cortina-Access CA8289 (Venus) engineering board + const: cortina-access,ca8289-engboard + + - description: Cortina-Access CA8289 (Venus) reference board + const: cortina-access,ca8289-refboard + +additionalProperties: true + +... diff --git a/Documentation/devicetree/bindings/serial/cortina-access,serial.yaml b/Documentation/devicetree/bindings/serial/cortina-access,serial.yaml new file mode 100644 index 000000000000..5d7fdd954491 --- /dev/null +++ b/Documentation/devicetree/bindings/serial/cortina-access,serial.yaml @@ -0,0 +1,46 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/serial/cortina-access,serial.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Cortina-Access UART controller + +maintainers: + - Jason Li <jason.li@cortina-access.com> + +allOf: + - $ref: serial.yaml# + +properties: + compatible: + const: cortina-access,serial + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + clocks: + maxItems: 1 + +required: + - compatible + - reg + - interrupts + - clocks + +unevaluatedProperties: false + +examples: + - | + #include <dt-bindings/interrupt-controller/irq.h> + #include <dt-bindings/interrupt-controller/arm-gic.h> + + serial@f4329188 { + compatible = "cortina-access,serial"; + reg = <0 0xf4329188 0 0x30>; + interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&apb_pclk>; + }; diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml index dd94c50e97f9..837e2a92e7e8 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.yaml +++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml @@ -367,6 +367,8 @@ patternProperties: description: Chengdu Corpro Technology Co., Ltd. "^corechips,.*": description: Shenzhen Corechips Microelectronics Co., Ltd. + "^cortina-access,.*": + description: Cortina Access, Inc. "^cortina,.*": description: Cortina Systems, Inc. "^cosmic,.*": diff --git a/MAINTAINERS b/MAINTAINERS index 20bd55913b2d..cc261888fae0 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2820,6 +2820,13 @@ F: tools/perf/tests/shell/lib/*coresight* F: tools/perf/util/cs-etm-decoder/* F: tools/perf/util/cs-etm.* +ARM/CORTINA-ACCESS VENUS ARM ARCHITECTURE +M: Jason Li <jason.li@cortina-access.com> +L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) +S: Maintained +F: Documentation/devicetree/bindings/arm/cortina-access.yaml +F: Documentation/devicetree/bindings/serial/cortina-access,serial.yaml + ARM/CORTINA SYSTEMS GEMINI ARM ARCHITECTURE M: Hans Ulli Kroll <ulli.kroll@googlemail.com> M: Linus Walleij <linusw@kernel.org> -- 2.39.5 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH 1/3] dt-bindings: serial: Add binding for Cortina-Access UART 2026-06-10 11:28 ` [PATCH 1/3] dt-bindings: serial: Add binding for Cortina-Access UART Jason Li @ 2026-06-10 11:36 ` sashiko-bot 2026-06-10 11:46 ` Krzysztof Kozlowski 2026-06-10 11:51 ` Krzysztof Kozlowski 2 siblings, 0 replies; 12+ messages in thread From: sashiko-bot @ 2026-06-10 11:36 UTC (permalink / raw) To: Jason Li; +Cc: robh, conor+dt, devicetree Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider: - [Medium] The board compatible strings restrict the array to a single string, forbidding the required generic SoC fallback. - [Low] The UART binding example defines a 4-cell `reg` property without specifying the parent bus `#address-cells` and `#size-cells`, which causes `dt_binding_check` to fail. - [Low] Alphabetical sorting violation in `vendor-prefixes.yaml` and `MAINTAINERS`, breaking devicetree tooling and sorting guidelines. - [Low] The UART binding uses a generic device class compatible string instead of a specific implementation string. -- commit 32a23126a643cf7b114be8e3c3826bc3ea97f447 Author: Jason Li <jason.lee651024@gmail.com> dt-bindings: serial: Add binding for Cortina-Access UART This commit adds a new device tree binding schema for the Cortina-Access UART controller, targeting the CAXXXX SoC family. It also introduces the vendor prefix for Cortina Access and a top-level ARM board binding for the CA8289 (Venus) SoC. > diff --git a/Documentation/devicetree/bindings/arm/cortina-access.yaml b/Documentation/devicetree/bindings/arm/cortina-access.yaml > new file mode 100644 > --- /dev/null > +++ b/Documentation/devicetree/bindings/arm/cortina-access.yaml [ ... ] > +properties: > + $nodename: > + const: / > + compatible: > + oneOf: > + - description: Cortina-Access CA8289 (Venus) engineering board > + const: cortina-access,ca8289-engboard [Severity: Medium] Will rigidly enforcing a single compatible string cause dtbs_check to fail on standard board device trees? Standard ARM platform device trees typically define the board compatible as an array containing the specific board followed by the generic SoC string. Should this use an items array to explicitly define and allow both the board string and the required SoC fallback string instead of const? > + > + - description: Cortina-Access CA8289 (Venus) reference board > + const: cortina-access,ca8289-refboard [ ... ] > diff --git a/Documentation/devicetree/bindings/serial/cortina-access,serial.yaml b/Documentation/devicetree/bindings/serial/cortina-access,serial.yaml > new file mode 100644 > --- /dev/null > +++ b/Documentation/devicetree/bindings/serial/cortina-access,serial.yaml [ ... ] > +properties: > + compatible: > + const: cortina-access,serial [Severity: Low] Is this compatible string too generic? The Devicetree specification generally advises against using generic device class names in compatible strings. Would it be better to name the compatible string after the first specific SoC implementation, such as cortina-access,ca8289-uart, and use that as the generic fallback? > + > + reg: > + maxItems: 1 [ ... ] > +examples: > + - | > + #include <dt-bindings/interrupt-controller/irq.h> > + #include <dt-bindings/interrupt-controller/arm-gic.h> > + > + serial@f4329188 { > + compatible = "cortina-access,serial"; > + reg = <0 0xf4329188 0 0x30>; [Severity: Low] Does this example fail dt_binding_check? The schema restricts the reg property to maxItems: 1. Because no parent bus node is defined, the dt-extract-example tool wraps this in a default root node with 1-cell address and size. This causes the 4-cell reg array here to be parsed as two distinct register regions, violating the maxItems constraint. > + interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>; > + clocks = <&apb_pclk>; > + }; > diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml > --- a/Documentation/devicetree/bindings/vendor-prefixes.yaml > +++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml > @@ -367,6 +367,8 @@ patternProperties: > description: Chengdu Corpro Technology Co., Ltd. > "^corechips,.*": > description: Shenzhen Corechips Microelectronics Co., Ltd. > + "^cortina-access,.*": > + description: Cortina Access, Inc. [Severity: Low] Could this insertion break schema validation due to alphabetical sorting? The vendor-prefixes.yaml file enforces strict ASCII alphabetical sorting. A comma (ASCII 44) is less than a hyphen (ASCII 45), so ^cortina,.* should precede ^cortina-access,.*. > "^cortina,.*": > description: Cortina Systems, Inc. > "^cosmic,.*": > diff --git a/MAINTAINERS b/MAINTAINERS > --- a/MAINTAINERS > +++ b/MAINTAINERS > @@ -2749,6 +2749,13 @@ F: tools/perf/tests/shell/lib/*coresight* > F: tools/perf/util/cs-etm-decoder/* > F: tools/perf/util/cs-etm.* > > +ARM/CORTINA-ACCESS VENUS ARM ARCHITECTURE > +M: Jason Li <jason.li@cortina-access.com> > +L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) > +S: Maintained > +F: Documentation/devicetree/bindings/arm/cortina-access.yaml > +F: Documentation/devicetree/bindings/serial/cortina-access,serial.yaml > + [Severity: Low] Does this entry violate the alphabetical sorting guidelines for the MAINTAINERS file? A space (ASCII 32) is less than a hyphen (ASCII 45), so ARM/CORTINA SYSTEMS should appear before ARM/CORTINA-ACCESS. > ARM/CORTINA SYSTEMS GEMINI ARM ARCHITECTURE > M: Hans Ulli Kroll <ulli.kroll@googlemail.com> > M: Linus Walleij <linusw@kernel.org> -- Sashiko AI review · https://sashiko.dev/#/patchset/20260610112821.3030099-1-jason.li@cortina-access.com?part=1 ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 1/3] dt-bindings: serial: Add binding for Cortina-Access UART 2026-06-10 11:28 ` [PATCH 1/3] dt-bindings: serial: Add binding for Cortina-Access UART Jason Li 2026-06-10 11:36 ` sashiko-bot @ 2026-06-10 11:46 ` Krzysztof Kozlowski 2026-06-10 11:51 ` Krzysztof Kozlowski 2 siblings, 0 replies; 12+ messages in thread From: Krzysztof Kozlowski @ 2026-06-10 11:46 UTC (permalink / raw) To: Jason Li, jason.li, Greg Kroah-Hartman, Jiri Slaby Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Catalin Marinas, Will Deacon, Arnd Bergmann, linux-serial, linux-arm-kernel, devicetree, linux-kernel On 10/06/2026 13:28, Jason Li wrote: > Add DT binding schema for the Cortina-Access UART controller. > This IP is integrated into most CAXXXX SoC family members. > > Also add the vendor prefix for Cortina Access, Inc. and the > top-level ARM board binding document for the CA8289 (Venus) SoC. > > Signed-off-by: Jason Li <jason.li@cortina-access.com> > Assisted-by: Claude:claude-opus-4-8 > --- > .../bindings/arm/cortina-access.yaml | 29 ++++++++++++ > .../serial/cortina-access,serial.yaml | 46 +++++++++++++++++++ > .../devicetree/bindings/vendor-prefixes.yaml | 2 + > MAINTAINERS | 7 +++ This is somehow complete mess. serial and arm together? Please carefully read submitting patches (both documents!) and don't send AI-assisted slop. You must not combine independent works together. > 4 files changed, 84 insertions(+) > create mode 100644 Documentation/devicetree/bindings/arm/cortina-access.yaml > create mode 100644 Documentation/devicetree/bindings/serial/cortina-access,serial.yaml > > diff --git a/Documentation/devicetree/bindings/arm/cortina-access.yaml b/Documentation/devicetree/bindings/arm/cortina-access.yaml > new file mode 100644 > index 000000000000..ec0320ed0c0b > --- /dev/null > +++ b/Documentation/devicetree/bindings/arm/cortina-access.yaml > @@ -0,0 +1,29 @@ > +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause > +%YAML 1.2 > +--- > +$id: http://devicetree.org/schemas/arm/cortina-access.yaml# > +$schema: http://devicetree.org/meta-schemas/core.yaml# > + > +title: Cortina-Access SoC boards > + > +maintainers: > + - Jason Li <jason.li@cortina-access.com> > + > +description: > + Boards based on Cortina-Access ARMv8 SoCs targeting networking and > + access applications. > + > +properties: > + $nodename: > + const: / > + compatible: > + oneOf: > + - description: Cortina-Access CA8289 (Venus) engineering board > + const: cortina-access,ca8289-engboard > + > + - description: Cortina-Access CA8289 (Venus) reference board > + const: cortina-access,ca8289-refboard Where is the SoC? This looks like very poor contribution. If you opened any existing recent board binding you would see it is done differently. Best regards, Krzysztof ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 1/3] dt-bindings: serial: Add binding for Cortina-Access UART 2026-06-10 11:28 ` [PATCH 1/3] dt-bindings: serial: Add binding for Cortina-Access UART Jason Li 2026-06-10 11:36 ` sashiko-bot 2026-06-10 11:46 ` Krzysztof Kozlowski @ 2026-06-10 11:51 ` Krzysztof Kozlowski 2 siblings, 0 replies; 12+ messages in thread From: Krzysztof Kozlowski @ 2026-06-10 11:51 UTC (permalink / raw) To: Jason Li, jason.li, Greg Kroah-Hartman, Jiri Slaby Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Catalin Marinas, Will Deacon, Arnd Bergmann, linux-serial, linux-arm-kernel, devicetree, linux-kernel On 10/06/2026 13:28, Jason Li wrote: > + > +allOf: > + - $ref: serial.yaml# > + > +properties: > + compatible: > + const: cortina-access,serial Aren't writing bindings very clear about that? Please, take your time to read through the docs, so we will not need to repeat basic guidance. It is documented there on purpose. Best regards, Krzysztof ^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH 2/3] tty: serial: Add UART driver for Cortina-Access platform 2026-06-10 11:28 [PATCH 0/3] tty: serial: Add Cortina-Access UART driver and platform support Jason Li 2026-06-10 11:28 ` Jason Li 2026-06-10 11:28 ` [PATCH 1/3] dt-bindings: serial: Add binding for Cortina-Access UART Jason Li @ 2026-06-10 11:28 ` Jason Li 2026-06-10 11:40 ` sashiko-bot 2026-06-10 11:28 ` [PATCH 3/3] arm64: dts: cortina-access: Add DTS for CA8289 SoC and Venus board Jason Li 3 siblings, 1 reply; 12+ messages in thread From: Jason Li @ 2026-06-10 11:28 UTC (permalink / raw) To: jason.li, Greg Kroah-Hartman, Jiri Slaby Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Catalin Marinas, Will Deacon, Arnd Bergmann, linux-serial, linux-arm-kernel, devicetree, linux-kernel This driver supports Cortina Access UART IP integrated in most CAXXXX line of SoCs. Earlycon is also supported. Signed-off-by: Jason Li <jason.li@cortina-access.com> Assisted-by: Claude:claude-opus-4-8 --- MAINTAINERS | 6 + drivers/tty/serial/Kconfig | 21 + drivers/tty/serial/Makefile | 1 + drivers/tty/serial/serial_cortina-access.c | 755 +++++++++++++++++++++ 4 files changed, 783 insertions(+) create mode 100644 drivers/tty/serial/serial_cortina-access.c diff --git a/MAINTAINERS b/MAINTAINERS index cc261888fae0..515d89d96472 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -6687,6 +6687,12 @@ S: Maintained F: Documentation/hwmon/corsair-psu.rst F: drivers/hwmon/corsair-psu.c +CORTINA-ACCESS SERIAL CONSOLE DRIVER +M: Jason Li <jason.li@cortina-access.com> +L: linux-serial@vger.kernel.org +S: Supported +F: drivers/tty/serial/serial_cortina-access.c + COUNTER SUBSYSTEM M: William Breathitt Gray <wbg@kernel.org> L: linux-iio@vger.kernel.org diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig index cf7dba473b20..99a1c9308395 100644 --- a/drivers/tty/serial/Kconfig +++ b/drivers/tty/serial/Kconfig @@ -1592,6 +1592,27 @@ config SERIAL_NUVOTON_MA35D1_CONSOLE but you can alter that using a kernel command line option such as "console=ttyNVTx". +config SERIAL_CORTINA_ACCESS + tristate "Cortina-Access serial port support" + depends on OF + select SERIAL_CORE + help + This driver is for the Cortina-Access SoC UART, present in the + CA8289 (Venus) and related CAXXXX family of SoCs. If you have a + machine based on the Cortina-Access SoC and wish to use the serial + port, say 'Y' here. Otherwise, say 'N'. + +config SERIAL_CORTINA_ACCESS_CONSOLE + bool "Console on Cortina-Access serial port" + depends on SERIAL_CORTINA_ACCESS=y + select SERIAL_CORE_CONSOLE + select SERIAL_EARLYCON + help + Say 'Y' here if you wish to use the Cortina-Access UART as the system + console (the device which receives all kernel messages and warnings + and which allows logins in single user mode). + /dev/ttyS* is the default device node. + endmenu config SERIAL_MCTRL_GPIO diff --git a/drivers/tty/serial/Makefile b/drivers/tty/serial/Makefile index bba7b21a4a1d..54866c419714 100644 --- a/drivers/tty/serial/Makefile +++ b/drivers/tty/serial/Makefile @@ -98,3 +98,4 @@ obj-$(CONFIG_SERIAL_MCTRL_GPIO) += serial_mctrl_gpio.o obj-$(CONFIG_KGDB_SERIAL_CONSOLE) += kgdboc.o obj-$(CONFIG_SERIAL_NUVOTON_MA35D1) += ma35d1_serial.o +obj-$(CONFIG_SERIAL_CORTINA_ACCESS) += serial_cortina-access.o diff --git a/drivers/tty/serial/serial_cortina-access.c b/drivers/tty/serial/serial_cortina-access.c new file mode 100644 index 000000000000..f25eae987ccd --- /dev/null +++ b/drivers/tty/serial/serial_cortina-access.c @@ -0,0 +1,755 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * UART driver for Cortina-Access SoC platform + * Copyright (C) 2026 Cortina-Access Inc. + */ +#include <linux/clk.h> +#include <linux/console.h> +#include <linux/delay.h> +#include <linux/io.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/platform_device.h> +#include <linux/serial.h> +#include <linux/serial_core.h> +#include <linux/sysrq.h> +#include <linux/tty.h> +#include <linux/tty_flip.h> + +/*************************************** + * UART Related registers + ****************************************/ +/* register definitions */ +#define CFG 0x00 +#define FC 0x04 +#define RX_SAMPLE 0x08 +#define RT_TUNE 0x0C +#define TX_DAT 0x10 +#define RX_DAT 0x14 +#define INFO 0x18 +#define IE 0x1C +#define INT 0x24 +#define STATUS 0x2C + +/* CFG */ +#define CFG_STOP_2BIT BIT(2) +#define CFG_PARITY_EVEN BIT(3) +#define CFG_PARITY_EN BIT(4) +#define CFG_TX_EN BIT(5) +#define CFG_RX_EN BIT(6) +#define CFG_UART_EN BIT(7) +#define CFG_BAUD_SART_SHIFT 8 + +/* INFO */ +#define INFO_TX_EMPTY BIT(3) +#define INFO_TX_FULL BIT(2) +#define INFO_RX_EMPTY BIT(1) +#define INFO_RX_FULL BIT(0) + +/* Interrupt */ +#define RX_BREAK BIT(7) +#define RX_FIFO_NONEMPTYE BIT(6) +#define TX_FIFO_EMPTYE BIT(5) +#define RX_FIFO_UNDERRUNE BIT(4) +#define RX_FIFO_OVERRUNE BIT(3) +#define RX_PARITY_ERRE BIT(2) +#define RX_STOP_ERRE BIT(1) +#define TX_FIFO_OVERRUNE BIT(0) + +#define TX_TIMEOUT 5000 +#define UART_NR 4 +#define CA_UART_NAME_LEN 32 + +struct cortina_uart_port { + struct uart_port uart; + char name[CA_UART_NAME_LEN]; + char has_bi; + unsigned int may_wakeup; +}; + +static struct cortina_uart_port *cortina_uart_ports; + +static irqreturn_t cortina_uart_interrupt(int irq, void *dev_id); +static inline void cortina_uart_interrupt_tx_chars(struct uart_port *port); + +/* Return uart_port pointer based on index */ +static struct cortina_uart_port *cortina_uart_get_port(unsigned int index) +{ + struct cortina_uart_port *pca_port = cortina_uart_ports; + + if (index >= UART_NR) + index = 0; + + pca_port += index; + + return pca_port; +} + +/* uart_ops functions */ +static unsigned int cortina_uart_tx_empty(struct uart_port *port) +{ + /* Return 0 on FIFO full condition, TIOCSER_TEMT otherwise */ + return (readl(port->membase + INFO) & INFO_TX_EMPTY) ? TIOCSER_TEMT : 0; +} + +static void cortina_uart_set_mctrl(struct uart_port *port, unsigned int mctrl) +{ + /* + * Even if we do not support configuring the modem control lines, this + * function must be provided to the serial core. + * port->ops->set_mctrl() is called in uart_configure_port() + */ +} + +static unsigned int cortina_uart_get_mctrl(struct uart_port *port) +{ + /* Unimplemented signals asserted, per Documentation/serial/driver */ + return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR; +} + +static void cortina_uart_stop_tx(struct uart_port *port) +{ + /* Turn off Tx interrupts. The port lock is held at this point */ + unsigned int reg_v; + + reg_v = readl(port->membase + IE); + writel(reg_v & ~TX_FIFO_EMPTYE, port->membase + IE); +} + +static void cortina_uart_start_tx(struct uart_port *port) +{ + /* Turn on Tx interrupts. The port lock is held at this point */ + unsigned int reg_v; + + reg_v = readl(port->membase + IE); + writel(reg_v | TX_FIFO_EMPTYE, port->membase + IE); + + reg_v = readl(port->membase + CFG); + writel(reg_v | CFG_TX_EN, port->membase + CFG); + + /* + * If TX FIFO is already empty the TX_FIFO_EMPTY interrupt may be + * edge-triggered and won't fire again. Kick-start the transmission + * explicitly so the first character is not lost. + */ + if (readl(port->membase + INFO) & INFO_TX_EMPTY) + cortina_uart_interrupt_tx_chars(port); +} + +static void cortina_uart_stop_rx(struct uart_port *port) +{ + /* Turn off Rx interrupts. The port lock is held at this point */ + unsigned int reg_v; + + reg_v = readl(port->membase + IE); + writel(reg_v & ~RX_FIFO_NONEMPTYE, port->membase + IE); +} + +static void cortina_uart_enable_ms(struct uart_port *port) +{ + /* Nope, you really can't hope to attach a modem to this */ +} + +static int cortina_uart_startup(struct uart_port *port) +{ + unsigned int reg_v; + int retval; + unsigned long flags; + + /* Disable interrupts */ + writel(0, port->membase + IE); + + retval = request_irq(port->irq, cortina_uart_interrupt, 0, + "cortina_uart", port); + if (retval) + return retval; + + spin_lock_irqsave(&port->lock, flags); + + reg_v = readl(port->membase + CFG); + reg_v |= (CFG_UART_EN | CFG_TX_EN | CFG_RX_EN | 0x3 /* 8-bits data */); + writel(reg_v, port->membase + CFG); + reg_v = readl(port->membase + IE); + writel(reg_v | RX_FIFO_NONEMPTYE | TX_FIFO_EMPTYE, port->membase + IE); + + spin_unlock_irqrestore(&port->lock, flags); + return 0; +} + +static void cortina_uart_shutdown(struct uart_port *port) +{ + cortina_uart_stop_tx(port); + cortina_uart_stop_rx(port); + free_irq(port->irq, port); +} + +static void cortina_uart_set_termios(struct uart_port *port, + struct ktermios *termios, + const struct ktermios *old) +{ + unsigned long flags; + int baud; + unsigned int reg_v, sample_freq = 0; + + baud = uart_get_baud_rate(port, termios, old, 0, 230400); + reg_v = readl(port->membase + CFG); + /* mask off the baud settings */ + reg_v &= 0xff; + reg_v |= (port->uartclk / baud) << CFG_BAUD_SART_SHIFT; + + /* Sampling rate should be half of baud count */ + sample_freq = (reg_v >> CFG_BAUD_SART_SHIFT) / 2; + + /* See include/uapi/asm-generic/termbits.h for CSIZE definition */ + /* mask off the data width */ + reg_v &= 0xfffffffc; + switch (termios->c_cflag & CSIZE) { + case CS5: + reg_v |= 0x0; + break; + case CS6: + reg_v |= 0x1; + break; + case CS7: + reg_v |= 0x2; + break; + case CS8: + default: + reg_v |= 0x3; + break; + } + + /* mask off Stop bits */ + reg_v &= ~(CFG_STOP_2BIT); + if (termios->c_cflag & CSTOPB) + reg_v |= CFG_STOP_2BIT; + + /* Parity */ + reg_v &= ~(CFG_PARITY_EN); + reg_v |= CFG_PARITY_EVEN; + if (termios->c_cflag & PARENB) { + reg_v |= CFG_PARITY_EN; + if (termios->c_cflag & PARODD) + reg_v &= ~(CFG_PARITY_EVEN); + } + + spin_lock_irqsave(&port->lock, flags); + writel(reg_v, port->membase + CFG); + writel(sample_freq, port->membase + RX_SAMPLE); + spin_unlock_irqrestore(&port->lock, flags); +} + +static const char *cortina_uart_type(struct uart_port *port) +{ + return container_of(port, struct cortina_uart_port, uart)->name; +} + +static void cortina_uart_config_port(struct uart_port *port, int flags) +{ + /* + * Driver core for serial ports forces a non-zero value for port type. + * Write an arbitrary value here to accommodate the serial core driver, + * as ID part of UAPI is redundant. + */ + port->type = 1; +} + +static int cortina_uart_verify_port(struct uart_port *port, + struct serial_struct *ser) +{ + if (ser->type != PORT_UNKNOWN && ser->type != 1) + return -EINVAL; + return 0; +} + +static void cortina_access_power(struct uart_port *port, unsigned int state, + unsigned int oldstate) +{ + unsigned int reg_v; + + reg_v = readl(port->membase + CFG); + switch (state) { + case UART_PM_STATE_ON: + reg_v |= CFG_UART_EN; + break; + case UART_PM_STATE_OFF: + reg_v &= ~CFG_UART_EN; + break; + default: + pr_err("cortina-access serial: Unknown PM state %d\n", state); + } + writel(reg_v, port->membase + CFG); +} + +#ifdef CONFIG_CONSOLE_POLL +static int cortina_poll_get_char(struct uart_port *port) +{ + if (readl(port->membase + INFO) & INFO_RX_EMPTY) + return NO_POLL_CHAR; + + return readl(port->membase + RX_DAT); +} + +static void cortina_poll_put_char(struct uart_port *port, unsigned char c) +{ + unsigned long time_out; + + time_out = jiffies + usecs_to_jiffies(TX_TIMEOUT); + + while (time_before(jiffies, time_out) && + (readl(port->membase + INFO) & INFO_TX_FULL)) + cpu_relax(); + + /* Give up if FIFO stuck! */ + if (readl(port->membase + INFO) & INFO_TX_FULL) + return; + + writel(c, port->membase + TX_DAT); +} +#endif /* CONFIG_CONSOLE_POLL */ + +static const struct uart_ops cortina_uart_ops = { + .tx_empty = cortina_uart_tx_empty, + .set_mctrl = cortina_uart_set_mctrl, + .get_mctrl = cortina_uart_get_mctrl, + .stop_tx = cortina_uart_stop_tx, + .start_tx = cortina_uart_start_tx, + .stop_rx = cortina_uart_stop_rx, + .enable_ms = cortina_uart_enable_ms, + .startup = cortina_uart_startup, + .shutdown = cortina_uart_shutdown, + .set_termios = cortina_uart_set_termios, + .type = cortina_uart_type, + .config_port = cortina_uart_config_port, + .verify_port = cortina_uart_verify_port, + .pm = cortina_access_power, +#ifdef CONFIG_CONSOLE_POLL + .poll_get_char = cortina_poll_get_char, + .poll_put_char = cortina_poll_put_char, +#endif +}; + +static inline void cortina_uart_interrupt_rx_chars(struct uart_port *port, + unsigned long status) +{ + struct tty_port *ttyport = &port->state->port; + unsigned int ch; + unsigned int rx, flg; + struct cortina_uart_port *pca_port; + + rx = readl(port->membase + INFO); + if (INFO_RX_EMPTY & rx) + return; + + if (status & RX_FIFO_OVERRUNE) + port->icount.overrun++; + + pca_port = cortina_uart_get_port(port->line); + + /* Read characters while FIFO is not empty */ + do { + flg = TTY_NORMAL; + port->icount.rx++; + ch = readl(port->membase + RX_DAT); + if (status & RX_PARITY_ERRE) { + port->icount.parity++; + flg = TTY_PARITY; + } + + if (pca_port->has_bi) { + if (status & RX_BREAK) { + port->icount.brk++; + if (uart_handle_break(port)) + goto ignore; + } + } else { + /* Treat stop err as BI */ + if (status & RX_STOP_ERRE) { + port->icount.brk++; + if (uart_handle_break(port)) + goto ignore; + } + } + if (!(ch & 0x100)) /* RX char is not valid */ + goto ignore; + + if (uart_handle_sysrq_char(port, (unsigned char)ch)) + goto ignore; + + tty_insert_flip_char(ttyport, ch, flg); +ignore: + rx = readl(port->membase + INFO); + } while (!(INFO_RX_EMPTY & rx)); + + spin_unlock(&port->lock); + tty_flip_buffer_push(ttyport); + spin_lock(&port->lock); +} + +static inline void cortina_uart_interrupt_tx_chars(struct uart_port *port) +{ + u8 ch; + + /* + * uart_port_tx() drains the kfifo xmit buffer, handles x_char, + * calls uart_write_wakeup() and stop_tx() when the buffer empties. + */ + uart_port_tx(port, ch, + !(readl(port->membase + INFO) & INFO_TX_FULL), + writel(ch, port->membase + TX_DAT)); +} + +static irqreturn_t cortina_uart_interrupt(int irq, void *dev_id) +{ + struct uart_port *port = (struct uart_port *)dev_id; + unsigned int irq_status; + + spin_lock(&port->lock); + + /* Clear interrupt */ + irq_status = readl(port->membase + INT); + writel(irq_status, port->membase + INT); + + /* Process any Rx chars first */ + cortina_uart_interrupt_rx_chars(port, irq_status); + /* Then use any Tx space */ + cortina_uart_interrupt_tx_chars(port); + + spin_unlock(&port->lock); + + return IRQ_HANDLED; +} + +#ifdef CONFIG_SERIAL_CORTINA_ACCESS_CONSOLE +static void cortina_console_write(struct console *co, const char *s, + unsigned int count) +{ + struct uart_port *port; + struct cortina_uart_port *pca_port; + unsigned int i, previous; + unsigned long flags; + int locked; + + pca_port = cortina_uart_get_port(co->index); + port = &pca_port->uart; + + local_irq_save(flags); + if (port->sysrq) { + locked = 0; + } else if (oops_in_progress) { + locked = spin_trylock(&port->lock); + } else { + spin_lock(&port->lock); + locked = 1; + } + + /* Save current state */ + previous = readl(port->membase + IE); + /* Disable Tx interrupts so this all goes out in one go */ + cortina_uart_stop_tx(port); + + /* Write all the chars */ + for (i = 0; i < count; i++) { + /* Wait for the TX buffer to be empty */ + while (!(readl(port->membase + INFO) & INFO_TX_EMPTY)) + cpu_relax(); + + writel(*s, port->membase + TX_DAT); + + /* CR/LF handling */ + if (*s++ == '\n') { + while (!(readl(port->membase + INFO) & INFO_TX_EMPTY)) + cpu_relax(); + writel('\r', port->membase + TX_DAT); + } + } + + writel(previous, port->membase + IE); /* Restore interrupt state */ + + if (locked) + spin_unlock(&port->lock); + local_irq_restore(flags); +} + +static int __init cortina_console_setup(struct console *co, char *options) +{ + struct uart_port *port; + struct cortina_uart_port *pca_port; + int baud = 115200; + int bits = 8; + int parity = 'n'; + int flow = 'n'; + + if (co->index < 0 || co->index >= UART_NR) + return -ENODEV; + + pca_port = cortina_uart_get_port(co->index); + port = &pca_port->uart; + + if (options) + uart_parse_options(options, &baud, &parity, &bits, &flow); + + return uart_set_options(port, co, baud, parity, bits, flow); +} + +static struct uart_driver cortina_uart_driver; + +static struct console cortina_console = { + .name = "ttyS", + .write = cortina_console_write, + .device = uart_console_device, + .setup = cortina_console_setup, + .flags = CON_PRINTBUFFER, + .index = -1, + .data = &cortina_uart_driver, +}; + +#define CORTINA_CONSOLE (&cortina_console) + +/* Support EARLYCON */ +static void cortina_putc(struct uart_port *port, unsigned char c) +{ + unsigned int tmout = TX_TIMEOUT; + + /* No jiffies at early boot stage; wait up to TX_TIMEOUT us */ + while (--tmout) { + if (!(readl(port->membase + INFO) & INFO_TX_FULL)) + break; + udelay(1); + } + + /* Give up if FIFO stuck */ + if (readl(port->membase + INFO) & INFO_TX_FULL) + return; + + writel(c, port->membase + TX_DAT); +} + +static void cortina_early_write(struct console *con, const char *s, + unsigned int n) +{ + struct earlycon_device *dev = con->data; + + uart_console_write(&dev->port, s, n, cortina_putc); +} + +static int __init cortina_early_console_setup(struct earlycon_device *device, + const char *opt) +{ + u32 reg_v; + + if (!device->port.membase) + return -ENODEV; + + device->con->write = cortina_early_write; + + /* + * If the bootloader did not enable the UART, initialise it here + * at 115200 baud so that early boot messages are not lost. + * The magic constant mirrors the reference BSP setting: + * CFG[31:8] = baud divisor for 115200, CFG[7] = UART_EN, + * CFG[6:5] = RX_EN|TX_EN, CFG[1:0] = 8-bit data. + */ + reg_v = readl(device->port.membase + CFG); + if (!(reg_v & CFG_UART_EN)) { + writel(0x00043de3, device->port.membase + CFG); + writel(0x00043d / 2, device->port.membase + RX_SAMPLE); + } + + return 0; +} + +EARLYCON_DECLARE(ca_serial, cortina_early_console_setup); +OF_EARLYCON_DECLARE(ca_serial, "cortina-access,serial", + cortina_early_console_setup); +#else +#define CORTINA_CONSOLE NULL +#endif /* CONFIG_SERIAL_CORTINA_ACCESS_CONSOLE */ + +static struct uart_driver cortina_uart_driver = { + .owner = THIS_MODULE, + .driver_name = "cortina-access_uart", + .dev_name = "ttyS", + .major = TTY_MAJOR, + .minor = 64, + .nr = UART_NR, + .cons = CORTINA_CONSOLE, +}; + +/* Match table for of_platform binding */ +static const struct of_device_id cortina_uart_of_match[] = { + { .compatible = "cortina-access,serial" }, + {} +}; +MODULE_DEVICE_TABLE(of, cortina_uart_of_match); + +static int serial_cortina_probe(struct platform_device *pdev) +{ + struct device_node *np = pdev->dev.of_node; + struct cortina_uart_port *port; + struct resource *res; + struct clk *pclk_info; + int uart_idx; + int irq; + int ret; + + if (!cortina_uart_ports) { + cortina_uart_ports = kcalloc(UART_NR, sizeof(*cortina_uart_ports), + GFP_KERNEL); + if (!cortina_uart_ports) + return -ENOMEM; + } + + port = cortina_uart_ports; + for (uart_idx = 0; uart_idx < UART_NR; ++uart_idx) { + /* Find first empty slot */ + if (strlen(port->name) == 0) + break; + port++; + } + + if (uart_idx >= UART_NR) + return -ENODEV; + + snprintf(port->name, sizeof(port->name), + "Cortina-Access UART%d", uart_idx); + + /* Retrieve HW base address and reserve the I/O region */ + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) + return -EINVAL; + + port->uart.mapbase = res->start; + port->uart.membase = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(port->uart.membase)) + return PTR_ERR(port->uart.membase); + + /* Retrieve IRQ */ + irq = platform_get_irq(pdev, 0); + if (irq < 0) + return irq; + + port->uart.irq = irq; + + pclk_info = devm_clk_get_enabled(&pdev->dev, NULL); + if (IS_ERR(pclk_info)) { + dev_err(&pdev->dev, "failed to get clock\n"); + return PTR_ERR(pclk_info); + } + + port->uart.uartclk = clk_get_rate(pclk_info); + port->uart.ops = &cortina_uart_ops; + port->uart.dev = &pdev->dev; + port->uart.line = uart_idx; + port->uart.iotype = UPIO_MEM32; + port->uart.type = 1; + port->uart.has_sysrq = IS_ENABLED(CONFIG_SERIAL_CORTINA_ACCESS_CONSOLE); + + if (of_property_read_bool(np, "wakeup-source")) + port->may_wakeup = true; + if (of_property_read_bool(np, "break-indicator")) + port->has_bi = true; + + if (port->may_wakeup) + device_init_wakeup(&pdev->dev, true); + + ret = uart_add_one_port(&cortina_uart_driver, &port->uart); + if (ret) + return ret; + + platform_set_drvdata(pdev, port); + + return 0; +} + +static void serial_cortina_remove(struct platform_device *pdev) +{ + struct cortina_uart_port *pca_port = platform_get_drvdata(pdev); + + if (pca_port) { + memset(pca_port->name, 0, CA_UART_NAME_LEN); + uart_remove_one_port(&cortina_uart_driver, &pca_port->uart); + } + + platform_set_drvdata(pdev, NULL); + + /* + * Free the port array when the last port is removed, i.e. when + * all slots are empty again. + */ + if (cortina_uart_ports) { + int i; + + for (i = 0; i < UART_NR; i++) { + if (strlen(cortina_uart_ports[i].name) != 0) + return; + } + kfree(cortina_uart_ports); + cortina_uart_ports = NULL; + } +} + +#ifdef CONFIG_PM +static int serial_cortina_suspend(struct platform_device *pdev, + pm_message_t state) +{ + struct cortina_uart_port *p = platform_get_drvdata(pdev); + + uart_suspend_port(&cortina_uart_driver, &p->uart); + + return 0; +} + +static int serial_cortina_resume(struct platform_device *pdev) +{ + struct cortina_uart_port *p = platform_get_drvdata(pdev); + + uart_resume_port(&cortina_uart_driver, &p->uart); + + return 0; +} +#else +#define serial_cortina_suspend NULL +#define serial_cortina_resume NULL +#endif + +static struct platform_driver serial_cortina_driver = { + .probe = serial_cortina_probe, + .remove = serial_cortina_remove, +#ifdef CONFIG_PM + .suspend = serial_cortina_suspend, + .resume = serial_cortina_resume, +#endif + .driver = { + .name = "cortina-access_serial", + .of_match_table = cortina_uart_of_match, + }, +}; + +static int __init cortina_uart_init(void) +{ + int ret; + + ret = uart_register_driver(&cortina_uart_driver); + if (ret) + return ret; + + ret = platform_driver_register(&serial_cortina_driver); + if (ret) + uart_unregister_driver(&cortina_uart_driver); + + return ret; +} + +static void __exit cortina_uart_exit(void) +{ + platform_driver_unregister(&serial_cortina_driver); + uart_unregister_driver(&cortina_uart_driver); +} + +module_init(cortina_uart_init); +module_exit(cortina_uart_exit); + +MODULE_AUTHOR("Cortina-Access Inc."); +MODULE_DESCRIPTION("Cortina-Access UART driver"); +MODULE_LICENSE("GPL"); -- 2.39.5 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH 2/3] tty: serial: Add UART driver for Cortina-Access platform 2026-06-10 11:28 ` [PATCH 2/3] tty: serial: Add UART driver for Cortina-Access platform Jason Li @ 2026-06-10 11:40 ` sashiko-bot 0 siblings, 0 replies; 12+ messages in thread From: sashiko-bot @ 2026-06-10 11:40 UTC (permalink / raw) To: Jason Li; +Cc: robh, devicetree, conor+dt Thank you for your contribution! Sashiko AI review found 10 potential issue(s) to consider: - [High] Global array allocation, port slot selection, and cleanup lack synchronization, leading to race conditions, memory leaks, and UAF. - [High] Kernel panic in `cortina_console_setup()` due to NULL pointer dereference when called for an unprobed UART index. - [High] `cortina_poll_put_char()` uses `jiffies` for timeout calculations, resulting in an infinite loop and system hang. - [High] Read-modify-write operations on the CFG register are performed without holding the port lock, leading to TOCTOU state corruption. - [High] The console write function disables hardware interrupts and then takes a sleeping spinlock, triggering a lockdep splat on PREEMPT_RT. - [Medium] The RX interrupt handler incorrectly applies a single, one-time error status to all characters drained from the FIFO. - [Medium] Failed probes permanently leak port slots from the global `cortina_uart_ports` array. - [Medium] The wakeup source initialized during probe is never disabled, causing a memory leak when the driver is unbound or fails to probe. - [Medium] The `cortina_uart_shutdown` callback performs read-modify-write operations on the Interrupt Enable (IE) register without holding the port lock. - [Low] The console write function transmits an incorrect LF-CR (`\n\r`) sequence instead of the standard CR-LF (`\r\n`). -- commit fd0d487faa14545601b1e17f9d5e8a68bcd53bfd Author: Jason Li <jason.lee651024@gmail.com> Subject: tty: serial: Add UART driver for Cortina-Access platform This commit introduces a new UART driver for the Cortina-Access SoC platform, adding support for the CAXXXX family along with earlycon and console functionality. > diff --git a/drivers/tty/serial/serial_cortina-access.c b/drivers/tty/serial/serial_cortina-access.c > new file mode 100644 > index 0000000000000..f25eae987ccdc > --- /dev/null > +++ b/drivers/tty/serial/serial_cortina-access.c [ ... ] > +static void cortina_uart_shutdown(struct uart_port *port) > +{ > + cortina_uart_stop_tx(port); > + cortina_uart_stop_rx(port); [Severity: Medium] Could this corrupt the IE register state? The serial core calls the shutdown callback without holding the port lock, but the stop_tx and stop_rx functions perform read-modify-write operations on the IE register. > + free_irq(port->irq, port); > +} [ ... ] > +static void cortina_uart_set_termios(struct uart_port *port, > + struct ktermios *termios, > + const struct ktermios *old) > +{ > + unsigned long flags; > + int baud; > + unsigned int reg_v, sample_freq = 0; > + > + baud = uart_get_baud_rate(port, termios, old, 0, 230400); > + reg_v = readl(port->membase + CFG); [Severity: High] Is the CFG register read vulnerable to TOCTOU corruption here? The CFG register is read into a local variable outside the port lock, but it is written inside the lock later. If another context acquires the lock and modifies CFG concurrently, it seems this could overwrite and lose those changes. > + /* mask off the baud settings */ > + reg_v &= 0xff; [ ... ] > +static void cortina_access_power(struct uart_port *port, unsigned int state, > + unsigned int oldstate) > +{ > + unsigned int reg_v; > + > + reg_v = readl(port->membase + CFG); [Severity: High] Does this need to hold the port lock? The CFG register is read and written here with no locking, which might race with other register accesses. > + switch (state) { > + case UART_PM_STATE_ON: > + reg_v |= CFG_UART_EN; > + break; [ ... ] > +#ifdef CONFIG_CONSOLE_POLL > +static int cortina_poll_get_char(struct uart_port *port) > +{ > + if (readl(port->membase + INFO) & INFO_RX_EMPTY) > + return NO_POLL_CHAR; > + > + return readl(port->membase + RX_DAT); > +} > + > +static void cortina_poll_put_char(struct uart_port *port, unsigned char c) > +{ > + unsigned long time_out; > + > + time_out = jiffies + usecs_to_jiffies(TX_TIMEOUT); > + > + while (time_before(jiffies, time_out) && > + (readl(port->membase + INFO) & INFO_TX_FULL)) > + cpu_relax(); [Severity: High] Will this loop hang the system? Since this polling function is called from the kgdb framework with local hardware interrupts disabled, jiffies will not increment. Should atomic polling loops use udelay and an iteration counter instead? > + > + /* Give up if FIFO stuck! */ > + if (readl(port->membase + INFO) & INFO_TX_FULL) > + return; [ ... ] > +static inline void cortina_uart_interrupt_rx_chars(struct uart_port *port, > + unsigned long status) > +{ [ ... ] > + /* Read characters while FIFO is not empty */ > + do { > + flg = TTY_NORMAL; > + port->icount.rx++; > + ch = readl(port->membase + RX_DAT); > + if (status & RX_PARITY_ERRE) { [Severity: Medium] Could this artificially inflate error statistics? The status argument is read once before the loop, but it is evaluated against every character drained from the FIFO. If an error bit was set initially, it looks like every subsequent valid character in the batch is flagged as an error. > + port->icount.parity++; > + flg = TTY_PARITY; > + } [ ... ] > +#ifdef CONFIG_SERIAL_CORTINA_ACCESS_CONSOLE > +static void cortina_console_write(struct console *co, const char *s, > + unsigned int count) > +{ > + struct uart_port *port; > + struct cortina_uart_port *pca_port; > + unsigned int i, previous; > + unsigned long flags; > + int locked; > + > + pca_port = cortina_uart_get_port(co->index); > + port = &pca_port->uart; > + > + local_irq_save(flags); > + if (port->sysrq) { > + locked = 0; > + } else if (oops_in_progress) { > + locked = spin_trylock(&port->lock); > + } else { > + spin_lock(&port->lock); [Severity: High] Will this cause a sleeping-while-atomic lockdep warning on PREEMPT_RT? Disabling hardware interrupts and then acquiring a sleeping lock (like spinlock_t on RT kernels) is not allowed. Should this use uart_port_lock_irqsave instead? > + locked = 1; > + } [ ... ] > + /* Write all the chars */ > + for (i = 0; i < count; i++) { > + /* Wait for the TX buffer to be empty */ > + while (!(readl(port->membase + INFO) & INFO_TX_EMPTY)) > + cpu_relax(); > + > + writel(*s, port->membase + TX_DAT); > + > + /* CR/LF handling */ > + if (*s++ == '\n') { [Severity: Low] Does this transmit an incorrect LF-CR sequence instead of the standard CR-LF? It writes the current character and then appends a carriage return if the character was a newline. Could this be simplified by using uart_console_write? > + while (!(readl(port->membase + INFO) & INFO_TX_EMPTY)) > + cpu_relax(); > + writel('\r', port->membase + TX_DAT); > + } > + } [ ... ] > +static int __init cortina_console_setup(struct console *co, char *options) > +{ > + struct uart_port *port; > + struct cortina_uart_port *pca_port; > + int baud = 115200; > + int bits = 8; > + int parity = 'n'; > + int flow = 'n'; > + > + if (co->index < 0 || co->index >= UART_NR) > + return -ENODEV; > + > + pca_port = cortina_uart_get_port(co->index); > + port = &pca_port->uart; > + > + if (options) > + uart_parse_options(options, &baud, &parity, &bits, &flow); > + > + return uart_set_options(port, co, baud, parity, bits, flow); [Severity: High] Can this cause a kernel panic if a console is requested on an unprobed port index (e.g. via the command line)? It looks like this fetches a potentially zero-initialized port from the global array and passes it to uart_set_options, which will unconditionally dereference the port operations. > +} [ ... ] > +static int serial_cortina_probe(struct platform_device *pdev) > +{ > + struct device_node *np = pdev->dev.of_node; > + struct cortina_uart_port *port; > + struct resource *res; > + struct clk *pclk_info; > + int uart_idx; > + int irq; > + int ret; > + > + if (!cortina_uart_ports) { > + cortina_uart_ports = kcalloc(UART_NR, sizeof(*cortina_uart_ports), > + GFP_KERNEL); [Severity: High] Is there a race condition with this global array allocation? The cortina_uart_ports array is allocated and searched without any locking. Could concurrent probing of multiple instances lead to a double allocation and memory leak? > + if (!cortina_uart_ports) > + return -ENOMEM; > + } > + > + port = cortina_uart_ports; > + for (uart_idx = 0; uart_idx < UART_NR; ++uart_idx) { > + /* Find first empty slot */ > + if (strlen(port->name) == 0) > + break; > + port++; > + } > + > + if (uart_idx >= UART_NR) > + return -ENODEV; > + > + snprintf(port->name, sizeof(port->name), > + "Cortina-Access UART%d", uart_idx); [Severity: Medium] If a subsequent initialization step fails in the probe function, does this permanently leak the port slot? The name is assigned to claim the slot, but it doesn't appear to be cleared on the error paths. [ ... ] > + if (of_property_read_bool(np, "wakeup-source")) > + port->may_wakeup = true; > + if (of_property_read_bool(np, "break-indicator")) > + port->has_bi = true; > + > + if (port->may_wakeup) > + device_init_wakeup(&pdev->dev, true); [Severity: Medium] Does this leak the wakeup source memory? device_init_wakeup is called to enable the wakeup source, but it is never disabled on the probe error path or in the removal callback. > + > + ret = uart_add_one_port(&cortina_uart_driver, &port->uart); [ ... ] > +static void serial_cortina_remove(struct platform_device *pdev) > +{ > + struct cortina_uart_port *pca_port = platform_get_drvdata(pdev); > + > + if (pca_port) { > + memset(pca_port->name, 0, CA_UART_NAME_LEN); > + uart_remove_one_port(&cortina_uart_driver, &pca_port->uart); [Severity: High] Does clearing the slot name before unregistering the port open a race condition? If the name is cleared early, a concurrent probe might hijack the slot and overwrite the port state during active teardown. > + } > + > + platform_set_drvdata(pdev, NULL); -- Sashiko AI review · https://sashiko.dev/#/patchset/20260610112821.3030099-1-jason.li@cortina-access.com?part=2 ^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH 3/3] arm64: dts: cortina-access: Add DTS for CA8289 SoC and Venus board 2026-06-10 11:28 [PATCH 0/3] tty: serial: Add Cortina-Access UART driver and platform support Jason Li ` (2 preceding siblings ...) 2026-06-10 11:28 ` [PATCH 2/3] tty: serial: Add UART driver for Cortina-Access platform Jason Li @ 2026-06-10 11:28 ` Jason Li 2026-06-10 11:37 ` sashiko-bot 2026-06-10 11:49 ` Krzysztof Kozlowski 3 siblings, 2 replies; 12+ messages in thread From: Jason Li @ 2026-06-10 11:28 UTC (permalink / raw) To: jason.li, Greg Kroah-Hartman, Jiri Slaby Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Catalin Marinas, Will Deacon, Arnd Bergmann, linux-serial, linux-arm-kernel, devicetree, linux-kernel Add SoC DTSI for the Cortina-Access CA8289 (Venus) and a board DTS for the Venus engineering board. The description covers the minimum set of hardware nodes needed to boot a kernel with an INITRD rootfs: CPUs, GIC, timer, PSCI, fixed clock and UART. Signed-off-by: Jason Li <jason.li@cortina-access.com> Assisted-by: Claude:claude-opus-4-8 --- MAINTAINERS | 1 + arch/arm64/Kconfig.platforms | 10 ++ arch/arm64/boot/dts/Makefile | 1 + arch/arm64/boot/dts/cortina-access/Makefile | 2 + .../dts/cortina-access/ca8289-engboard.dts | 31 +++++ .../boot/dts/cortina-access/ca8289-soc.dtsi | 118 ++++++++++++++++++ 6 files changed, 163 insertions(+) create mode 100644 arch/arm64/boot/dts/cortina-access/Makefile create mode 100644 arch/arm64/boot/dts/cortina-access/ca8289-engboard.dts create mode 100644 arch/arm64/boot/dts/cortina-access/ca8289-soc.dtsi diff --git a/MAINTAINERS b/MAINTAINERS index 515d89d96472..ebfdb9c267cc 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2826,6 +2826,7 @@ L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) S: Maintained F: Documentation/devicetree/bindings/arm/cortina-access.yaml F: Documentation/devicetree/bindings/serial/cortina-access,serial.yaml +F: arch/arm64/boot/dts/cortina-access/ ARM/CORTINA SYSTEMS GEMINI ARM ARCHITECTURE M: Hans Ulli Kroll <ulli.kroll@googlemail.com> diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms index dc995a732117..ba6dda0660c3 100644 --- a/arch/arm64/Kconfig.platforms +++ b/arch/arm64/Kconfig.platforms @@ -134,6 +134,16 @@ config ARCH_CIX This enables support for the Cixtech SoC family, like P1(sky1). +config ARCH_CORTINA_ACCESS + bool "Cortina-Access SoC Family" + select GPIOLIB + select PINCTRL + help + This enables support for Cortina-Access SoCs. The family + includes ARMv8-based devices targeting networking and access + applications. + If you have a Cortina-Access board, say Y here. + config ARCH_EXYNOS bool "Samsung Exynos SoC family" select COMMON_CLK_SAMSUNG diff --git a/arch/arm64/boot/dts/Makefile b/arch/arm64/boot/dts/Makefile index 98ec8f1b76e4..a599f525fb9a 100644 --- a/arch/arm64/boot/dts/Makefile +++ b/arch/arm64/boot/dts/Makefile @@ -16,6 +16,7 @@ subdir-y += broadcom subdir-y += bst subdir-y += cavium subdir-y += cix +subdir-y += cortina-access subdir-y += exynos subdir-y += freescale subdir-y += hisilicon diff --git a/arch/arm64/boot/dts/cortina-access/Makefile b/arch/arm64/boot/dts/cortina-access/Makefile new file mode 100644 index 000000000000..554893f381fe --- /dev/null +++ b/arch/arm64/boot/dts/cortina-access/Makefile @@ -0,0 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0 +dtb-$(CONFIG_ARCH_CORTINA_ACCESS) += ca8289-engboard.dtb diff --git a/arch/arm64/boot/dts/cortina-access/ca8289-engboard.dts b/arch/arm64/boot/dts/cortina-access/ca8289-engboard.dts new file mode 100644 index 000000000000..c8289a0f8269 --- /dev/null +++ b/arch/arm64/boot/dts/cortina-access/ca8289-engboard.dts @@ -0,0 +1,31 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * dts file for Cortina Access Venus Engineering Board + * + * Copyright (C) 2026, Cortina Access Inc. + * + */ + +/dts-v1/; + +#include "ca8289-soc.dtsi" + +/ { + model = "Cortina Access Venus Engineering Board"; + compatible = "cortina-access,ca8289-engboard"; + #address-cells = <2>; + #size-cells = <2>; + + aliases { + serial0 = &uart0; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + memory@0 { /* 512MB */ + device_type = "memory"; + reg = <0x00000000 0x00000000 0x0 0x20000000>; + }; +}; diff --git a/arch/arm64/boot/dts/cortina-access/ca8289-soc.dtsi b/arch/arm64/boot/dts/cortina-access/ca8289-soc.dtsi new file mode 100644 index 000000000000..8e7ffcf4ccab --- /dev/null +++ b/arch/arm64/boot/dts/cortina-access/ca8289-soc.dtsi @@ -0,0 +1,118 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * dts file for Cortina Access CA8289 SoC + * + * Copyright (C) 2026, Cortina Access Inc. + */ + +#include <dt-bindings/interrupt-controller/arm-gic.h> +#include <dt-bindings/interrupt-controller/irq.h> + +/ { + cpus { + #address-cells = <2>; + #size-cells = <0>; + + cpu0: cpu@0 { + compatible = "arm,cortex-a55", "arm,armv8"; + device_type = "cpu"; + reg = <0x0 0x0>; + enable-method = "psci"; + }; + cpu1: cpu@100 { + compatible = "arm,cortex-a55", "arm,armv8"; + device_type = "cpu"; + reg = <0x0 0x100>; + enable-method = "psci"; + }; + cpu2: cpu@200 { + compatible = "arm,cortex-a55", "arm,armv8"; + device_type = "cpu"; + reg = <0x0 0x200>; + enable-method = "psci"; + }; + cpu3: cpu@300 { + compatible = "arm,cortex-a55", "arm,armv8"; + device_type = "cpu"; + reg = <0x0 0x300>; + enable-method = "psci"; + }; + cpu-map { + cluster0 { + core0 { + cpu = <&cpu0>; + }; + core1 { + cpu = <&cpu1>; + }; + core2 { + cpu = <&cpu2>; + }; + core3 { + cpu = <&cpu3>; + }; + }; + }; + }; + + psci { + compatible = "arm,psci-0.2"; + method = "smc"; + }; + + gic: interrupt-controller@4f8000000 { + compatible = "arm,gic-v3"; + #interrupt-cells = <3>; + interrupt-controller; + #redistributor-regions = <1>; + reg = <0x00000004 0xF8000000 0 0x10000>, + <0x00000004 0xF8040000 0 0x80000>; + }; + + apb_pclk: apb-pclk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <125000000>; + }; + + reserved-memory { + #address-cells = <2>; + #size-cells = <2>; + ranges; + + /* TrustZone reserved region; must not be mapped by the kernel */ + tz_pool: tz-buffer@f000000 { + reg = <0x0 0x0F000000 0x0 0x1000000>; + no-map; + }; + }; + + /* See Documentation/devicetree/bindings/timer/arm,arch_timer.yaml */ + timer { + compatible = "arm,armv8-timer"; + interrupt-parent = <&gic>; + interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>, + <GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>, + <GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>, + <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>; + clock-frequency = <25000000>; + }; + + uart0: serial@f4329188 { + device_type = "serial"; + compatible = "cortina-access,serial"; + reg = <0x00000000 0xf4329188 0x0 0x30>; + clocks = <&apb_pclk>; + interrupt-parent = <&gic>; + interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>; + }; + + uart1: serial@f43291b8 { + device_type = "serial"; + compatible = "cortina-access,serial"; + reg = <0x00000000 0xf43291b8 0x0 0x30>; + clocks = <&apb_pclk>; + interrupt-parent = <&gic>; + interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>; + }; +}; -- 2.39.5 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH 3/3] arm64: dts: cortina-access: Add DTS for CA8289 SoC and Venus board 2026-06-10 11:28 ` [PATCH 3/3] arm64: dts: cortina-access: Add DTS for CA8289 SoC and Venus board Jason Li @ 2026-06-10 11:37 ` sashiko-bot 2026-06-10 11:49 ` Krzysztof Kozlowski 1 sibling, 0 replies; 12+ messages in thread From: sashiko-bot @ 2026-06-10 11:37 UTC (permalink / raw) To: Jason Li; +Cc: robh, conor+dt, devicetree Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider: - [Medium] Use of discouraged `clock-frequency` property in the ARMv8 timer node. - [Low] Missing root `#address-cells` and `#size-cells` in SoC DTSI. -- commit bb6d4b41e4c489bdce2ba3142178fa3654514276 Author: Jason Li <jason.lee651024@gmail.com> arm64: dts: cortina-access: Add DTS for CA8289 SoC and Venus board Add SoC DTSI for the Cortina-Access CA8289 (Venus) and a board DTS for the Venus engineering board. The description covers the minimum set of hardware nodes needed to boot a kernel with an INITRD rootfs. > diff --git a/arch/arm64/boot/dts/cortina-access/ca8289-soc.dtsi b/arch/arm64/boot/dts/cortina-access/ca8289-soc.dtsi > new file mode 100644 > index 0000000000000..8e7ffcf4ccab4 > --- /dev/null > +++ b/arch/arm64/boot/dts/cortina-access/ca8289-soc.dtsi > @@ -0,0 +1,118 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * dts file for Cortina Access CA8289 SoC > + * > + * Copyright (C) 2026, Cortina Access Inc. > + */ > + > +#include <dt-bindings/interrupt-controller/arm-gic.h> > +#include <dt-bindings/interrupt-controller/irq.h> > + > +/ { [Severity: Low] Should the root node of this DTSI include its own #address-cells and #size-cells declarations? While the top-level ca8289-engboard.dts provides these, defining several top-level nodes (like gic, uart0, uart1) that use 64-bit addresses relies on the board file to satisfy the DTSI's cell size requirements. Could these be added to the DTSI root node so it remains self-contained? > + cpus { > + #address-cells = <2>; > + #size-cells = <0>; [ ... ] > + /* See Documentation/devicetree/bindings/timer/arm,arch_timer.yaml */ > + timer { > + compatible = "arm,armv8-timer"; > + interrupt-parent = <&gic>; > + interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>, > + <GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>, > + <GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>, > + <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>; > + clock-frequency = <25000000>; [Severity: Medium] Is this clock-frequency property strictly necessary for this new SoC? For ARMv8 architectures, the system timer frequency should typically be programmed into the CNTFRQ_EL0 register by the boot firmware (e.g., TF-A) on all CPUs. The devicetree clock-frequency property is generally treated as a workaround for legacy firmware that cannot be modified. For new SoC ports, can the boot firmware be updated to properly initialize CNTFRQ_EL0 instead? > + }; -- Sashiko AI review · https://sashiko.dev/#/patchset/20260610112821.3030099-1-jason.li@cortina-access.com?part=3 ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 3/3] arm64: dts: cortina-access: Add DTS for CA8289 SoC and Venus board 2026-06-10 11:28 ` [PATCH 3/3] arm64: dts: cortina-access: Add DTS for CA8289 SoC and Venus board Jason Li 2026-06-10 11:37 ` sashiko-bot @ 2026-06-10 11:49 ` Krzysztof Kozlowski 1 sibling, 0 replies; 12+ messages in thread From: Krzysztof Kozlowski @ 2026-06-10 11:49 UTC (permalink / raw) To: Jason Li, jason.li, Greg Kroah-Hartman, Jiri Slaby Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Catalin Marinas, Will Deacon, Arnd Bergmann, linux-serial, linux-arm-kernel, devicetree, linux-kernel On 10/06/2026 13:28, Jason Li wrote: > Add SoC DTSI for the Cortina-Access CA8289 (Venus) and a board DTS for > the Venus engineering board. The description covers the minimum set of > hardware nodes needed to boot a kernel with an INITRD rootfs: CPUs, > GIC, timer, PSCI, fixed clock and UART. > > Signed-off-by: Jason Li <jason.li@cortina-access.com> > Assisted-by: Claude:claude-opus-4-8 SoB should be the last tag. Also, it does not match From field. > --- > MAINTAINERS | 1 + > arch/arm64/Kconfig.platforms | 10 ++ > arch/arm64/boot/dts/Makefile | 1 + > arch/arm64/boot/dts/cortina-access/Makefile | 2 + > .../dts/cortina-access/ca8289-engboard.dts | 31 +++++ > .../boot/dts/cortina-access/ca8289-soc.dtsi | 118 ++++++++++++++++++ > 6 files changed, 163 insertions(+) > create mode 100644 arch/arm64/boot/dts/cortina-access/Makefile > create mode 100644 arch/arm64/boot/dts/cortina-access/ca8289-engboard.dts > create mode 100644 arch/arm64/boot/dts/cortina-access/ca8289-soc.dtsi > > diff --git a/MAINTAINERS b/MAINTAINERS > index 515d89d96472..ebfdb9c267cc 100644 > --- a/MAINTAINERS > +++ b/MAINTAINERS > @@ -2826,6 +2826,7 @@ L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) > S: Maintained > F: Documentation/devicetree/bindings/arm/cortina-access.yaml > F: Documentation/devicetree/bindings/serial/cortina-access,serial.yaml > +F: arch/arm64/boot/dts/cortina-access/ > > ARM/CORTINA SYSTEMS GEMINI ARM ARCHITECTURE > M: Hans Ulli Kroll <ulli.kroll@googlemail.com> > diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms > index dc995a732117..ba6dda0660c3 100644 > --- a/arch/arm64/Kconfig.platforms > +++ b/arch/arm64/Kconfig.platforms > @@ -134,6 +134,16 @@ config ARCH_CIX > This enables support for the Cixtech SoC family, > like P1(sky1). > > +config ARCH_CORTINA_ACCESS > + bool "Cortina-Access SoC Family" > + select GPIOLIB > + select PINCTRL > + help > + This enables support for Cortina-Access SoCs. The family > + includes ARMv8-based devices targeting networking and access > + applications. > + If you have a Cortina-Access board, say Y here. > + > config ARCH_EXYNOS > bool "Samsung Exynos SoC family" > select COMMON_CLK_SAMSUNG > diff --git a/arch/arm64/boot/dts/Makefile b/arch/arm64/boot/dts/Makefile > index 98ec8f1b76e4..a599f525fb9a 100644 > --- a/arch/arm64/boot/dts/Makefile > +++ b/arch/arm64/boot/dts/Makefile > @@ -16,6 +16,7 @@ subdir-y += broadcom > subdir-y += bst > subdir-y += cavium > subdir-y += cix > +subdir-y += cortina-access > subdir-y += exynos > subdir-y += freescale > subdir-y += hisilicon > diff --git a/arch/arm64/boot/dts/cortina-access/Makefile b/arch/arm64/boot/dts/cortina-access/Makefile > new file mode 100644 > index 000000000000..554893f381fe > --- /dev/null > +++ b/arch/arm64/boot/dts/cortina-access/Makefile > @@ -0,0 +1,2 @@ > +# SPDX-License-Identifier: GPL-2.0 > +dtb-$(CONFIG_ARCH_CORTINA_ACCESS) += ca8289-engboard.dtb > diff --git a/arch/arm64/boot/dts/cortina-access/ca8289-engboard.dts b/arch/arm64/boot/dts/cortina-access/ca8289-engboard.dts > new file mode 100644 > index 000000000000..c8289a0f8269 > --- /dev/null > +++ b/arch/arm64/boot/dts/cortina-access/ca8289-engboard.dts > @@ -0,0 +1,31 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * dts file for Cortina Access Venus Engineering Board > + * > + * Copyright (C) 2026, Cortina Access Inc. > + * > + */ > + > +/dts-v1/; > + > +#include "ca8289-soc.dtsi" > + > +/ { > + model = "Cortina Access Venus Engineering Board"; > + compatible = "cortina-access,ca8289-engboard"; > + #address-cells = <2>; > + #size-cells = <2>; > + > + aliases { > + serial0 = &uart0; > + }; > + > + chosen { > + stdout-path = "serial0:115200n8"; > + }; > + > + memory@0 { /* 512MB */ > + device_type = "memory"; > + reg = <0x00000000 0x00000000 0x0 0x20000000>; > + }; > +}; > diff --git a/arch/arm64/boot/dts/cortina-access/ca8289-soc.dtsi b/arch/arm64/boot/dts/cortina-access/ca8289-soc.dtsi > new file mode 100644 > index 000000000000..8e7ffcf4ccab > --- /dev/null > +++ b/arch/arm64/boot/dts/cortina-access/ca8289-soc.dtsi > @@ -0,0 +1,118 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * dts file for Cortina Access CA8289 SoC > + * > + * Copyright (C) 2026, Cortina Access Inc. > + */ > + > +#include <dt-bindings/interrupt-controller/arm-gic.h> > +#include <dt-bindings/interrupt-controller/irq.h> > + > +/ { > + cpus { > + #address-cells = <2>; > + #size-cells = <0>; > + > + cpu0: cpu@0 { > + compatible = "arm,cortex-a55", "arm,armv8"; > + device_type = "cpu"; > + reg = <0x0 0x0>; > + enable-method = "psci"; > + }; Missing blank lines. Look at existing code how this is supposed to look like. > + cpu1: cpu@100 { > + compatible = "arm,cortex-a55", "arm,armv8"; > + device_type = "cpu"; > + reg = <0x0 0x100>; > + enable-method = "psci"; > + }; > + cpu2: cpu@200 { > + compatible = "arm,cortex-a55", "arm,armv8"; > + device_type = "cpu"; > + reg = <0x0 0x200>; > + enable-method = "psci"; > + }; > + cpu3: cpu@300 { > + compatible = "arm,cortex-a55", "arm,armv8"; > + device_type = "cpu"; > + reg = <0x0 0x300>; > + enable-method = "psci"; > + }; > + cpu-map { > + cluster0 { > + core0 { > + cpu = <&cpu0>; > + }; > + core1 { > + cpu = <&cpu1>; > + }; > + core2 { > + cpu = <&cpu2>; > + }; > + core3 { > + cpu = <&cpu3>; > + }; > + }; > + }; > + }; > + > + psci { > + compatible = "arm,psci-0.2"; > + method = "smc"; > + }; > + > + gic: interrupt-controller@4f8000000 { And now you repeat basic mistakes: 1. Pointed out by W=1 dtbs_check build 2. Fixed long time in every source 3. Explicitly documented in writing bindings and DTS coding style > + compatible = "arm,gic-v3"; > + #interrupt-cells = <3>; > + interrupt-controller; > + #redistributor-regions = <1>; > + reg = <0x00000004 0xF8000000 0 0x10000>, > + <0x00000004 0xF8040000 0 0x80000>; Read DTS coding style. > + }; > + > + apb_pclk: apb-pclk { Nope, drop entire node. > + compatible = "fixed-clock"; > + #clock-cells = <0>; > + clock-frequency = <125000000>; > + }; > + > + reserved-memory { > + #address-cells = <2>; > + #size-cells = <2>; > + ranges; > + > + /* TrustZone reserved region; must not be mapped by the kernel */ > + tz_pool: tz-buffer@f000000 { > + reg = <0x0 0x0F000000 0x0 0x1000000>; > + no-map; > + }; > + }; > + > + /* See Documentation/devicetree/bindings/timer/arm,arch_timer.yaml */ > + timer { > + compatible = "arm,armv8-timer"; > + interrupt-parent = <&gic>; > + interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>, > + <GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>, > + <GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>, > + <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>; > + clock-frequency = <25000000>; > + }; > + > + uart0: serial@f4329188 { > + device_type = "serial"; > + compatible = "cortina-access,serial"; > + reg = <0x00000000 0xf4329188 0x0 0x30>; This is AI slop. Whatever Claude convinced you to do, it is nothing like upstream kernel source. Best regards, Krzysztof ^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2026-06-10 12:51 UTC | newest] Thread overview: 12+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-06-10 11:28 [PATCH 0/3] tty: serial: Add Cortina-Access UART driver and platform support Jason Li 2026-06-10 11:28 ` Jason Li 2026-06-10 12:50 ` Arnd Bergmann 2026-06-10 11:28 ` [PATCH 1/3] dt-bindings: serial: Add binding for Cortina-Access UART Jason Li 2026-06-10 11:36 ` sashiko-bot 2026-06-10 11:46 ` Krzysztof Kozlowski 2026-06-10 11:51 ` Krzysztof Kozlowski 2026-06-10 11:28 ` [PATCH 2/3] tty: serial: Add UART driver for Cortina-Access platform Jason Li 2026-06-10 11:40 ` sashiko-bot 2026-06-10 11:28 ` [PATCH 3/3] arm64: dts: cortina-access: Add DTS for CA8289 SoC and Venus board Jason Li 2026-06-10 11:37 ` sashiko-bot 2026-06-10 11:49 ` Krzysztof Kozlowski
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox