Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* iio: adc: KASAN wild-memory-access in complete() on early IRQ
From: Jaeyoung Chung @ 2026-06-10 11:57 UTC (permalink / raw)
  To: Jonathan Cameron, David Lechner, Nuno Sá, Andy Shevchenko,
	Vladimir Zapolskiy, Piotr Wojtaszczyk
  Cc: Jaeyoung Chung, linux-iio, linux-arm-kernel, linux-kernel,
	Sangyun Kim, Kyungwook Boo

Hi,

lpc32xx_adc_probe() in drivers/iio/adc/lpc32xx_adc.c and
spear_adc_probe() in drivers/iio/adc/spear_adc.c register their
interrupt handler with devm_request_irq() before they initialize
st->completion with init_completion(). If an interrupt arrives after
devm_request_irq() and before init_completion(), the handler calls
complete() on an uninitialized completion, causing a kernel panic.

The probe path, in lpc32xx_adc_probe():

    iodev = devm_iio_device_alloc(&pdev->dev, sizeof(*st)); /* st kzalloc-zeroed */
    ...
    retval = devm_request_irq(&pdev->dev, irq, lpc32xx_adc_isr, 0,
                              LPC32XXAD_NAME, st);           /* register handler */
    ...
    init_completion(&st->completion);                       /* initialize completion */

spear_adc_probe() has the same ordering: devm_request_irq() for
spear_adc_isr() before init_completion(&st->completion).

Both interrupt handlers, lpc32xx_adc_isr() and spear_adc_isr(), call
complete():

    complete(&st->completion);

If the device raises an interrupt before init_completion() runs,
complete() acquires the uninitialized wait.lock and walks the zeroed
task_list in swake_up_locked(). The zeroed task_list makes list_empty()
return false, so swake_up_locked() dereferences a NULL list entry,
triggering a KASAN wild-memory-access.

Suggested fix: move init_completion(&st->completion) above
devm_request_irq(), so the completion is valid before the handler can run.

Reported-by: Sangyun Kim <sangyun.kim@snu.ac.kr>
Reported-by: Kyungwook Boo <bookyungwook@gmail.com>

Thanks,
Jaeyoung Chung


^ permalink raw reply

* spi: uniphier: KASAN wild-memory-access in complete() on early IRQ
From: Jaeyoung Chung @ 2026-06-10 11:56 UTC (permalink / raw)
  To: Mark Brown, Kunihiko Hayashi, Masami Hiramatsu
  Cc: Jaeyoung Chung, linux-spi, linux-arm-kernel, linux-kernel,
	Sangyun Kim, Kyungwook Boo

Hi,

uniphier_spi_probe() in drivers/spi/spi-uniphier.c registers the
interrupt handler uniphier_spi_handler() with devm_request_irq() before
it initializes priv->xfer_done with init_completion(). If an interrupt
arrives after devm_request_irq() and before init_completion(), the
handler calls complete() on an uninitialized completion, causing a
kernel panic.

The probe path, in uniphier_spi_probe():

    host = spi_alloc_host(&pdev->dev, sizeof(*priv)); /* priv kzalloc-zeroed */
    ...
    ret = devm_request_irq(&pdev->dev, irq, uniphier_spi_handler,
                           0, "uniphier-spi", priv);  /* register handler */
    ...
    init_completion(&priv->xfer_done);                /* initialize completion */

The interrupt handler uniphier_spi_handler() calls complete() on its
done path:

    done:
        complete(&priv->xfer_done);

If the device raises an interrupt before init_completion() runs,
complete() acquires the uninitialized wait.lock and walks the zeroed
task_list in swake_up_locked(). The zeroed task_list makes list_empty()
return false, so swake_up_locked() dereferences a NULL list entry,
triggering a KASAN wild-memory-access.

Suggested fix: move init_completion(&priv->xfer_done) above
devm_request_irq(), so the completion is valid before the handler can run.

Reported-by: Sangyun Kim <sangyun.kim@snu.ac.kr>
Reported-by: Kyungwook Boo <bookyungwook@gmail.com>

Thanks,
Jaeyoung Chung


^ permalink raw reply

* Re: [PATCH v17 21/28] drm/tests: bridge: Add KUnit tests for bridge chain format selection
From: Jani Nikula @ 2026-06-10 11:54 UTC (permalink / raw)
  To: Nicolas Frattaroli, Harry Wentland, Leo Li, Rodrigo Siqueira,
	Alex Deucher, Christian König, David Airlie, Simona Vetter,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
	Jonas Karlman, Jernej Skrabec, Sandy Huang, Heiko Stübner,
	Andy Yan, Rodrigo Vivi, Joonas Lahtinen, Tvrtko Ursulin,
	Dmitry Baryshkov, Sascha Hauer, Rob Herring, Jonathan Corbet,
	Shuah Khan, Daniel Stone
  Cc: kernel, amd-gfx, dri-devel, linux-kernel, linux-arm-kernel,
	linux-rockchip, intel-gfx, intel-xe, linux-doc, wayland-devel
In-Reply-To: <gnicb4WkT1S4aQIC2G_naw@collabora.com>

On Wed, 10 Jun 2026, Nicolas Frattaroli <nicolas.frattaroli@collabora.com> wrote:
> If you don't want __maybe_unused, then sure, I'll move them into a new
> .c file. Though I think the two are roughly equivalent in that I don't
> think anyone is really trying to minimise the size of their KUnit
> binaries.

I think placing arrays in headers is bad practice, and we shouldn't set
that example, kunit or not.

> I'll send a patch to move them to a .c

Thanks.

BR,
Jani.


-- 
Jani Nikula, Intel


^ permalink raw reply

* Re: [PATCH] arm64: dts: lx2160a-rev2: avoid 32-bit pcie window system ram overlap
From: Arnd Bergmann @ 2026-06-10 11:51 UTC (permalink / raw)
  To: Josua Mayer, Frank Li, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley
  Cc: linux-arm-kernel, devicetree, linux-kernel
In-Reply-To: <20260610-lx2160-pcie-fix-ranges-32bit-v1-1-98086fc5fb6b@solid-run.com>

On Wed, Jun 10, 2026, at 13:45, Josua Mayer wrote:
> A 3GB non-prefetchable PCIe bus window can overlap with inbound DMA
> addresses for low system RAM, so DMA transactions may be routed to a BAR
> on the same host bridge instead of memory.
>
> Change the 32-bit non-prefetchable PCIe window back from 3GB to 1GB on all
> controllers, avoiding that overlap while keeping the added 64-bit
> prefetchable region.
>
> This partially reverts commit 9ed301397090 ("arm64: dts: lx2160a-rev2:
> extend 32-bit and add 64-bit pci regions").
>
> Fixes: 9ed301397090 ("arm64: dts: lx2160a-rev2: extend 32-bit and add 
> 64-bit pci regions")
> Reported-by: Arnd Bergmann <arnd@arndb.de>
> Closes: 
> https://lore.kernel.org/r/9e6326f6-dad1-4169-a63c-e62ee5b341f2@app.fastmail.com
> Signed-off-by: Josua Mayer <josua@solid-run.com>

Looks good to me, thanks for the fix!

Acked-by: Arnd Bergmann <arnd@arndb.de>


^ permalink raw reply

* Re: [PATCH 1/3] dt-bindings: serial: Add binding for Cortina-Access UART
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
In-Reply-To: <20260610112821.3030099-3-jason.li@cortina-access.com>

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

* Re: [PATCH 3/3] arm64: dts: cortina-access: Add DTS for CA8289 SoC and Venus board
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
In-Reply-To: <20260610112821.3030099-5-jason.li@cortina-access.com>

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

* Re: [PATCH 1/3] dt-bindings: serial: Add binding for Cortina-Access UART
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
In-Reply-To: <20260610112821.3030099-3-jason.li@cortina-access.com>

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

* [PATCH] arm64: dts: lx2160a-rev2: avoid 32-bit pcie window system ram overlap
From: Josua Mayer @ 2026-06-10 11:45 UTC (permalink / raw)
  To: Frank Li, Rob Herring, Krzysztof Kozlowski, Conor Dooley
  Cc: linux-arm-kernel, devicetree, linux-kernel, Arnd Bergmann,
	Josua Mayer

A 3GB non-prefetchable PCIe bus window can overlap with inbound DMA
addresses for low system RAM, so DMA transactions may be routed to a BAR
on the same host bridge instead of memory.

Change the 32-bit non-prefetchable PCIe window back from 3GB to 1GB on all
controllers, avoiding that overlap while keeping the added 64-bit
prefetchable region.

This partially reverts commit 9ed301397090 ("arm64: dts: lx2160a-rev2:
extend 32-bit and add 64-bit pci regions").

Fixes: 9ed301397090 ("arm64: dts: lx2160a-rev2: extend 32-bit and add 64-bit pci regions")
Reported-by: Arnd Bergmann <arnd@arndb.de>
Closes: https://lore.kernel.org/r/9e6326f6-dad1-4169-a63c-e62ee5b341f2@app.fastmail.com
Signed-off-by: Josua Mayer <josua@solid-run.com>
---
 arch/arm64/boot/dts/freescale/fsl-lx2160a-rev2.dtsi | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/arch/arm64/boot/dts/freescale/fsl-lx2160a-rev2.dtsi b/arch/arm64/boot/dts/freescale/fsl-lx2160a-rev2.dtsi
index 3570399f9b21c..3d2637fee2d35 100644
--- a/arch/arm64/boot/dts/freescale/fsl-lx2160a-rev2.dtsi
+++ b/arch/arm64/boot/dts/freescale/fsl-lx2160a-rev2.dtsi
@@ -17,7 +17,7 @@ &pcie1 {
 	ranges = /* 16-Bit IO Window */
 		 <0x81000000 0x00 0x00000000 0x80 0x00010000 0x00 0x00010000>,
 		 /* 32-Bit - non-prefetchable */
-		 <0x82000000 0x00 0x40000000 0x80 0x40000000 0x00 0xc0000000>,
+		 <0x82000000 0x00 0x40000000 0x80 0x40000000 0x00 0x40000000>,
 		 /* 64-Bit - prefetchable - 16GB */
 		 <0xC3000000 0x84 0x00000000 0x84 0x00000000 0x04 0x00000000>;
 
@@ -37,7 +37,7 @@ &pcie2 {
 	ranges = /* 16-Bit IO Window */
 		 <0x81000000 0x00 0x00000000 0x88 0x00010000 0x00 0x00010000>,
 		 /* 32-Bit - non-prefetchable */
-		 <0x82000000 0x00 0x40000000 0x88 0x40000000 0x00 0xc0000000>,
+		 <0x82000000 0x00 0x40000000 0x88 0x40000000 0x00 0x40000000>,
 		 /* 64-Bit - prefetchable - 16GB */
 		 <0xC3000000 0x8c 0x00000000 0x8c 0x00000000 0x04 0x00000000>;
 
@@ -57,7 +57,7 @@ &pcie3 {
 	ranges = /* 16-Bit IO Window */
 		 <0x81000000 0x00 0x00000000 0x90 0x00010000 0x00 0x00010000>,
 		 /* 32-Bit - non-prefetchable */
-		 <0x82000000 0x00 0x40000000 0x90 0x40000000 0x00 0xc0000000>,
+		 <0x82000000 0x00 0x40000000 0x90 0x40000000 0x00 0x40000000>,
 		 /* 64-Bit - prefetchable - 16GB */
 		 <0xC3000000 0x94 0x00000000 0x94 0x00000000 0x04 0x00000000>;
 
@@ -78,7 +78,7 @@ &pcie4 {
 	ranges = /* 16-Bit IO Window */
 		 <0x81000000 0x00 0x00000000 0x98 0x00010000 0x00 0x00010000>,
 		 /* 32-Bit - non-prefetchable */
-		 <0x82000000 0x00 0x40000000 0x98 0x40000000 0x00 0xc0000000>,
+		 <0x82000000 0x00 0x40000000 0x98 0x40000000 0x00 0x40000000>,
 		 /* 64-Bit - prefetchable - 16GB */
 		 <0xC3000000 0x9c 0x00000000 0x9c 0x00000000 0x04 0x00000000>;
 
@@ -98,7 +98,7 @@ &pcie5 {
 	ranges = /* 16-Bit IO Window */
 		 <0x81000000 0x00 0x00000000 0xa0 0x00010000 0x00 0x00010000>,
 		 /* 32-Bit - non-prefetchable */
-		 <0x82000000 0x00 0x40000000 0xa0 0x40000000 0x00 0xc0000000>,
+		 <0x82000000 0x00 0x40000000 0xa0 0x40000000 0x00 0x40000000>,
 		 /* 64-Bit - prefetchable - 16GB */
 		 <0xC3000000 0xa4 0x00000000 0xa4 0x00000000 0x04 0x00000000>;
 
@@ -118,7 +118,7 @@ &pcie6 {
 	ranges = /* 16-Bit IO Window */
 		 <0x81000000 0x00 0x00000000 0xa8 0x00010000 0x00 0x00010000>,
 		 /* 32-Bit - non-prefetchable */
-		 <0x82000000 0x00 0x40000000 0xa8 0x40000000 0x00 0xc0000000>,
+		 <0x82000000 0x00 0x40000000 0xa8 0x40000000 0x00 0x40000000>,
 		 /* 64-Bit - prefetchable - 16GB */
 		 <0xC3000000 0xac 0x00000000 0xac 0x00000000 0x04 0x00000000>;
 

---
base-commit: c10cfc952215644956284a42fa7b7860dfbcb5f5
change-id: 20260610-lx2160-pcie-fix-ranges-32bit-0868570e495f

Best regards,
-- 
Josua Mayer <josua@solid-run.com>



^ permalink raw reply related

* Re: [PATCH] usb: gadget: aspeed_udc: check endpoint DMA allocation
From: Andrew Jeffery @ 2026-06-10 11:45 UTC (permalink / raw)
  To: Ruoyu Wang, Neal Liu, Greg Kroah-Hartman
  Cc: Joel Stanley, linux-aspeed, linux-usb, linux-arm-kernel,
	linux-kernel
In-Reply-To: <20260608081948.3-1-ruoyuw560@gmail.com>

On Mon, 2026-06-08 at 16:19 +0800, Ruoyu Wang wrote:
> ast_udc_probe() allocates a coherent DMA buffer used as the backing store
> for endpoint buffers. ast_udc_init_ep() derives per-endpoint buffer
> pointers from udc->ep0_buf, so a failed allocation is dereferenced during
> probe.
> 
> Check the allocation before endpoint setup. The existing probe error path
> called ast_udc_remove(), which unregisters the gadget unconditionally and
> is not safe before usb_add_gadget_udc() succeeds. Add a local cleanup
> helper for probe failures so pre-registration failures only unwind the
> resources that were actually initialized.
> 
> This was found by a local static analysis checker for unchecked allocator
> returns while scanning Linux 6.16. The change was checked by applying it
> to current mainline and by running checkpatch. I do not have access to
> Aspeed UDC hardware, so no runtime testing was performed.
> 
> Fixes: 055276c13205 ("usb: gadget: add Aspeed ast2600 udc driver")
> Signed-off-by: Ruoyu Wang <ruoyuw560@gmail.com>
> ---
> Note: a 2022 patch attempted to add only a NULL check for this
> allocation:
> https://lore.kernel.org/all/20221213025120.23149-1-jiasheng@iscas.ac.cn/
> 
> This version also fixes the probe unwind path so the clock is disabled
> on allocation failure and usb_del_gadget_udc() is not called before the
> gadget has been registered.
> 
> diff --git a/drivers/usb/gadget/udc/aspeed_udc.c b/drivers/usb/gadget/udc/aspeed_udc.c
> index 7fc6696b7..809a7d5b7 100644
> --- a/drivers/usb/gadget/udc/aspeed_udc.c
> +++ b/drivers/usb/gadget/udc/aspeed_udc.c
> @@ -1434,11 +1434,34 @@ static void ast_udc_init_hw(struct ast_udc_dev *udc)
>  	ast_udc_write(udc, 0, AST_UDC_EP0_CTRL);
>  }
>  
> +static void ast_udc_cleanup(struct platform_device *pdev)
> +{
> +	struct ast_udc_dev *udc = platform_get_drvdata(pdev);
> +	unsigned long flags;
> +	u32 ctrl;
> +
> +	spin_lock_irqsave(&udc->lock, flags);
> +
> +	/* Disable upstream port connection */
> +	ctrl = ast_udc_read(udc, AST_UDC_FUNC_CTRL) & ~USB_UPSTREAM_EN;
> +	ast_udc_write(udc, ctrl, AST_UDC_FUNC_CTRL);
> +
> +	clk_disable_unprepare(udc->clk);
> +
> +	spin_unlock_irqrestore(&udc->lock, flags);
> +
> +	if (udc->ep0_buf)
> +		dma_free_coherent(&pdev->dev,
> +				  AST_UDC_EP_DMA_SIZE * AST_UDC_NUM_ENDPOINTS,
> +				  udc->ep0_buf,
> +				  udc->ep0_buf_dma);
> +
> +	udc->ep0_buf = NULL;
> +}
> +
>  static void ast_udc_remove(struct platform_device *pdev)
>  {
>  	struct ast_udc_dev *udc = platform_get_drvdata(pdev);
> -	unsigned long flags;
> -	u32 ctrl;
>  
>  	usb_del_gadget_udc(&udc->gadget);
>  	if (udc->driver) {
> @@ -1453,23 +1476,7 @@ static void ast_udc_remove(struct platform_device *pdev)
>  		return;
>  	}
>  
> -	spin_lock_irqsave(&udc->lock, flags);
> -
> -	/* Disable upstream port connection */
> -	ctrl = ast_udc_read(udc, AST_UDC_FUNC_CTRL) & ~USB_UPSTREAM_EN;
> -	ast_udc_write(udc, ctrl, AST_UDC_FUNC_CTRL);
> -
> -	clk_disable_unprepare(udc->clk);
> -
> -	spin_unlock_irqrestore(&udc->lock, flags);
> -
> -	if (udc->ep0_buf)
> -		dma_free_coherent(&pdev->dev,
> -				  AST_UDC_EP_DMA_SIZE * AST_UDC_NUM_ENDPOINTS,
> -				  udc->ep0_buf,
> -				  udc->ep0_buf_dma);
> -
> -	udc->ep0_buf = NULL;
> +	ast_udc_cleanup(pdev);
>  }
>  
>  static int ast_udc_probe(struct platform_device *pdev)
> @@ -1523,6 +1530,10 @@ static int ast_udc_probe(struct platform_device *pdev)
>  					  AST_UDC_EP_DMA_SIZE *
>  					  AST_UDC_NUM_ENDPOINTS,
>  					  &udc->ep0_buf_dma, GFP_KERNEL);
> +	if (!udc->ep0_buf) {
> +		rc = -ENOMEM;
> +		goto err_disable_clk;
> +	}
>  
>  	udc->gadget.speed = USB_SPEED_UNKNOWN;
>  	udc->gadget.max_speed = USB_SPEED_HIGH;
> @@ -1553,20 +1564,20 @@ static int ast_udc_probe(struct platform_device *pdev)
>  	udc->irq = platform_get_irq(pdev, 0);
>  	if (udc->irq < 0) {
>  		rc = udc->irq;
> -		goto err;
> +		goto err_cleanup;
>  	}
>  
>  	rc = devm_request_irq(&pdev->dev, udc->irq, ast_udc_isr, 0,
>  			      KBUILD_MODNAME, udc);
>  	if (rc) {
>  		dev_err(&pdev->dev, "Failed to request interrupt\n");
> -		goto err;
> +		goto err_cleanup;
>  	}
>  
>  	rc = usb_add_gadget_udc(&pdev->dev, &udc->gadget);
>  	if (rc) {
>  		dev_err(&pdev->dev, "Failed to add gadget udc\n");
> -		goto err;
> +		goto err_cleanup;
>  	}
>  
>  	dev_info(&pdev->dev, "Initialized udc in USB%s mode\n",
> @@ -1574,9 +1585,14 @@ static int ast_udc_probe(struct platform_device *pdev)
>  
>  	return 0;
>  
> +err_disable_clk:
> +	clk_disable_unprepare(udc->clk);
> +	goto err;
> +err_cleanup:
> +	ast_udc_cleanup(pdev);
> +	goto err;
>  err:

That last goto is unnecessary.

However, I find it unsettling that in a patch fixing resource handling
we add a mildly convoluted cleanup path, with portions jumping over
each other in this way.

The err_disable_clk label is only used once, and itself jumps down to
the err label. This is the case because beyond its goto we free udc-
>ep0_buf in ast_udc_cleanup(). I think it would make more sense to move
the call to clk_disable_unprepare() into the conditional body of the
allocation failure test, then change its goto label to 'err'. That way
the above hunk becomes:

   +err_cleanup:
   +    ast_udc_cleanup(pdev);
    err:
        ...

Which seems a bit more natural.

Andrew

>  	dev_err(&pdev->dev, "Failed to udc probe, rc:0x%x\n", rc);
> -	ast_udc_remove(pdev);
>  
>  	return rc;
>  }


^ permalink raw reply

* Re: [PATCH v17 21/28] drm/tests: bridge: Add KUnit tests for bridge chain format selection
From: Nicolas Frattaroli @ 2026-06-10 11:42 UTC (permalink / raw)
  To: Harry Wentland, Leo Li, Rodrigo Siqueira, Alex Deucher,
	Christian König, David Airlie, Simona Vetter,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
	Jonas Karlman, Jernej Skrabec, Sandy Huang, Heiko Stübner,
	Andy Yan, Rodrigo Vivi, Joonas Lahtinen, Tvrtko Ursulin,
	Dmitry Baryshkov, Sascha Hauer, Rob Herring, Jonathan Corbet,
	Shuah Khan, Daniel Stone, Jani Nikula
  Cc: kernel, amd-gfx, dri-devel, linux-kernel, linux-arm-kernel,
	linux-rockchip, intel-gfx, intel-xe, linux-doc, wayland-devel
In-Reply-To: <04ff70850213ae0f75486b1a27a7edb6fb4e71c3@intel.com>

On Wednesday, 10 June 2026 12:32:29 Central European Summer Time Jani Nikula wrote:
> On Tue, 09 Jun 2026, Nicolas Frattaroli <nicolas.frattaroli@collabora.com> wrote:
> > diff --git a/drivers/gpu/drm/tests/drm_bridge_test.c b/drivers/gpu/drm/tests/drm_bridge_test.c
> > index 64b665580a88..92f142ca6695 100644
> > --- a/drivers/gpu/drm/tests/drm_bridge_test.c
> > +++ b/drivers/gpu/drm/tests/drm_bridge_test.c
> > @@ -2,15 +2,23 @@
> >  /*
> >   * Kunit test for drm_bridge functions
> >   */
> > +#include <linux/cleanup.h>
> > +#include <linux/media-bus-format.h>
> > +
> >  #include <drm/drm_atomic_state_helper.h>
> > +#include <drm/drm_atomic_uapi.h>
> >  #include <drm/drm_bridge.h>
> >  #include <drm/drm_bridge_connector.h>
> >  #include <drm/drm_bridge_helper.h>
> > +#include <drm/drm_edid.h>
> >  #include <drm/drm_kunit_helpers.h>
> > +#include <drm/drm_managed.h>
> >  
> >  #include <kunit/device.h>
> >  #include <kunit/test.h>
> >  
> > +#include "drm_kunit_edid.h"
> 
> So here's the problem with adding *any* arrays into headers: every
> compilation unit that includes them duplicates all the arrays. It's only
> really okay for single use.
> 
> And, in this case, most of the included arrays are unused, leading to
> build failures:
> 
>   CC [M]  drivers/gpu/drm/tests/drm_bridge_test.o
> In file included from ../drivers/gpu/drm/tests/drm_bridge_test.c:21:
> ../drivers/gpu/drm/tests/drm_kunit_edid.h:958:28: error: ‘test_edid_hdmi_4k_rgb_yuv420_dc_max_340mhz’ defined but not used [-Werror=unused-const-variable=]
>   958 | static const unsigned char test_edid_hdmi_4k_rgb_yuv420_dc_max_340mhz[] = {
>       |                            ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> ../drivers/gpu/drm/tests/drm_kunit_edid.h:726:28: error: ‘test_edid_hdmi_1080p_rgb_yuv_dc_max_340mhz’ defined but not used [-Werror=unused-const-variable=]
>   726 | static const unsigned char test_edid_hdmi_1080p_rgb_yuv_dc_max_340mhz[] = {
>       |                            ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> ../drivers/gpu/drm/tests/drm_kunit_edid.h:612:28: error: ‘test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz’ defined but not used [-Werror=unused-const-variable=]
>   612 | static const unsigned char test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz[] = {
>       |                            ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> ../drivers/gpu/drm/tests/drm_kunit_edid.h:498:28: error: ‘test_edid_hdmi_1080p_rgb_max_340mhz’ defined but not used [-Werror=unused-const-variable=]
>   498 | static const unsigned char test_edid_hdmi_1080p_rgb_max_340mhz[] = {
>       |                            ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> ../drivers/gpu/drm/tests/drm_kunit_edid.h:390:28: error: ‘test_edid_hdmi_1080p_rgb_max_200mhz_hdr’ defined but not used [-Werror=unused-const-variable=]
>   390 | static const unsigned char test_edid_hdmi_1080p_rgb_max_200mhz_hdr[] = {
>       |                            ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> ../drivers/gpu/drm/tests/drm_kunit_edid.h:271:28: error: ‘test_edid_hdmi_1080p_rgb_max_200mhz’ defined but not used [-Werror=unused-const-variable=]
>   271 | static const unsigned char test_edid_hdmi_1080p_rgb_max_200mhz[] = {
>       |                            ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> ../drivers/gpu/drm/tests/drm_kunit_edid.h:163:28: error: ‘test_edid_hdmi_1080p_rgb_max_100mhz’ defined but not used [-Werror=unused-const-variable=]
>   163 | static const unsigned char test_edid_hdmi_1080p_rgb_max_100mhz[] = {
>       |                            ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> ../drivers/gpu/drm/tests/drm_kunit_edid.h:57:28: error: ‘test_edid_dvi_1080p’ defined but not used [-Werror=unused-const-variable=]
>    57 | static const unsigned char test_edid_dvi_1080p[] = {
>       |                            ^~~~~~~~~~~~~~~~~~~
> cc1: all warnings being treated as errors
> 
> This breaks the build for me, I don't know how it didn't for any of you.

It broke the build for me in the past[1], but then I couldn't repro
it anymore when challenged on my fix[2].

> 
> Reverting these two fixes it:
> 
> ce1d0139adac ("drm/tests: bridge: Add test for HDMI output bus formats helper")
> 082fbc179c01 ("drm/tests: bridge: Add KUnit tests for bridge chain format selection")
> 
> I think the proper fix would be to move the arrays into a .c file, and
> only have declarations in the headers. But that needs to happen real
> soon or the commits need to be reverted.

If you don't want __maybe_unused, then sure, I'll move them into a new
.c file. Though I think the two are roughly equivalent in that I don't
think anyone is really trying to minimise the size of their KUnit
binaries.

I'll send a patch to move them to a .c

[1]: https://lore.kernel.org/dri-devel/20260121-color-format-v7-20-ef790dae780c@collabora.com/
[2]: https://lore.kernel.org/dri-devel/20260210-didactic-okapi-of-modernism-ff00d9@houat/

Kind regards,
Nicolas Frattaroli

> 
> BR,
> Jani.
> 
> 
> 






^ permalink raw reply

* Re: [PATCH v4 1/2] arm64: smp: Fix hot-unplug tearing by forcing unregistration
From: Catalin Marinas @ 2026-06-10 11:38 UTC (permalink / raw)
  To: Jinjie Ruan
  Cc: will, corbet, skhan, punit.agrawal, mrigendra.chaubey,
	suzuki.poulose, chenl311, fengchengwen, maz, timothy.hayes,
	lpieralisi, arnd, gshan, jic23, dietmar.eggemann, sudeep.holla,
	pierre.gondois, linux-arm-kernel, linux-doc, linux-kernel
In-Reply-To: <20260610075202.3597031-2-ruanjinjie@huawei.com>

On Wed, Jun 10, 2026 at 03:52:01PM +0800, Jinjie Ruan wrote:
> Sashiko review pointed out the following issue[1].
> 
> Commit eba4675008a6 ("arm64: arch_register_cpu() variant to check if
> an ACPI handle is now available.") introduced architectural safety
> blocks inside arch_unregister_cpu(). If a hot-unplug operation is
> determined to be a physical hardware removal (where _STA evaluates to
> !ACPI_STA_DEVICE_PRESENT), or if firmware evaluation fails, it aborts
> the unregistration transaction early to protect unreadied arm64
> infrastructure.
> 
> However, returning early from arch_unregister_cpu() causes a catastrophic
> state tearing because the generic ACPI layer (acpi_processor_post_eject())
> unconditionally continues its cleanup flow. This leaves the stale sysfs
> device leaked in the memory, deadlocking any subsequent hot-add attempts
> on the same CPU.
> 
> Fix it by simplifying arch_unregister_cpu() to always proceed with
> the unregistration, as a pr_err_once() warning is sufficient to make
> it more visible for currently not supported physical CPU removal.
> Also remove the redundant NULL check on acpi_handle as it cannot be
> NULL when calling arch_unregister_cpu().
> 
> [1]: https://sashiko.dev/#/patchset/20260520022023.126670-1-ruanjinjie@huawei.com
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: Jonathan Cameron <jic23@kernel.org>
> Cc: James Morse <james.morse@arm.com>
> Cc: stable@vger.kernel.org
> Fixes: eba4675008a6e ("arm64: arch_register_cpu() variant to check if an ACPI handle is now available.")
> Suggested-by: Catalin Marinas <catalin.marinas@arm.com>
> Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>

Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>


^ permalink raw reply

* Re: [Question] Enabling CoreSight TRBE in firmware on CIX Orion O6
From: Leo Yan @ 2026-06-10 11:34 UTC (permalink / raw)
  To: Gary Yang
  Cc: Yunseong Kim, Peter Chen, Fugang Duan, Guomin Chen, Hans Zhang,
	Joakim Zhang, Jerry Zhu, CIX Linux Kernel Upstream Group,
	devicetree, linux-arm-kernel, linux-kernel@vger.kernel.org,
	Yunseong Kim, Yunseong Kim
In-Reply-To: <aikVYZDMYuPscIKR@gary-System-Product-Name>

On Wed, Jun 10, 2026 at 03:42:25PM +0800, Gary Yang wrote:

[...]

> >   (2) Or expose the full CoreSight topology in ACPI:
> >      - Add ARMHC97C (TMC-ETR) device with MMIO base address
> >      - Add ARMHC502 (funnel) devices if applicable
> >      - Reference: ARM DEN0067 (CoreSight Architecture ACPI bindings)

The CPUs on O6 support ETE + TRBE, you don't need to use ETR or funnel
modules.

> The firmware (TF-A) for the Radxa O6 is provided and maintained by Radxa. We 
> will forward your request to the Radxa firmware team and ask them to evaluate 
> enabling TRBE access from non-secure EL1/EL2 (i.e. setting MDCR_EL3.NSTBE = 1 
> in TF-A), as you suggested.

The issue is caused by ACPI: the APIC table does not contain a TRBE
interrupt, and the SSDT is missing ETE nodes (ETE node should be
present for each CPU):

  Device (CPU0)
  {
    ...

    Device ( ETE0 ) {
        Name (_UID, Zero)
        Name (_HID , "ARMHC500")
    }
  }

Thanks,
Leo


^ permalink raw reply

* [PATCH 3/3] arm64: dts: cortina-access: Add DTS for CA8289 SoC and Venus board
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
In-Reply-To: <20260610112821.3030099-1-jason.li@cortina-access.com>

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

* [PATCH 2/3] tty: serial: Add UART driver for Cortina-Access platform
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
In-Reply-To: <20260610112821.3030099-1-jason.li@cortina-access.com>

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

* [PATCH 1/3] dt-bindings: serial: Add binding for Cortina-Access UART
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
In-Reply-To: <20260610112821.3030099-1-jason.li@cortina-access.com>

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

* [PATCH 0/3] tty: serial: Add Cortina-Access UART driver and platform support
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
In-Reply-To: <20260610112821.3030099-1-jason.li@cortina-access.com>

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

* [PATCH 0/3] tty: serial: Add Cortina-Access UART driver and platform support
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

* Re: [PATCH v2] arm64: errata: Workaround NVIDIA Olympus device store/load ordering erratum
From: Will Deacon @ 2026-06-10 11:28 UTC (permalink / raw)
  To: Shanker Donthineni
  Cc: Catalin Marinas, linux-arm-kernel, Vladimir Murzin, Mark Rutland,
	linux-kernel, linux-doc, Vikram Sethi, Jason Sequeira, jgg
In-Reply-To: <20260605144551.2004391-1-sdonthineni@nvidia.com>

[+Jason G]

On Fri, Jun 05, 2026 at 09:45:51AM -0500, Shanker Donthineni wrote:
> On systems with NVIDIA Olympus cores, a Device-nGnR* load can be
> observed by a peripheral before an older, non-overlapping Device-nGnR*
> store to the same peripheral. This breaks the program-order guarantee
> that software expects for Device-nGnR* accesses and can leave a
> peripheral in an incorrect state, as a load is observed before an
> earlier store takes effect.
> 
> The erratum can occur only when all of the following apply:
> 
>   - A PE executes a Device-nGnR* store followed by a younger
>     Device-nGnR* load.
>   - The store is not a store-release.
>   - The accesses target the same peripheral and do not overlap in bytes.
>   - There is at most one intervening Device-nGnR* store in program
>     order, and there are no intervening Device-nGnR* loads.
>   - There is no DSB, and no DMB that orders loads, between the store and
>     the load.
>   - Specific micro-architectural and timing conditions occur.
> 
> Two ways to restore ordering: insert a barrier (any DSB, or a DMB that
> orders loads) between the store and the load, or make the store a
> store-release. A load-acquire on the load side would not help, because
> acquire semantics do not prevent a load from being observed ahead of an
> older store; only the store side (release or a barrier) closes the
> window.

I think you can drop the paragraph above. A store-release isn't enough
to order against a later load in the architecture either, so we're
clearly in micro-architecture territory and I don't think you need to
describe mechanisms that don't work here.

> Promote the raw MMIO store helpers (__raw_writeb/w/l/q) from plain str*
> to stlr* (Store-Release), which removes the "store is not a
> store-release" condition for every device write the kernel issues.
> Because writel() and writel_relaxed() are both built on __raw_writel()
> in asm-generic/io.h, patching the raw variants covers both the
> non-relaxed and relaxed APIs without touching the higher layers. Note
> that writel()'s own barrier sits before the store, so it does not order
> the store against a subsequent readl(); the store-release promotion is
> what provides that ordering.

Sashiko points out that you're missing __const_memcpy_toio_aligned32().

> Like ARM64_ERRATUM_832075 on the load side, the change is gated on a new
> ARM64_WORKAROUND_DEVICE_STORE_RELEASE capability and only activated on
> parts that match MIDR_NVIDIA_OLYMPUS, so unaffected CPUs continue to use
> the plain str* sequence.
> 
> Note: stlr* only supports base-register addressing, so the raw accessors
> can no longer use the offset addressing introduced by commit d044d6ba6f02
> ("arm64: io: permit offset addressing"). The str* and stlr* alternates
> share a single inline-asm operand and the sequence is selected at boot,
> so the operand form is fixed at compile time; unaffected CPUs keep using
> str* but also revert to base-register addressing. This keeps the store
> side as simple as the existing load-side patching (load-acquire) and
> avoids adding complexity to the device write path; retaining offset
> addressing only for str* would otherwise require a runtime branch on
> every write.

I seem to remember Jason caring about that, possibly because some CPUs
are very picky about write-combining?

Will


^ permalink raw reply

* Re: [PATCH v1] arm64: errata: Mitigate TLBI errata on NVIDIA Olympus CPU
From: Mark Rutland @ 2026-06-10 11:28 UTC (permalink / raw)
  To: Shanker Donthineni
  Cc: Catalin Marinas, Will Deacon, linux-arm-kernel, linux-kernel,
	linux-doc, Vikram Sethi, Jason Sequeira, Alok Mooley, Rich Wiley
In-Reply-To: <aik1owW9Rz8B7rEz@J2N7QTR9R3>

On Wed, Jun 10, 2026 at 11:00:03AM +0100, Mark Rutland wrote:
> On Tue, Jun 09, 2026 at 06:40:44PM -0500, Shanker Donthineni wrote:
> I have one minor comment below, but that's more for Catalin/Will, and
> doesn't require a respin.

[...]

> As this is getting increasingly long, maybe it's worth reducing this to
> "Various" in the title, i.e.
> 
> 	bool "Cortex-*/Neoverse: Completion of affected memory accesses might not be guaranteed by completion of a TLBI"

Sorry, I messed that up when copy-editing. That should have been:

	bool "Various: Completion of affected memory accesses might not be guaranteed by completion of a TLBI"

As above, that doesn't need a respin.

Mark.


^ permalink raw reply

* Re: [PATCH v6 2/2] ARM: dts: aspeed: ventura2: Add Meta ventura2 BMC
From: Andrew Jeffery @ 2026-06-10 11:22 UTC (permalink / raw)
  To: Kyle Hsieh, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Joel Stanley
  Cc: devicetree, linux-arm-kernel, linux-aspeed, linux-kernel
In-Reply-To: <20260610-ventura2_initial_dts-v6-2-375d8e9d7ebf@gmail.com>

Hi Kyle,

On Wed, 2026-06-10 at 09:22 +0800, Kyle Hsieh wrote:
> Add linux device tree entry related to the Meta(Facebook) rmc-node.
> The system uses an AT2600 BMC.
> This node is named "ventura2".
> 
> Signed-off-by: Kyle Hsieh <kylehsieh1995@gmail.com>

I have some comments on v5 that are applicable here too.

https://lore.kernel.org/all/3d56889c004fc2d11b76ace6033c7ccfb8a37d03.camel@codeconstruct.com.au/

Andrew


^ permalink raw reply

* Re: [PATCH 1/2] KVM: arm64: Replace memslot_is_logging() with kvm_slot_dirty_track_enabled()
From: Wei-Lin Chang @ 2026-06-10 11:18 UTC (permalink / raw)
  To: Alexandru Elisei, Leonardo Bras
  Cc: linux-arm-kernel, kvmarm, linux-kernel, Marc Zyngier,
	Oliver Upton, Joey Gouly, Steffen Eiden, Suzuki K Poulose,
	Zenghui Yu, Catalin Marinas, Will Deacon, Gavin Shan
In-Reply-To: <aiky6H02ArbFpwGZ@raptor>

On Wed, Jun 10, 2026 at 10:48:24AM +0100, Alexandru Elisei wrote:
> Hi Leo,
> 
> Just FYI, write faults on read-only memslots are handled as MMIO accesses in
> kvm_handle_guest_abort() (gfn_to_hva_memslot_prot() sets @writable to false).

Thanks! I also missed this...

With this it looks like the behavior of the condition at the third callsite
will be the same regardless of using memslot_is_logging() or
kvm_slot_dirty_track_enabled().

For the second, s2vi->map_writable can only be true if the memslot is not RO.
So no behavior changes there, in terms of the extra RO check in
memslot_is_logging().

Thanks,
Wei-Lin Chang

> 
> Thanks,
> Alex
> 
> On Tue, Jun 09, 2026 at 05:31:01PM +0100, Leonardo Bras wrote:
> > On Mon, Jun 08, 2026 at 04:55:45PM +0100, Leonardo Bras wrote:
> > > Hi Wei Lin,
> > > 
> > > On Fri, Jun 05, 2026 at 04:32:47PM +0100, Wei-Lin Chang wrote:
> > > > When checking whether a memslot has dirty logging enabled, the
> > > > KVM_MEM_LOG_DIRTY_PAGES flag is the source of truth. Previously we were
> > > > using memslot_is_logging() which only tests dirty bitmap and did not
> > > > consider dirty ring. This was not detected because
> > > > KVM_CAP_DIRTY_LOG_RING_WITH_BITMAP was introduced together with KVM
> > > > arm64 dirty ring, and users need to enable it to ensure dirty
> > > > information is not lost for the case of VGIC LPI/ITS table changes.
> > > > 
> > > > Fix this by using kvm_slot_dirty_track_enabled() instead which checks
> > > > KVM_MEM_LOG_DIRTY_PAGES.
> > > > 
> > > > Note that memslot_is_logging() also treats a memslot as not logging if
> > > > KVM_MEM_READONLY is set, hence a memslot with both dirty logging and
> > > > read only would be seen as not logging for memslot_is_logging(), but
> > > > logging for kvm_slot_dirty_track_enabled(). This allows a read only
> > > > mapping of size > PAGE_SIZE to be built when memslot_is_logging() is
> > > > used, leading to a better read performance compared to
> > > > kvm_slot_dirty_track_enabled(). However memslots that have both
> > > > KVM_MEM_LOG_DIRTY_PAGES and KVM_MEM_READONLY set do not really make
> > > > sense as dirty logging is essentially nop for a read only memslot, so
> > > > this shouldn't affect real workloads much.
> > > 
> > > 
> > > It worries me a bit that we are ignoring the KVM_MEM_READONLY flag... 
> > > I have not yet gone through the whole s2_mmu code but IIUC we can have 
> > > scenarios on which a memslot can be read-only and have dirty-logging 
> > > enabled. 
> > 
> > 
> > > If a memslot is not faulted yet, IIUC it is marked as read-only 
> > > (so it can be mapped on write fault), and we can have dirty-logging 
> > > enabled for it as well (as the VMM has no idea). 
> > > 
> > 
> > Ignore above bit, I confused memslot with block/page entry.
> > 
> > Looking a bit more, my viewpoint is that:
> > - Due to dirty_ring, checking memslot.dirty_bitmap should be done only to 
> >   detect the existence of a dirty_bitmap, not the migration process.
> > - This changes how detection works, in regardas to read-only blocks:
> >   memslot_is_logging() -> Checks dirty-bitmap + read-only memslot
> >   kvm_slot_dirty_track_enabled()  -> Checks only memslot flag
> > - As a simpler change, we could have:
> > 
> > ~~~
> > -   return memslot->dirty_bitmap && !(memslot->flags & KVM_MEM_READONLY);
> > +   return kvm_slot_dirty_track_enabled(memslot) && !(memslot->flags & KVM_MEM_READONLY);
> > ~~~
> > 
> > Both are cheking memslot->flags, so it will be probably optimized by the 
> > compiler as:
> > 
> > ~~~
> > return memslot->flags & 3 == 1
> > ~~~
> > 
> > My main worry was that in the curent patch we are changing the behavior 
> > on skipping read-only memslots. So going through the users, we can see:
> > 
> > > > 
> > > > Fixes: 9cb1096f8590 ("KVM: arm64: Enable ring-based dirty memory tracking")
> > > > Signed-off-by: Wei-Lin Chang <weilin.chang@arm.com>
> > > > ---
> > > > It took me a long investigation to acquire the context needed to
> > > > understand this change, however the reason for this problem not being
> > > > detected is an educated guess. Please let me know if this is wrong or
> > > > if there are other issues, thanks!
> > > > 
> > > >  arch/arm64/kvm/mmu.c | 11 +++--------
> > > >  1 file changed, 3 insertions(+), 8 deletions(-)
> > > > 
> > > > diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
> > > > index 4da9281312eb..06c46124d3e7 100644
> > > > --- a/arch/arm64/kvm/mmu.c
> > > > +++ b/arch/arm64/kvm/mmu.c
> > > > @@ -161,11 +161,6 @@ static int kvm_mmu_split_huge_pages(struct kvm *kvm, phys_addr_t addr,
> > > >  	return ret;
> > > >  }
> > > >  
> > > > -static bool memslot_is_logging(struct kvm_memory_slot *memslot)
> > > > -{
> > > > -	return memslot->dirty_bitmap && !(memslot->flags & KVM_MEM_READONLY);
> > > > -}
> > > > -
> > > >  /**
> > > >   * kvm_arch_flush_remote_tlbs() - flush all VM TLB entries for v7/8
> > > >   * @kvm:	pointer to kvm structure.
> > > > @@ -1748,7 +1743,7 @@ static short kvm_s2_resolve_vma_size(const struct kvm_s2_fault_desc *s2fd,
> > > >  {
> > > >  	short vma_shift;
> > > >  
> > > > -	if (memslot_is_logging(s2fd->memslot)) {
> > > > +	if (kvm_slot_dirty_track_enabled(s2fd->memslot)) {
> > > >  		s2vi->max_map_size = PAGE_SIZE;
> > > >  		vma_shift = PAGE_SHIFT;
> > > >  	} else {
> > 
> > On the case dirty_track is enabled in a read-only slot, it will resolve to 
> > a smaller vma_size. The fault granule will be smaller here. This could be 
> > bad for performance, so maybe we could add a check for read-only block 
> > here:
> > 
> > ~~~
> > -   if (memslot_is_logging(s2fd->memslot)) {
> > +   if (kvm_slot_dirty_track_enabled(s2fd->memslot) &&
> > +       !memslot_is_readonly(s2fd->memslot) {
> > ~~~
> > 
> > 
> > > > @@ -1953,7 +1948,7 @@ static int kvm_s2_fault_compute_prot(const struct kvm_s2_fault_desc *s2fd,
> > > >  	*prot = KVM_PGTABLE_PROT_R;
> > > >  
> > > >  	if (s2vi->map_writable && (s2vi->device ||
> > > > -				   !memslot_is_logging(s2fd->memslot) ||
> > > > +				   !kvm_slot_dirty_track_enabled(s2fd->memslot) ||
> > > >  				   kvm_is_write_fault(s2fd->vcpu)))
> > > >  		*prot |= KVM_PGTABLE_PROT_W;
> > > >
> > 
> > 
> > On the same scenario (dirty_track enabled on readonly memslot):
> > This one should be safe, as kvm_is_write_fault() will check if the memslot 
> > is readonly and return false in this case. But then, it will have to 
> > actually call kvm_is_write_fault(), as the previous version would not even 
> > call it in that scenario.
> > 
> > Not sure how would that impact perforformance, though.
> > 
> > > > @@ -2084,7 +2079,7 @@ static int user_mem_abort(const struct kvm_s2_fault_desc *s2fd)
> > > >  	 * and a write fault needs to collapse a block entry into a table.
> > > >  	 */
> > > >  	memcache = get_mmu_memcache(s2fd->vcpu);
> > > > -	if (!perm_fault || (memslot_is_logging(s2fd->memslot) &&
> > > > +	if (!perm_fault || (kvm_slot_dirty_track_enabled(s2fd->memslot) &&
> > > >  			    kvm_is_write_fault(s2fd->vcpu))) {
> > > >  		ret = topup_mmu_memcache(s2fd->vcpu, memcache);
> > > >  		if (ret)
> > 
> > Same thing, if memslot is tracking and is readonly, topup_*() would be 
> > called with the new patch, but not with the old behavior. 
> > 
> > All of that depends on how the VMM uses dirty_tracking: does it enable for 
> > all memory, or only for memory that is writable?
> > 
> > I could not find anything that would prevent user from enabling 
> > dirty_tracking on read-only memslots, so we can either ignore this 
> > scenario, apply those patches and let those users carry the extra overhead, 
> > or do an extra test to make sure it's doing the same thing as before.
> > 
> > Thanks!
> > Leo
> > 


^ permalink raw reply

* Re: [PATCH 1/2] nvme-apple: Only limit admin queue tag space when with Linear SQ is present
From: Nick Chan @ 2026-06-10 11:15 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Sven Peter, Janne Grunau, Neal Gompa, Keith Busch, Jens Axboe,
	Sagi Grimberg, asahi, linux-arm-kernel, linux-nvme, linux-kernel,
	stable
In-Reply-To: <20260610051146.GA559@lst.de>


Christoph Hellwig 於 2026/6/10 下午1:11 寫道:
> On Sat, Jun 06, 2026 at 09:25:25PM +0800, Nick Chan wrote:
>> Apple NVMe controllers require tags of pending commands to not be shared
>> across admin and IO queues. However, on Apple A11 without linear SQ, it is
>> not possible for either queue to skip over some tags and must go from 0 to
>> the configured maximum before wrapping around.
>>
>> As a result, in order to prevent tag collision, dynamic tag reservation
>> while a command is in-flight becomes necessary. In this context, there is
>> no reason to limit the admin queue's tag space, as it is not helpful in
>> preventing tag collision.
> I'm not really into these Apple specific, but what does
> "dynamic tag reservation" mean here?

This version is based on an incorrect premise (v2 is correct and already applied)
so feel free to stop reading.

In this version, the incorrect premise is that it was not possible for either queue
to skip over tags and must go from 0 to the configured the maximum. 

Under this premise, the only way to prevent collision is to set a bitfield indicating
which tags are in use when submitting a command ("dynamic tag reservation").
If a tag is already found to be used when submitting a command, return
BLK_STS_RESOURCE so the caller retries later.

Best regards,
Nick Chan



>


^ permalink raw reply

* Re: [PATCH v5 2/2] ARM: dts: aspeed: ventura2: Add Meta ventura2 BMC
From: Andrew Jeffery @ 2026-06-10 11:15 UTC (permalink / raw)
  To: Kyle Hsieh, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Joel Stanley
  Cc: devicetree, linux-arm-kernel, linux-aspeed, linux-kernel
In-Reply-To: <20260608-ventura2_initial_dts-v5-2-37ee5bcf58b6@gmail.com>

Hi Kyle,

On Mon, 2026-06-08 at 10:42 +0800, Kyle Hsieh wrote:
> Add linux device tree entry related to the Meta(Facebook) rmc-node.

This is redundant as it is evident from the patch itself. Can you
please remove it?

> The system use an AT2600 BMC.
> This node is named "ventura2".

Can you provide some more detail about the platform in the commit
message? What's it's purpose? Can you describe some interesting
features or details about its design?

> 
> Signed-off-by: Kyle Hsieh <kylehsieh1995@gmail.com>
> ---
>  arch/arm/boot/dts/aspeed/Makefile                  |    1 +
>  .../dts/aspeed/aspeed-bmc-facebook-ventura2.dts    | 2888 ++++++++++++++++++++
>  2 files changed, 2889 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/aspeed/Makefile b/arch/arm/boot/dts/aspeed/Makefile
> index 9adf9278dc94..6b96997629d4 100644
> --- a/arch/arm/boot/dts/aspeed/Makefile
> +++ b/arch/arm/boot/dts/aspeed/Makefile
> @@ -32,6 +32,7 @@ dtb-$(CONFIG_ARCH_ASPEED) += \
>  	aspeed-bmc-facebook-minipack.dtb \
>  	aspeed-bmc-facebook-santabarbara.dtb \
>  	aspeed-bmc-facebook-tiogapass.dtb \
> +	aspeed-bmc-facebook-ventura2.dtb \
>  	aspeed-bmc-facebook-wedge40.dtb \
>  	aspeed-bmc-facebook-wedge100.dtb \
>  	aspeed-bmc-facebook-wedge400-data64.dtb \
> diff --git a/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-ventura2.dts b/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-ventura2.dts
> new file mode 100644
> index 000000000000..9bf7d6e52e40
> --- /dev/null
> +++ b/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-ventura2.dts
> @@ -0,0 +1,2888 @@
> +// SPDX-License-Identifier: GPL-2.0
> +// Copyright (c) 2023 Facebook Inc.
> +/dts-v1/;
> +
> +#include "aspeed-g6.dtsi"
> +#include <dt-bindings/i2c/i2c.h>
> +#include <dt-bindings/gpio/aspeed-gpio.h>
> +
> +/ {
> +	model = "Facebook Ventura2 RMC";
> +	compatible = "facebook,ventura2-rmc", "aspeed,ast2600";
> 

...

> +};
> +

...

> +&gpio1 {
> +	gpio-line-names =
> +	/*18A0-18A7*/	"","","","","","","","",
> +	/*18B0-18B7*/	"","","","",
> +			"FM_BOARD_BMC_REV_ID0","FM_BOARD_BMC_REV_ID1",
> +			"FM_BOARD_BMC_REV_ID2","",
> +	/*18C0-18C7*/	"SPI_BMC_BIOS_ROM_IRQ0_R_N","","","","","","","",
> +	/*18D0-18D7*/	"","","","","","","","",
> +	/*18E0-18E3*/	"FM_BMC_PROT_LS_EN","AC_PWR_BMC_BTN_R_N","","";
> +};
> +
> +&i2c0 {
> +	status = "okay";
> +
> +	i2c-mux@77 {
> +		compatible = "nxp,pca9548";
> +		reg = <0x77>;
> +		#address-cells = <1>;
> +		#size-cells = <0>;
> +		i2c-mux-idle-disconnect;
> +
> +		i2c0mux0ch0: i2c@0 {
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +			reg = <0>;
> +		};
> +
> +		i2c0mux0ch1: i2c@1 {
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +			reg = <1>;
> +		};
> +
> +		i2c0mux0ch2: i2c@2 {
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +			reg = <2>;
> +		};
> +
> +		i2c0mux0ch3: i2c@3 {
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +			reg = <3>;
> +			status = "okay";
> +		};
> +
> +		i2c0mux0ch4: i2c@4 {
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +			reg = <4>;
> +			status = "okay";
> +		};
> +
> +		i2c0mux0ch5: i2c@5 {
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +			reg = <5>;
> +			status = "okay";
> +
> +			eeprom@56 {
> +				compatible = "atmel,24c128";
> +				reg = <0x56>;
> +			};
> +		};
> +
> +		i2c0mux0ch6: i2c@6 {
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +			reg = <6>;
> +
> +			eeprom@56 {
> +				compatible = "atmel,24c128";
> +				reg = <0x56>;
> +			};
> +
> +			fan_io_expander0: gpio@20 {
> +				compatible = "nxp,pca9555";
> +				reg = <0x20>;
> +				gpio-controller;
> +				#gpio-cells = <2>;
> +			};
> +
> +			fan_io_expander1: gpio@21 {
> +				compatible = "nxp,pca9555";
> +				reg = <0x21>;
> +				gpio-controller;
> +				#gpio-cells = <2>;
> +			};
> +
> +			adc@1d {
> +				compatible = "ti,adc128d818";
> +				reg = <0x1d>;
> +				ti,mode = /bits/ 8 <1>;
> +			};
> +
> +			adc@35 {
> +				compatible = "maxim,max11617";
> +				reg = <0x35>;
> +			};
> +		};
> +
> +		i2c0mux0ch7: i2c@7 {
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +			reg = <7>;
> +
> +			fanctl0: fan-controller@20 {
> +				compatible = "maxim,max31790";
> +				reg = <0x20>;
> +				#address-cells = <1>;
> +				#size-cells = <0>;
> +				channel@2 {

Can you make sure that you consistently use a blank line to separate
child nodes from each other and from properties in their parent?

Please fix throughout.

> +					reg = <2>;
> +					sensor-type = "TACH";
> +				};
> +				channel@5 {
> +					reg = <5>;
> +					sensor-type = "TACH";
> +				};
> +			};
> +
> +			fanctl1: fan-controller@23 {
> +				compatible = "nuvoton,nct7363";
> +				reg = <0x23>;
> +				#pwm-cells = <2>;
> +
> +				fan-9 {
> +					pwms = <&fanctl1 0 20000>;
> +					tach-ch = /bits/ 8 <0x09>;
> +				};
> +
> +				fan-11 {
> +					pwms = <&fanctl1 0 20000>;
> +					tach-ch = /bits/ 8 <0x0B>;
> +				};
> +
> +				fan-10 {
> +					pwms = <&fanctl1 4 20000>;
> +					tach-ch = /bits/ 8 <0x0A>;
> +				};
> +
> +				fan-13 {
> +					pwms = <&fanctl1 4 20000>;
> +					tach-ch = /bits/ 8 <0x0D>;
> +				};
> +
> +				fan-15 {
> +					pwms = <&fanctl1 6 20000>;
> +					tach-ch = /bits/ 8 <0x0F>;
> +				};
> +
> +				fan-1 {

Can you please sort the fan nodes in ascending order?

> +					pwms = <&fanctl1 6 20000>;
> +					tach-ch = /bits/ 8 <0x01>;
> +				};
> +
> +				fan-0 {
> +					pwms = <&fanctl1 10 20000>;
> +					tach-ch = /bits/ 8 <0x00>;
> +				};
> +
> +				fan-3 {
> +					pwms = <&fanctl1 10 20000>;
> +					tach-ch = /bits/ 8 <0x03>;
> +				};
> +			};
> +		};
> +	};
> +};
> 

...

> +
> +	// Marvell 88E6393X EEPROM

Please try to be consistent with the comment style (prefer /* */).

> +	eeprom@50 {
> +		compatible = "atmel,24c64";
> +		reg = <0x50>;
> +	};
> +
> +	rtc@51 {
> +		compatible = "nxp,pcf8563";
> +		reg = <0x51>;
> +	};
> +};
> +


^ permalink raw reply

* Re: [PATCH] perf: arm64: Replace symlink with actual file for syscall_64.tbl
From: Leo Yan @ 2026-06-10 10:59 UTC (permalink / raw)
  To: john.song
  Cc: linux-perf-users, acme, peterz, namhyung, john.g.garry, will,
	linux-arm-kernel
In-Reply-To: <AHMAuwBaMCb7DmUcFDGOhqrg.1.1781071552750.Hmail.john.song@ucloud.cn>

On Wed, Jun 10, 2026 at 02:05:52PM +0800, john.song wrote:

[...]

> The file tools/perf/arch/arm64/entry/syscalls/syscall_64.tbl is a
> symbolic link pointing to ../../../../../scripts/syscall.tbl.
> 
> This causes build failures in environments where the source tree is
> copied to a different location, such as RPM buildroots, where relative
> symlinks may become invalid.

What command did you use to copy it to a different location?

Could you confirm whether you can reproduce the issue using
"make perf-tarxz-src-pkg"?

Thanks,
Leo


^ permalink raw reply

* Re: [PATCH 2/3] soc: samsung: exynos-pmu: fix use-after-free of interrupt generator node
From: Peter Griffin @ 2026-06-10 10:58 UTC (permalink / raw)
  To: Alexey Klimov
  Cc: Krzysztof Kozlowski, Alim Akhtar, Sam Protsenko,
	linux-samsung-soc, linux-arm-kernel, linux-kernel, stable,
	Sashiko
In-Reply-To: <20260605-exynos-pmu-cpuhp-idle-fixes-v1-2-0cd05c81a82d@linaro.org>

Hi Alexey,

Thanks for your patch.

On Fri, 5 Jun 2026 at 21:19, Alexey Klimov <alexey.klimov@linaro.org> wrote:
>
> The setup_cpuhp_and_cpuidle() parses the device tree node for the
> interrupt generation block via of_parse_phandle() and decrements its
> reference count using of_node_put() immediately after fetching the resource
> address. However, later the intr_gen_node pointer is passed into
> of_syscon_register_regmap().
>
> Fix this by moving the of_node_put() invocation to after the
> of_syscon_register_regmap() call, and adding it to correct error paths.

I think  using
__free(device_node) = of_parse_phandle

would be a cleaner/simpler fix.

Peter




Peter.

>
> Reported-by: Sashiko <sashiko-bot@kernel.org>
> Closes: https://sashiko.dev/#/patchset/20260513-exynos850-cpuhotplug-v4-0-54fec5f65362@linaro.org?part=3
> Fixes: 78b72897a5c8 ("soc: samsung: exynos-pmu: Enable CPU Idle for gs101")
> Cc: stable@vger.kernel.org
> Signed-off-by: Alexey Klimov <alexey.klimov@linaro.org>
> ---
>  drivers/soc/samsung/exynos-pmu.c | 11 +++++++++--
>  1 file changed, 9 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/soc/samsung/exynos-pmu.c b/drivers/soc/samsung/exynos-pmu.c
> index 6e635872247a..9636287f6794 100644
> --- a/drivers/soc/samsung/exynos-pmu.c
> +++ b/drivers/soc/samsung/exynos-pmu.c
> @@ -428,23 +428,30 @@ static int setup_cpuhp_and_cpuidle(struct device *dev)
>          * syscon provided regmap.
>          */
>         ret = of_address_to_resource(intr_gen_node, 0, &intrgen_res);
> -       of_node_put(intr_gen_node);
> +       if (ret) {
> +               of_node_put(intr_gen_node);
> +               return ret;
> +       }
>
>         virt_addr = devm_ioremap(dev, intrgen_res.start,
>                                  resource_size(&intrgen_res));
> -       if (!virt_addr)
> +       if (!virt_addr) {
> +               of_node_put(intr_gen_node);
>                 return -ENOMEM;
> +       }
>
>         pmu_context->pmuintrgen = devm_regmap_init_mmio(dev, virt_addr,
>                                                         &regmap_pmu_intr);
>         if (IS_ERR(pmu_context->pmuintrgen)) {
>                 dev_err(dev, "failed to initialize pmu-intr-gen regmap\n");
> +               of_node_put(intr_gen_node);
>                 return PTR_ERR(pmu_context->pmuintrgen);
>         }
>
>         /* register custom mmio regmap with syscon */
>         ret = of_syscon_register_regmap(intr_gen_node,
>                                         pmu_context->pmuintrgen);
> +       of_node_put(intr_gen_node);
>         if (ret)
>                 return ret;
>
>
> --
> 2.51.0
>


^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox