Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* Re: [PATCH v2 2/2] gpio: xilinx: drop bitmap_complement() where feasible
From: Michal Simek @ 2026-04-21 13:44 UTC (permalink / raw)
  To: Yury Norov, Linus Walleij, Andy Shevchenko, Bartosz Golaszewski,
	Shubhrajyoti Datta, Srinivas Neeli, Yury Norov, linux-gpio,
	linux-kernel, linux-arm-kernel
In-Reply-To: <20260417175955.375275-3-ynorov@nvidia.com>



On 4/17/26 19:59, Yury Norov wrote:
> [Some people who received this message don't often get email from ynorov@nvidia.com. Learn why this is important at https://aka.ms/LearnAboutSenderIdentification ]
> 
> The drivers reproduces the following pattern:

The driver reproduce

With that fix
  Reviewed-by: Michal Simek <michal.simek@amd.com>

Thanks,
Michal



^ permalink raw reply

* Re: [PATCH v3 1/3] dt-bindings: power: Add power-domains-child-ids property
From: Rob Herring @ 2026-04-21 13:49 UTC (permalink / raw)
  To: Kevin Hilman (TI)
  Cc: Ulf Hansson, Geert Uytterhoeven, linux-pm, devicetree,
	linux-kernel, arm-scmi, linux-arm-kernel
In-Reply-To: <20260420-topic-lpm-pmdomain-child-ids-v3-1-c2c40bef238c@baylibre.com>

On Mon, Apr 20, 2026 at 04:51:17PM -0700, Kevin Hilman (TI) wrote:
> Add binding documentation for the new power-domains-child-ids property,
> which works in conjunction with the existing power-domains property to
> establish parent-child relationships between a multi-domain power domain
> provider and external parent domains.
> 
> Each element in the uint32 array identifies the child domain
> ID (index) within the provider that should be made a child domain of
> the corresponding phandle entry in power-domains. The two arrays must
> have the same number of elements.
> 
> Signed-off-by: Kevin Hilman (TI) <khilman@baylibre.com>

Missing my Reviewed-by.


^ permalink raw reply

* [GIT PULL] amlogic ARM64 DT fixes for v7.1-rc
From: Neil Armstrong @ 2026-04-21 13:52 UTC (permalink / raw)
  To: soc, arm; +Cc: linux-amlogic, linux-arm-kernel

Hi,

Here's the Amlogic ARM64 DT fixes for v7.1-rc, including a bunch of fixes
for the Khadas VIM4 and a couple of low priority fixes.

Thanks,
Neil

The following changes since commit 028ef9c96e96197026887c0f092424679298aae8:

   Linux 7.0 (2026-04-12 13:48:06 -0700)

are available in the Git repository at:

   https://git.kernel.org/pub/scm/linux/kernel/git/amlogic/linux.git tags/amlogic-fixes-v7.1-rc

for you to fetch changes up to 174a0ef3b33434f475c87e66f37980e39b73805a:

   arm64: dts: meson-gxl-p230: fix ethernet PHY interrupt number (2026-04-21 15:46:29 +0200)

----------------------------------------------------------------
Amlogic DT Fixes for v7.1:
- Fix ethernet PHY interrupt number for P230 reference board
- Add missing cache information to cpu0 for Amlogic AXG
- Fix Khadas VIM4 board model name
- Fix GIC register ranges for Amlogic T7
- Fix Khadas VIM4 memory layout for 8GB RAM
- Drop CPU masks from GICv3 PPI interrupts for Amlogic S6

----------------------------------------------------------------
Anand Moon (1):
       arm64: dts: amlogic: meson-axg: Add missing cache information to cpu0

Geert Uytterhoeven (1):
       arm64: dts: amlogic: s6: Drop CPU masks from GICv3 PPI interrupts

Jun Yan (1):
       arm64: dts: meson-gxl-p230: fix ethernet PHY interrupt number

Nick Xie (2):
       arm64: dts: amlogic: t7: khadas-vim4: fix memory layout for 8GB RAM
       arm64: dts: amlogic: t7: khadas-vim4: fix board model name

Ronald Claveau (1):
       arm64: dts: amlogic: Fix GIC register ranges for Amlogic T7

  arch/arm64/boot/dts/amlogic/amlogic-s6.dtsi                   | 10 +++++-----
  arch/arm64/boot/dts/amlogic/amlogic-t7-a311d2-khadas-vim4.dts |  6 ++++--
  arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi                   |  4 +++-
  arch/arm64/boot/dts/amlogic/meson-axg.dtsi                    |  6 ++++++
  arch/arm64/boot/dts/amlogic/meson-gxl-s905d-p230.dts          |  3 ++-
  5 files changed, 20 insertions(+), 9 deletions(-)


^ permalink raw reply

* Re: [PATCH v3 1/3] dt-bindings: gpio: zynq: Sort compatible strings alphabetically
From: Rob Herring @ 2026-04-21 13:52 UTC (permalink / raw)
  To: Shubhrajyoti Datta
  Cc: linux-kernel, git, shubhrajyoti.datta, Srinivas Neeli,
	Michal Simek, Linus Walleij, Bartosz Golaszewski,
	Krzysztof Kozlowski, Conor Dooley, linux-gpio, devicetree,
	linux-arm-kernel
In-Reply-To: <20260421104358.2496125-2-shubhrajyoti.datta@amd.com>

On Tue, Apr 21, 2026 at 04:13:56PM +0530, Shubhrajyoti Datta wrote:
> Sort the compatible string alphabetically.
> 
> Signed-off-by: Shubhrajyoti Datta <shubhrajyoti.datta@amd.com>

Missing Conor's ack.


^ permalink raw reply

* [PATCH v13 00/48] arm64: Support for Arm CCA in KVM
From: Jiahao zheng @ 2026-04-21 13:51 UTC (permalink / raw)
  To: steven.price
  Cc: alexandru.elisei, alpergun, aneesh.kumar, catalin.marinas,
	christoffer.dall, fj0570is, gankulkarni, gshan, james.morse,
	joey.gouly, kvm, kvmarm, linux-arm-kernel, linux-coco,
	linux-kernel, maz, oliver.upton, sdonthineni, suzuki.poulose,
	tabba, vannapurve, will, yuzenghui
In-Reply-To: <20260318155413.793430-1-steven.price@arm.com>

Hi Steven,

I've been testing CCA patch series and noticed Realm VM cannot boot successfully when the host is forced to run in nVHE mode (e.g., via `kvm-arm.mode=nvhe`). The kvmtool debug information will be truncated in set_guest_bank_private_gpa. 

Currently, in `kvm_ioctl_vcpu_run()`, running a Realm VM (REC) bypasses the standard nVHE EL2 stub. `kvm_rec_enter()` directly executes the SMC instruction to transition to the RMM. Upon returning to the EL1 host, the code falls back to `kvm_vgic_sync_hwstate()`, where the VGIC save operation is explicitly skipped for nVHE. Since the EL2 stub was bypassed, `__vgic_v3_save_state()` is never executed, and `ICH_*_EL2` states are lost.

To resolve this, I have a couple of thoughts:
1. If Host nVHE mode is not intended to be supported for Realms:
Since RME implies ARMv9 which mandates VHE, running a Realm with an nVHE host might just be an unsupported edge case. If so, we should explicitly reject RME initialization or REC creation when `!is_kernel_in_hyp_mode()`. This would cleanly prevent the undefined behavior.
2. If Host nVHE mode is intended to be supported:
Since RMM should remain agnostic to the Non-Secure VGIC states, the burden of saving these states falls strictly on KVM. However, the EL1 host cannot access `ICH_*_EL2`. Therefore, KVM needs to add specific logic for this scenario. We would likely need to route the REC exit through a dedicated nVHE EL2 stub to invoke `__vgic_v3_save_state()` before dropping back to EL1, rather than jumping straight back to `kvm_ioctl_vcpu_run()`.

I might have missed some documentation or comments regarding nVHE restrictions for CCA. If this is an oversight, it would be great to see a check added in the next iteration of the series.


Thanks,
Zheng


^ permalink raw reply

* Re: [PATCH bpf-next 2/3] bpf, arm64: Add JIT support for stack arguments
From: Alexei Starovoitov @ 2026-04-21 13:53 UTC (permalink / raw)
  To: Puranjay Mohan
  Cc: bpf, Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko,
	Martin KaFai Lau, Eduard Zingerman, Kumar Kartikeya Dwivedi,
	Song Liu, Yonghong Song, Xu Kuohai, Catalin Marinas, Will Deacon,
	linux-arm-kernel
In-Reply-To: <CANk7y0gNqm7U_0Kc6ZP9jd19gHKScOaTVDa4yxkxTVDonM0iUA@mail.gmail.com>

On Tue, Apr 21, 2026 at 4:53 AM Puranjay Mohan <puranjay12@gmail.com> wrote:
>
> On Tue, Apr 21, 2026 at 3:58 AM Alexei Starovoitov
> <alexei.starovoitov@gmail.com> wrote:
> >
> > On Mon, Apr 20, 2026 at 8:36 AM Puranjay Mohan <puranjay@kernel.org> wrote:
> > >
> >
> > nice and clean. I like how it maps to arm64 calling convention.
> >
> > > +       if (prog->aux->stack_arg_depth > prog->aux->incoming_stack_arg_depth) {
> > > +               u16 outgoing = prog->aux->stack_arg_depth - prog->aux->incoming_stack_arg_depth;
> > > +               int nr_on_stack = outgoing / sizeof(u64) - NR_STACK_ARG_REGS;
> > > +
> > > +               if (nr_on_stack > 0)
> > > +                       ctx.stack_arg_size = round_up(nr_on_stack * sizeof(u64), 16);
> > > +       }
> >
> > I'm struggling to understand this part.
> > Why do this when this func calls more than what callee passed in?
> > Looks fishy. I'd like to see selftests with more than 6,7,8 args.
> > Because only then this logic will kick in?
>
> Your confusion stems from the naming of "incoming_stack_arg_depth" and
> "stack_arg_depth" (this should be called total_stack_arg_depth in my
> opinion)
>
> So, if you see fixups.c
>
>                 func[i]->aux->incoming_stack_arg_depth =
> env->subprog_info[i].incoming_stack_arg_depth;
>                 func[i]->aux->stack_arg_depth =
> env->subprog_info[i].incoming_stack_arg_depth +
>
> env->subprog_info[i].outgoing_stack_arg_depth;
>
> prog->aux->stack_arg_depth doesn't store outgoing stack depth, rather
> it has the sum of both incoming and outgoing, that means if a func
> doesn't call any function with more than 5 arguments but receives more
> than five arguments, incoming_stack_arg_depth will be equal to
> stack_arg_depth.

Ohh. That's indeed all too confusing.
See my response to Yonghong.
I think stack_arg_depth should mean outgoing
and incoming_stack_arg_depth should mean incoming only and
it shouldn't be even used by JIT.
That memory was allocated by caller, so to JIT this callee
the conversion of r11+const is straightforward and no checks necessary.

> if (prog->aux->stack_arg_depth > prog->aux->incoming_stack_arg_depth)
>
> This check is for - "Does this function call any function with more
> than 5 arguments", if yes, is it more than 8? if yes allocate stack
> space, otherwise stack space is not needed because argument 6,7,8 can
> live in arm64 registers.

I think it should really be one check based on stack_arg_depth.


^ permalink raw reply

* Re: [PATCH v5 07/12] coresight: etm4x: fix inconsistencies with sysfs configuration
From: Yeoreum Yun @ 2026-04-21 14:02 UTC (permalink / raw)
  To: Leo Yan
  Cc: coresight, linux-arm-kernel, linux-kernel, suzuki.poulose,
	mike.leach, james.clark, alexander.shishkin, jie.gan
In-Reply-To: <20260421132842.GC929984@e132581.arm.com>

Hi Leo,

> On Tue, Apr 21, 2026 at 12:14:20PM +0100, Yeoreum Yun wrote:
>
> [...]
>
> > > >   - There is a risk of corrupting drvdata->config if a perf session enables
> > > >     tracing while cscfg_csdev_disable_active_config() is being handled in
> > > >     etm4_disable_sysfs().
> > >
> > > Similiar to above, cscfg_csdev_disable_active_config() is not
> > > protected in etm4_disable_sysfs().
> >
> > This is not true.
> > at the time of etm4_disable_sysfs() "mode" is already taken
> > (whether sysfs or perf). In this situation, it's enough to
> > call cscfg_csdev_disable_active_config() before chaning
> > mode to DISABLED.
>
> To be clear, I am trying to understand issue _before_ your patch.
> Without this patch, cscfg_csdev_disable_active_config() is not
> protected by the mode.

Right.

[...]

> > > > @@ -1386,6 +1401,7 @@ static void etm4_init_arch_data(void *info)
> > > >  	drvdata = dev_get_drvdata(init_arg->dev);
> > > >  	caps = &drvdata->caps;
> > > >  	csa = init_arg->csa;
> > > > +	config = &drvdata->active_config;
> > >
> > > Should we init drvdata->config instead so make it has sane values ?
> > >
> > > In other words, drvdata->active_config are always set at the runtime,
> > > so don't need to init it at all, right?
> >
> > No. at least when the initialise, I think we should fill the its
> > contesnt with the "etm4_set_default()".
> >
> > That's why the consequence call etm4_set_default() called with
> > active_config and config is coped with the default configutation.
>
> I'm concerned that some config fields may be reused across sessions.
> For example, a sysfs session copies drvdata->config into
> drvdata->active_config, and later a perf session may reuse stale
> values. The same issue can happen in the reverse direction.
>
> A clean approach would be to treat drvdata->active_config as
> per-session state:
>
>   1) clear drvdata->active_config at session start
>   2) apply the session-specific config
>      2.1) sysfs: use drvdata->config
>      2.2) perf: use event config

>   3) then apply configfs configuration
This is not true.

In case of "perf", it always clear the "active_config" with 0x00
before enable. so it wouldn't.

In case of sysfs we don't need to worries about since
"config" field saves everything and this is applied into active_config.

So, your issue doesn't exist in this case.



--
Sincerely,
Yeoreum Yun


^ permalink raw reply

* Re: [PATCH 0/4] Add hstimer support for H616 and T113-S3
From: Michal Piekos @ 2026-04-21 14:05 UTC (permalink / raw)
  To: Andre Przywara
  Cc: Daniel Lezcano, Thomas Gleixner, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Chen-Yu Tsai, Jernej Skrabec, Samuel Holland,
	Maxime Ripard, linux-kernel, devicetree, linux-arm-kernel,
	linux-sunxi
In-Reply-To: <b89c1c8b-2678-4f4f-a63c-03b92cf7617c@arm.com>

On Mon, Apr 20, 2026 at 04:14:44PM +0200, Andre Przywara wrote:
> Hi Michal,
> 
> On 4/20/26 13:27, Michal Piekos wrote:
> > On Sun, Apr 19, 2026 at 10:55:39PM +0200, Andre Przywara wrote:
> > > On Sun, 19 Apr 2026 14:46:06 +0200
> > > Michal Piekos <michal.piekos@mmpsystems.pl> wrote:
> > > 
> > > Hi Michal,
> > > 
> > > > Add support for Allwinner H616 high speed timer in sun5i hstimer driver
> > > > and describe corresponding nodes in dts for H616 and T113-S3.
> > > > 
> > > > H616 uses same model as existing driver except register shift compared
> > > > to older variants.
> > > > 
> > > > Added register layout abstraction in the driver, extended the binding
> > > > with new compatibles and wired up dts nodes for H616 and T113-S3 which
> > > > uses H616 as fallback compatible.
> > > 
> > > Can you say *why* we need this? IIUC Linux only ever uses one clock
> > > source, and selects the (non-optional) Generic Timer (aka arch timer)
> > > for that? So can you say what this hstimer clock source adds? I guess
> > > higher resolution, but what is your use case, so why would you need the
> > > 200 MHz? And does this offset the higher access cost of an MMIO
> > > access, compared to the arch timer's sysreg based access? Also, IIUC,
> > > people would need to manually select this as the clocksource, why and
> > > when would they do so? (Given they even know about it in the first
> > > place).
> > > Also the hstimer hasn't been used since the A20, so nobody seemed to
> > > have missed it meanwhile?
> > > 
> > > Cheers,
> > > Andre
> > > 
> > I took the table from https://linux-sunxi.org/Linux_mainlining_effort as
> > a todo list and wanted to help with it. I do not have own use case for
> > this timer. If it is not needed then I will spin v2 to include your
> > comments and abandon it.
> 
> Ah, that's good to know, and thanks for picking things from that list! I
> don't think there is a particular need to abandon your work, we could as
> well upstream it. At least the DT changes should be added, so that other DT
> users could make use of the timers - after all it's a Linux implementation
> choice to utilise just one timer. But please go ahead and post a complete
> v2, I don't think it hurts to have HSTIMER support in the kernel.
> And while you are at it: can you figure out what the need is for using two
> timers? One is a clock source, the other is for clock events? And why do we
> limit the counters and timers to 32 bit? Even the A13 manual lists them as
> 56 bits, and a wraparound time of roughly 21 seconds (with 32 bit counters)
> does not sound very long to me.
> 
Yes. Channel 0 is clockevent and channel 1 is a clocksource and sync
reference for channel 0 disable timing. 

32 bit counters seems like implementation choice rather than limitation
but that would need to be implemented and tested. Would you suggest to
extend it to 56 bit in the following patch?

> 
> Not sure what your primary motivation for fixing Allwinner support is, but
> we could probably find more worthwhile targets. Do you have Allwinner boards
> other than the OrangePi Zero 3? There are not many low hanging fruits on the
> H616 left (MBUS and LDOs(?) maybe), but the A523 has quite some missing
> drivers still, some of them probably more on the easy side.
> 
I have boards with A733, A527, T113-S3, H616, H6, H3 and I
think some older stuff too. My motivation is mostly fun and learning.
I also use those boards in custom projects.

I will take up GPADC on A527 after finishing this as I worked with ADC's
a lot on MCU's. Unless other suggestions?

Thank you for comments.
Michal

> If you are stuck with the OpiZero3, then you could just look and check the
> existing devices, and verify their operation. For instance I think USB-OTG
> is still broken - across most Allwinner SoCs actually, so it's a sunxi
> driver issue.
> 
> Thanks,
> Andre
> 
> > 
> > Michal
> > 
> > > > 
> > > > Signed-off-by: Michal Piekos <michal.piekos@mmpsystems.pl>
> > > > ---
> > > > Michal Piekos (4):
> > > >        dt-bindings: timer: allwinner,sun5i-a13-hstimer: add H616 and T113-S3
> > > >        clocksource/drivers/sun5i: add H616 hstimer support
> > > >        arm64: dts: allwinner: h616: add hstimer node
> > > >        arm: dts: allwinner: t113s: add hstimer node
> > > > 
> > > >   .../timer/allwinner,sun5i-a13-hstimer.yaml         |  8 +++-
> > > >   arch/arm/boot/dts/allwinner/sun8i-t113s.dtsi       | 12 +++++
> > > >   arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi     |  9 ++++
> > > >   drivers/clocksource/timer-sun5i.c                  | 56 +++++++++++++++++++---
> > > >   4 files changed, 78 insertions(+), 7 deletions(-)
> > > > ---
> > > > base-commit: faeab166167f5787719eb8683661fd41a3bb1514
> > > > change-id: 20260413-h616-t113s-hstimer-62939948f91c
> > > > 
> > > > Best regards,
> > > 
> > > 
> 
> 


^ permalink raw reply

* Re: [PATCH v2 2/2] arm64: dts: add tqma9596la-mba95xxca
From: Alexander Stein @ 2026-04-21 14:09 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Frank Li,
	Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam,
	Geert Uytterhoeven, Magnus Damm, Shawn Guo
  Cc: Markus Niebel, devicetree, linux-kernel, imx, linux-arm-kernel,
	linux, linux-renesas-soc
In-Reply-To: <20260326111803.1248934-2-alexander.stein@ew.tq-group.com>

Hi,

Am Donnerstag, 26. März 2026, 12:03:30 CEST schrieb Alexander Stein:
> From: Markus Niebel <Markus.Niebel@ew.tq-group.com>
> 
> This adds support for TQMa95xxLA modules, designed to be soldered
> on a carrier board. MBa95xxCA is a carrier reference board / starter kit
> design.
> 
> There is a common device tree for all variants with e.g. reduced
> CPU core / feature count.
> 
> Enable the external accessible PCIe controllers as host,
> add clocking and reset GPIO. While at it, add hogs for GPIO
> lines from the M.2 slots until M.2 connector driver is available.
> 
> Signed-off-by: Markus Niebel <Markus.Niebel@ew.tq-group.com>
> Signed-off-by: Alexander Stein <alexander.stein@ew.tq-group.com>

Any feedback on this? Patch 1 is already picked in commit d44627c13049e
("dt-bindings: arm: add bindings for TQMa95xxLA")

Thank and best regards,
Alexander

> ---
> Changes in v2:
> * removed useless regulator
> * added USB PD source configuration
> * Removed unused uart-has-rtscts properties (unused by LPUART)
> * Fixed RTS/CTS pullups in pinctrl
> * Added thermalzone on module
> 
>  arch/arm64/boot/dts/freescale/Makefile        |   1 +
>  .../freescale/imx95-tqma9596la-mba95xxca.dts  | 947 ++++++++++++++++++
>  .../boot/dts/freescale/imx95-tqma9596la.dtsi  | 297 ++++++
>  3 files changed, 1245 insertions(+)
>  create mode 100644 arch/arm64/boot/dts/freescale/imx95-tqma9596la-mba95xxca.dts
>  create mode 100644 arch/arm64/boot/dts/freescale/imx95-tqma9596la.dtsi
> 
> diff --git a/arch/arm64/boot/dts/freescale/Makefile b/arch/arm64/boot/dts/freescale/Makefile
> index 2879d567dede0..df79e56771319 100644
> --- a/arch/arm64/boot/dts/freescale/Makefile
> +++ b/arch/arm64/boot/dts/freescale/Makefile
> @@ -554,6 +554,7 @@ dtb-$(CONFIG_ARCH_MXC) += imx95-15x15-frdm.dtb
>  dtb-$(CONFIG_ARCH_MXC) += imx95-19x19-evk.dtb
>  dtb-$(CONFIG_ARCH_MXC) += imx95-19x19-evk-sof.dtb
>  dtb-$(CONFIG_ARCH_MXC) += imx95-toradex-smarc-dev.dtb
> +dtb-$(CONFIG_ARCH_MXC) += imx95-tqma9596la-mba95xxca.dtb
>  dtb-$(CONFIG_ARCH_MXC) += imx95-tqma9596sa-mb-smarc-2.dtb
>  dtb-$(CONFIG_ARCH_MXC) += imx95-var-dart-sonata.dtb
>  
> diff --git a/arch/arm64/boot/dts/freescale/imx95-tqma9596la-mba95xxca.dts b/arch/arm64/boot/dts/freescale/imx95-tqma9596la-mba95xxca.dts
> new file mode 100644
> index 0000000000000..f75580bb91e3e
> --- /dev/null
> +++ b/arch/arm64/boot/dts/freescale/imx95-tqma9596la-mba95xxca.dts
> @@ -0,0 +1,947 @@
> +// SPDX-License-Identifier: (GPL-2.0-or-later OR MIT)
> +/*
> + * Copyright (c) 2024-2026 TQ-Systems GmbH <linux@ew.tq-group.com>,
> + * D-82229 Seefeld, Germany.
> + * Author: Alexander Stein
> + * Author: Markus Niebel
> + */
> +
> +/dts-v1/;
> +
> +#include <dt-bindings/leds/common.h>
> +#include <dt-bindings/net/ti-dp83867.h>
> +#include <dt-bindings/pwm/pwm.h>
> +#include <dt-bindings/usb/pd.h>
> +#include "imx95-tqma9596la.dtsi"
> +
> +/ {
> +	model = "TQ-Systems i.MX95 TQMa95xxLA on MBa95xxCA";
> +	compatible = "tq,imx95-tqma9596la-mba95xxca", "tq,imx95-tqma9596la", "fsl,imx95";
> +	chassis-type = "embedded";
> +
> +	aliases {
> +		ethernet0 = &enetc_port0;
> +		ethernet1 = &enetc_port1;
> +		ethernet2 = &enetc_port2;
> +		gpio0 = &gpio1;
> +		gpio1 = &gpio2;
> +		gpio2 = &gpio3;
> +		gpio3 = &gpio4;
> +		i2c0 = &lpi2c1;
> +		i2c1 = &lpi2c2;
> +		i2c2 = &lpi2c3;
> +		i2c3 = &lpi2c4;
> +		i2c4 = &lpi2c5;
> +		i2c5 = &lpi2c6;
> +		i2c6 = &lpi2c7;
> +		i2c7 = &lpi2c8;
> +		mmc0 = &usdhc1;
> +		mmc1 = &usdhc2;
> +		rtc0 = &pcf85063;
> +		rtc1 = &scmi_bbm;
> +		serial0 = &lpuart1;
> +		serial1 = &lpuart2;
> +		serial2 = &lpuart3;
> +		serial3 = &lpuart4;
> +		serial4 = &lpuart5;
> +		serial5 = &lpuart6;
> +		serial6 = &lpuart7;
> +		serial7 = &lpuart8;
> +		spi0 = &flexspi1;
> +	};
> +
> +	chosen {
> +		stdout-path = &lpuart1;
> +	};
> +
> +	backlight_lvds: backlight-lvds {
> +		compatible = "pwm-backlight";
> +		pwms = <&tpm5 2 100000 0>;
> +		brightness-levels = <0 4 8 16 32 64 128 255>;
> +		default-brightness-level = <7>;
> +		enable-gpios = <&expander2 6 GPIO_ACTIVE_HIGH>;
> +		power-supply = <&reg_12v0>;
> +		status = "disabled";
> +	};
> +
> +	clk_eth: clk-eth {
> +		compatible = "fixed-clock";
> +		#clock-cells = <0>;
> +		clock-frequency = <156250000>;
> +	};
> +
> +	/*
> +	 * TODO: gate is disabled for now and GPIO are hogged
> +	 * ENETC driver switches the clock far too late for ENETC2 + SFP
> +	 */
> +	clk_eth_gate: clk-eth-gate {
> +		compatible = "gpio-gate-clock";
> +		enable-gpios = <&expander2 0 GPIO_ACTIVE_HIGH>;
> +		clocks = <&clk_eth>;
> +		#clock-cells = <0>;
> +		status = "disabled";
> +	};
> +
> +	clk_xtal25: clk-xtal25 {
> +		compatible = "fixed-clock";
> +		#clock-cells = <0>;
> +		clock-frequency = <25000000>;
> +	};
> +
> +	gpio-keys {
> +		compatible = "gpio-keys";
> +		autorepeat;
> +
> +		button-b {
> +			label = "BUTTON_B#";
> +			linux,code = <BTN_1>;
> +			gpios = <&expander1 0 GPIO_ACTIVE_LOW>;
> +			wakeup-source;
> +		};
> +	};
> +
> +	gpio-leds {
> +		compatible = "gpio-leds";
> +
> +		led-1 {
> +			color = <LED_COLOR_ID_GREEN>;
> +			function = LED_FUNCTION_STATUS;
> +			gpios = <&expander2 13 GPIO_ACTIVE_HIGH>;
> +			linux,default-trigger = "default-on";
> +		};
> +
> +		led-2 {
> +			color = <LED_COLOR_ID_AMBER>;
> +			function = LED_FUNCTION_HEARTBEAT;
> +			gpios = <&expander2 14 GPIO_ACTIVE_HIGH>;
> +			linux,default-trigger = "heartbeat";
> +		};
> +	};
> +
> +	iio-hwmon {
> +		compatible = "iio-hwmon";
> +		io-channels = <&adc1 0>, <&adc1 1>, <&adc1 2>, <&adc1 3>,
> +			      <&adc1 4>, <&adc1 5>, <&adc1 6>, <&adc1 7>;
> +	};
> +
> +	reg_v1v8_mb: regulator-v1v8-mb {
> +		compatible = "regulator-fixed";
> +		regulator-name = "V_1V8_MB";
> +		regulator-min-microvolt = <1800000>;
> +		regulator-max-microvolt = <1800000>;
> +		regulator-always-on;
> +	};
> +
> +	reg_v3v3_mb: regulator-v3v3-mb {
> +		compatible = "regulator-fixed";
> +		regulator-name = "V_3V3_MB";
> +		regulator-min-microvolt = <3300000>;
> +		regulator-max-microvolt = <3300000>;
> +		regulator-always-on;
> +	};
> +
> +	reg_3v3a_10g: regulator-3v3a-10g {
> +		compatible = "regulator-fixed";
> +		regulator-name = "3V3A_10G";
> +		regulator-min-microvolt = <3300000>;
> +		regulator-max-microvolt = <3300000>;
> +		gpio = <&expander2 15 GPIO_ACTIVE_HIGH>;
> +		startup-delay-us = <2000>;
> +		enable-active-high;
> +	};
> +
> +	reg_12v0: regulator-12v0 {
> +		compatible = "regulator-fixed";
> +		regulator-name = "12V0";
> +		regulator-min-microvolt = <12000000>;
> +		regulator-max-microvolt = <12000000>;
> +		gpio = <&expander1 15 GPIO_ACTIVE_HIGH>;
> +		enable-active-high;
> +	};
> +
> +	reg_pwm_fan: regulator-pwm-fan {
> +		compatible = "regulator-fixed";
> +		regulator-name = "FAN_PWR";
> +		regulator-min-microvolt = <12000000>;
> +		regulator-max-microvolt = <12000000>;
> +		gpio = <&expander3 15 GPIO_ACTIVE_HIGH>;
> +		enable-active-high;
> +		vin-supply = <&reg_12v0>;
> +	};
> +
> +	reg_lvds: regulator-lvds {
> +		compatible = "regulator-fixed";
> +		regulator-name = "LCD_PWR_EN";
> +		regulator-min-microvolt = <3300000>;
> +		regulator-max-microvolt = <3300000>;
> +		gpio = <&expander2 7 GPIO_ACTIVE_HIGH>;
> +		enable-active-high;
> +	};
> +
> +	/* USB NC limitations, RM 162.1.2 VBUS limitations */
> +	reg_vbus_usb3: regulator-vbus-usb3 {
> +		compatible = "regulator-fixed";
> +		regulator-min-microvolt = <5000000>;
> +		regulator-max-microvolt = <5000000>;
> +		regulator-name = "USB3_VBUS";
> +		gpio = <&gpio4 1 GPIO_ACTIVE_HIGH>;
> +		enable-active-high;
> +	};
> +
> +	sfp_xfi: sfp-xfi {
> +		compatible = "sff,sfp";
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&pinctrl_sfp>;
> +		i2c-bus = <&lpi2c7>;
> +		maximum-power-milliwatt = <2000>;
> +		mod-def0-gpios = <&expander1 3 GPIO_ACTIVE_LOW>;
> +		tx-fault-gpios = <&gpio2 30 GPIO_ACTIVE_HIGH>;
> +		los-gpios = <&gpio2 31 GPIO_ACTIVE_HIGH>;
> +		tx-disable-gpios = <&expander2 2 GPIO_ACTIVE_HIGH>;
> +	};
> +
> +	sound {
> +		compatible = "fsl,imx-audio-tlv320aic32x4";
> +		model = "tqm-tlv320aic32";
> +		audio-codec = <&tlv320aic3x04>;
> +		audio-cpu = <&sai3>;
> +		audio-routing =
> +			"IN3_L", "Mic Jack",
> +			"Mic Jack", "Mic Bias",
> +			"Headphone Jack", "HPL",
> +			"Headphone Jack", "HPR",
> +			"IN1_L", "Line In Jack",
> +			"IN1_R", "Line In Jack",
> +			"Line Out Jack", "LOL",
> +			"Line Out Jack", "LOR";
> +	};
> +};
> +
> +&adc1 {
> +	status = "okay";
> +};
> +
> +&enetc_port0 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pinctrl_enetc0>;
> +	phy-handle = <&ethphy0>;
> +	phy-mode = "rgmii-id";
> +	status = "okay";
> +};
> +
> +&enetc_port1 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pinctrl_enetc1>;
> +	phy-handle = <&ethphy1>;
> +	phy-mode = "rgmii-id";
> +	status = "okay";
> +};
> +
> +/* No support for XFI yet */
> +&enetc_port2 {
> +	sfp = <&sfp_xfi>;
> +	phy-mode = "10gbase-r";
> +	clocks = <&clk_eth>;
> +	clock-names = "enet_ref_clk";
> +	managed = "in-band-status";
> +	status = "disabled";
> +};
> +
> +&flexcan1 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pinctrl_flexcan1>;
> +	status = "okay";
> +};
> +
> +&flexcan2 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pinctrl_flexcan2>;
> +	status = "okay";
> +};
> +
> +&lpi2c2 {
> +	tlv320aic3x04: audio-codec@18 {
> +		compatible = "ti,tlv320aic32x4";
> +		reg = <0x18>;
> +		clocks = <&scmi_clk IMX95_CLK_SAI3>;
> +		clock-names = "mclk";
> +		reset-gpios = <&expander1 14 GPIO_ACTIVE_LOW>;
> +		iov-supply = <&reg_v3v3_mb>;
> +		ldoin-supply = <&reg_v3v3_mb>;
> +	};
> +
> +	fan_controller: fan-controller@2f {
> +		compatible = "microchip,emc2301", "microchip,emc2305";
> +		reg = <0x2f>;
> +		#address-cells = <1>;
> +		#size-cells = <0>;
> +		#pwm-cells = <3>;
> +		status = "okay";
> +
> +		fan: fan@0 {
> +			reg = <0x0>;
> +			pwms = <&fan_controller 40000 PWM_POLARITY_INVERTED 1>;
> +			#cooling-cells = <2>;
> +			fan-supply = <&reg_pwm_fan>;
> +		};
> +	};
> +
> +	ptn5110: usb-typec@50 {
> +		compatible = "nxp,ptn5110", "tcpci";
> +		reg = <0x50>;
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&pinctrl_typec>;
> +		interrupt-parent = <&gpio2>;
> +		interrupts = <28 IRQ_TYPE_LEVEL_LOW>;
> +
> +		typec_con: connector {
> +			compatible = "usb-c-connector";
> +			label = "X9";
> +			power-role = "source";
> +			data-role = "dual";
> +			source-pdos = <PDO_FIXED(5000, 500, PDO_FIXED_USB_COMM)>;
> +			self-powered;
> +
> +			port {
> +				typec_con_hs: endpoint {
> +					remote-endpoint = <&typec_hs>;
> +				};
> +			};
> +		};
> +	};
> +
> +	sensor_mb: temperature-sensor@1e {
> +		compatible = "nxp,se97b", "jedec,jc-42.4-temp";
> +		reg = <0x1e>;
> +	};
> +
> +	eeprom_mb: eeprom@56 {
> +		compatible = "nxp,se97b", "atmel,24c02";
> +		reg = <0x56>;
> +		pagesize = <16>;
> +		vcc-supply = <&reg_v3v3_mb>;
> +	};
> +
> +	pcieclk: clock-generator@68 {
> +		compatible = "renesas,9fgv0441";
> +		reg = <0x68>;
> +		clocks = <&clk_xtal25>;
> +		#clock-cells = <1>;
> +	};
> +
> +	/* D39 IN/OUT 3V3 */
> +	expander1: gpio@74 {
> +		compatible = "ti,tca9539";
> +		reg = <0x74>;
> +		vcc-supply = <&reg_v3v3_mb>;
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&pinctrl_expander1>;
> +		gpio-controller;
> +		#gpio-cells = <2>;
> +		interrupt-controller;
> +		#interrupt-cells = <2>;
> +		interrupt-parent = <&gpio2>;
> +		interrupts = <14 IRQ_TYPE_EDGE_FALLING>;
> +
> +		gpio-line-names =
> +			/* 00 */ "BUTTON_B#", "CAM0_SYNC_3V3",
> +			/* 02 */ "CAM1_SYNC_3V3", "SFP_MOD_ABS",
> +			/* 04 */ "DIG_IN1", "DIG_IN2",
> +			/* 06 */ "DIG_IN3", "DIG_IN4",
> +			/* 08 */ "DIG_OUT_1_2_STATE", "DIG_OUT_3_4_STATE",
> +			/* 10 */ "DIG_OUT_1_EN", "DIG_OUT_2_EN",
> +			/* 12 */ "DIG_OUT_3_EN", "DIG_OUT_4_EN",
> +			/* 14 */ "AUDIO_RST#", "12V_EN";
> +	};
> +
> +	/* D40 OUT 3V3 */
> +	expander2: gpio@75 {
> +		compatible = "ti,tca9539";
> +		reg = <0x75>;
> +		vcc-supply = <&reg_3v3>;
> +		gpio-controller;
> +		#gpio-cells = <2>;
> +
> +		gpio-line-names =
> +			/* 00 */ "ETH10G_REFCLK_EN", "ETH10G_REFCLK_RST#",
> +			/* 02 */ "SFP_TX_DIS", "USB3_RESET#",
> +			/* 04 */ "USB2_RESET#", "LCD_RESET#",
> +			/* 06 */ "LCD_BLT_EN", "LCD_PWR_EN",
> +			/* 08 */ "M2_KEYE_PERST#", "M2_KEYE_WDISABLE1#",
> +			/* 10 */ "M2_KEYE_WDISABLE2#", "M2_KEYB_PERST#",
> +			/* 12 */ "M2_KEYB_WDISABLE1#", "USER_LED1",
> +			/* 14 */ "USER_LED2", "3V3A_10G_EN";
> +
> +		eth10g-refclk-en-hog {
> +			gpio-hog;
> +			gpios = <0 GPIO_ACTIVE_HIGH>;
> +			output-high;
> +			line-name = "ETH10G_REFCLK_EN";
> +		};
> +
> +		eth10g-refclk-rst-hog {
> +			gpio-hog;
> +			gpios = <1 GPIO_ACTIVE_LOW>;
> +			output-low;
> +			line-name = "ETH10G_REFCLK_RST#";
> +		};
> +
> +		m2_keye_wdisable1_hog: m2-keye-wdisable1-hog {
> +			gpio-hog;
> +			gpios = <9 GPIO_ACTIVE_LOW>;
> +			output-low;
> +			line-name = "M2_KEYE_WDISABLE1#";
> +		};
> +
> +		m2_keye_wdisable2_hog: m2-keye-wdisable2-hog {
> +			gpio-hog;
> +			gpios = <10 GPIO_ACTIVE_LOW>;
> +			output-low;
> +			line-name = "M2_KEYE_WDISABLE2#";
> +		};
> +
> +		m2-keyb-wdisable1-hog {
> +			gpio-hog;
> +			gpios = <12 GPIO_ACTIVE_LOW>;
> +			output-low;
> +			line-name = "M2_KEYB_WDISABLE1#";
> +		};
> +	};
> +
> +	/* D41 OUT 1V8 */
> +	expander3: gpio@76 {
> +		compatible = "ti,tca9539";
> +		reg = <0x76>;
> +		vcc-supply = <&reg_v1v8_mb>;
> +		gpio-controller;
> +		#gpio-cells = <2>;
> +
> +		gpio-line-names =
> +			/* 00 */ "ENET1_RESET#", "ENET2_RESET#",
> +			/* 02 */ "M2_KEYE_SDIO_RST#", "M2_KEYE_DEV_WLAN_WAKE#",
> +			/* 04 */ "M2_KEYE_DEV_BT_WAKE", "M2_KEYB_W_DISABLE2#",
> +			/* 06 */ "M2_KEYB_RST#", "M2_KEYB_FULL_CARD_PWR_OFF#",
> +			/* 08 */ "M2_KEYB_DPR", "CAM0_PWR#",
> +			/* 10 */ "CAM1_PWR#", "CAM0_RST#",
> +			/* 12 */ "CAM1_RST#", "CAM0_TRIGGER",
> +			/* 14 */ "CAM1_TRIGGER", "FAN_PWR_EN";
> +
> +		m2-keye-sdio-rst-hog {
> +			gpio-hog;
> +			gpios = <2 GPIO_ACTIVE_LOW>;
> +			output-low;
> +			line-name = "M2_KEYE_SDIO_RST#";
> +		};
> +
> +		m2-keye-dev_wlan-wake-hog {
> +			gpio-hog;
> +			gpios = <3 GPIO_ACTIVE_LOW>;
> +			input;
> +			line-name = "M2_KEYE_DEV_WLAN_WAKE#";
> +		};
> +
> +		m2-keye-dev_bt-wake-hog {
> +			gpio-hog;
> +			gpios = <4 GPIO_ACTIVE_LOW>;
> +			input;
> +			line-name = "M2_KEYE_DEV_BT_WAKE#";
> +		};
> +
> +		m2-keyb-wdisable2-hog {
> +			gpio-hog;
> +			gpios = <5 GPIO_ACTIVE_LOW>;
> +			output-low;
> +			line-name = "M2_KEYB_WDISABLE1#";
> +		};
> +
> +		m2-keyb-rst-hog {
> +			gpio-hog;
> +			gpios = <6 GPIO_ACTIVE_LOW>;
> +			output-low;
> +			line-name = "M2_KEYB_RST#";
> +		};
> +
> +		m2-keyb-full-card-pwr-off-hog {
> +			gpio-hog;
> +			gpios = <7 GPIO_ACTIVE_LOW>;
> +			output-low;
> +			line-name = "M2_KEYB_FULL_CARD_PWR_OFF#";
> +		};
> +	};
> +};
> +
> +/* X4 + XFP */
> +&lpi2c7 {
> +	clock-frequency = <400000>;
> +	pinctrl-names = "default", "gpio";
> +	pinctrl-0 = <&pinctrl_lpi2c7>;
> +	pinctrl-1 = <&pinctrl_lpi2c7_recovery>;
> +	scl-gpios = <&gpio2 7 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
> +	sda-gpios = <&gpio2 6 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
> +	status = "okay";
> +
> +	/* TODO: 0x19: retimer */
> +
> +	/* 0x50 / 0x51: SFP EEPROM */
> +};
> +
> +/* X4 */
> +&lpspi4 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pinctrl_lpspi4>;
> +	cs-gpios = <&gpio5 13 GPIO_ACTIVE_LOW>, <&gpio5 14 GPIO_ACTIVE_LOW>;
> +	status = "okay";
> +};
> +
> +&lpuart1 {
> +	/* console */
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pinctrl_lpuart1>;
> +	status = "okay";
> +};
> +
> +&lpuart2 {
> +	/* SM */
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pinctrl_lpuart2>;
> +	status = "reserved";
> +};
> +
> +&lpuart5 {
> +	/* X16 M.2 KEY E */
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pinctrl_lpuart5>;
> +	status = "okay";
> +};
> +
> +&lpuart7 {
> +	/* X5 */
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pinctrl_lpuart7>;
> +	status = "okay";
> +};
> +
> +&lpuart8 {
> +	/* X15 */
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pinctrl_lpuart8>;
> +	linux,rs485-enabled-at-boot-time;
> +	status = "okay";
> +};
> +
> +&netc_blk_ctrl {
> +	status = "okay";
> +};
> +
> +&netc_emdio {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pinctrl_emdio>;
> +	status = "okay";
> +
> +	/* IRQ pin is AON GPIO, not usable */
> +	ethphy0: ethernet-phy@0 {
> +		compatible = "ethernet-phy-ieee802.3-c22";
> +		reg = <0>;
> +		reset-gpios = <&expander3 0 GPIO_ACTIVE_LOW>;
> +		reset-assert-us = <500000>;
> +		reset-deassert-us = <50000>;
> +		ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_50_NS>;
> +		ti,tx-internal-delay = <DP83867_RGMIIDCTL_2_50_NS>;
> +		ti,fifo-depth = <DP83867_PHYCR_FIFO_DEPTH_4_B_NIB>;
> +		ti,dp83867-rxctrl-strap-quirk;
> +		ti,clk-output-sel = <DP83867_CLK_O_SEL_OFF>;
> +	};
> +
> +	ethphy1: ethernet-phy@1 {
> +		compatible = "ethernet-phy-ieee802.3-c22";
> +		reg = <1>;
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&pinctrl_ethphy1>;
> +		reset-gpios = <&expander3 1 GPIO_ACTIVE_LOW>;
> +		reset-assert-us = <500000>;
> +		reset-deassert-us = <50000>;
> +		interrupt-parent = <&gpio4>;
> +		interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
> +		ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_50_NS>;
> +		ti,tx-internal-delay = <DP83867_RGMIIDCTL_2_50_NS>;
> +		ti,fifo-depth = <DP83867_PHYCR_FIFO_DEPTH_4_B_NIB>;
> +		ti,dp83867-rxctrl-strap-quirk;
> +		ti,clk-output-sel = <DP83867_CLK_O_SEL_OFF>;
> +	};
> +};
> +
> +&netc_timer {
> +	status = "okay";
> +};
> +
> +&netcmix_blk_ctrl {
> +	status = "okay";
> +};
> +
> +/* X16 M2 / E-Key mPCIe */
> +&pcie0 {
> +	pinctrl-0 = <&pinctrl_pcie0>;
> +	pinctrl-names = "default";
> +	clocks = <&scmi_clk IMX95_CLK_HSIO>,
> +		 <&scmi_clk IMX95_CLK_HSIOPLL>,
> +		 <&scmi_clk IMX95_CLK_HSIOPLL_VCO>,
> +		 <&scmi_clk IMX95_CLK_HSIOPCIEAUX>,
> +		 <&pcieclk 1>;
> +	clock-names = "pcie", "pcie_bus", "pcie_phy", "pcie_aux", "ref";
> +	reset-gpios = <&expander2 8 GPIO_ACTIVE_LOW>;
> +	/* Not supported on REV.0100 */
> +	/* supports-clkreq; */
> +	status = "okay";
> +};
> +
> +/* X17 M2 / B-Key PCIe */
> +&pcie1 {
> +	pinctrl-0 = <&pinctrl_pcie1>;
> +	pinctrl-names = "default";
> +	clocks = <&scmi_clk IMX95_CLK_HSIO>,
> +		 <&scmi_clk IMX95_CLK_HSIOPLL>,
> +		 <&scmi_clk IMX95_CLK_HSIOPLL_VCO>,
> +		 <&scmi_clk IMX95_CLK_HSIOPCIEAUX>,
> +		 <&pcieclk 0>;
> +	clock-names = "pcie", "pcie_bus", "pcie_phy", "pcie_aux", "ref";
> +	reset-gpios = <&expander2 11 GPIO_ACTIVE_LOW>;
> +	/* Not supported on REV.0100 */
> +	/* supports-clkreq; */
> +	status = "okay";
> +};
> +
> +&reg_sdvmmc {
> +	status = "okay";
> +};
> +
> +&sai3 {
> +	#sound-dai-cells = <0>;
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pinctrl_sai3>;
> +	assigned-clocks = <&scmi_clk IMX95_CLK_AUDIOPLL1_VCO>,
> +			  <&scmi_clk IMX95_CLK_AUDIOPLL2_VCO>,
> +			  <&scmi_clk IMX95_CLK_AUDIOPLL1>,
> +			  <&scmi_clk IMX95_CLK_AUDIOPLL2>,
> +			  <&scmi_clk IMX95_CLK_SAI3>;
> +	assigned-clock-parents = <0>, <0>, <0>, <0>,
> +				 <&scmi_clk IMX95_CLK_AUDIOPLL1>;
> +	assigned-clock-rates = <3932160000>,
> +			       <3612672000>, <393216000>,
> +			       <361267200>, <12288000>;
> +	fsl,sai-mclk-direction-output;
> +	status = "okay";
> +};
> +
> +&scmi_bbm {
> +	linux,code = <KEY_POWER>;
> +};
> +
> +&thermal_zones {
> +	a55-thermal {
> +		trips {
> +			cpu_active0: trip-active0 {
> +				temperature = <40000>;
> +				hysteresis = <5000>;
> +				type = "active";
> +			};
> +
> +			cpu_active1: trip-active1 {
> +				temperature = <48000>;
> +				hysteresis = <3000>;
> +				type = "active";
> +			};
> +
> +			cpu_active2: trip-active2 {
> +				temperature = <60000>;
> +				hysteresis = <10000>;
> +				type = "active";
> +			};
> +		};
> +
> +		cooling-maps {
> +			map1 {
> +				trip = <&cpu_active0>;
> +				cooling-device = <&fan 0 2>;
> +			};
> +
> +			map2 {
> +				trip = <&cpu_active1>;
> +				cooling-device = <&fan 3 5>;
> +			};
> +
> +			map3 {
> +				trip = <&cpu_active2>;
> +				cooling-device = <&fan 6 10>;
> +			};
> +		};
> +	};
> +};
> +
> +&tpm3 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pinctrl_tpm3>;
> +	status = "okay";
> +};
> +
> +&tpm5 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pinctrl_tpm5>;
> +};
> +
> +&usb2 {
> +	dr_mode = "otg";
> +	hnp-disable;
> +	srp-disable;
> +	adp-disable;
> +	usb-role-switch;
> +	disable-over-current;
> +	samsung,picophy-pre-emp-curr-control = <3>;
> +	samsung,picophy-dc-vol-level-adjust = <7>;
> +	status = "okay";
> +
> +	port {
> +		typec_hs: endpoint {
> +			remote-endpoint = <&typec_con_hs>;
> +		};
> +	};
> +};
> +
> +&usb3 {
> +	status = "okay";
> +};
> +
> +&usb3_dwc3 {
> +	dr_mode = "host";
> +	#address-cells = <1>;
> +	#size-cells = <0>;
> +	status = "okay";
> +
> +	hub_2_0: hub@1 {
> +		compatible = "usb451,8142";
> +		reg = <1>;
> +		peer-hub = <&hub_3_0>;
> +		reset-gpios = <&expander2 3 GPIO_ACTIVE_LOW>;
> +		vdd-supply = <&reg_v3v3_mb>;
> +		#address-cells = <1>;
> +		#size-cells = <0>;
> +
> +		hub_2_1: hub@1 {
> +			compatible = "usb424,2514";
> +			reg = <1>;
> +			reset-gpios = <&expander2 4 GPIO_ACTIVE_LOW>;
> +			vdd-supply = <&reg_v3v3_mb>;
> +			vdda-supply = <&reg_v3v3_mb>;
> +		};
> +	};
> +
> +	hub_3_0: hub@2 {
> +		compatible = "usb451,8140";
> +		reg = <2>;
> +		peer-hub = <&hub_2_0>;
> +		reset-gpios = <&expander2 3 GPIO_ACTIVE_LOW>;
> +		vdd-supply = <&reg_v3v3_mb>;
> +	};
> +};
> +
> +&usb3_phy {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pinctrl_usb3>;
> +	vbus-supply = <&reg_vbus_usb3>;
> +	status = "okay";
> +};
> +
> +/* X7 µSD */
> +&usdhc2 {
> +	pinctrl-names = "default", "state_100mhz", "state_200mhz";
> +	pinctrl-0 = <&pinctrl_usdhc2>;
> +	pinctrl-1 = <&pinctrl_usdhc2_100mhz>;
> +	pinctrl-2 = <&pinctrl_usdhc2_200mhz>;
> +	vmmc-supply = <&reg_sdvmmc>;
> +	cd-gpios = <&gpio3 0 GPIO_ACTIVE_LOW>;
> +	no-mmc;
> +	no-sdio;
> +	disable-wp;
> +	bus-width = <4>;
> +	status = "okay";
> +};
> +
> +&scmi_iomuxc {
> +	pinctrl_enetc0: enetc0grp {
> +		fsl,pins = <IMX95_PAD_ENET1_RD0__NETCMIX_TOP_ETH0_RGMII_RD0		0x1100>,
> +			   <IMX95_PAD_ENET1_RD1__NETCMIX_TOP_ETH0_RGMII_RD1		0x1100>,
> +			   <IMX95_PAD_ENET1_RD2__NETCMIX_TOP_ETH0_RGMII_RD2		0x1100>,
> +			   <IMX95_PAD_ENET1_RD3__NETCMIX_TOP_ETH0_RGMII_RD3		0x1100>,
> +			   <IMX95_PAD_ENET1_RXC__NETCMIX_TOP_ETH0_RGMII_RX_CLK		0x1100>,
> +			   <IMX95_PAD_ENET1_RX_CTL__NETCMIX_TOP_ETH0_RGMII_RX_CTL	0x1100>,
> +			   <IMX95_PAD_ENET1_TD0__NETCMIX_TOP_ETH0_RGMII_TD0		0x11e>,
> +			   <IMX95_PAD_ENET1_TD1__NETCMIX_TOP_ETH0_RGMII_TD1		0x11e>,
> +			   <IMX95_PAD_ENET1_TD2__NETCMIX_TOP_ETH0_RGMII_TD2		0x11e>,
> +			   <IMX95_PAD_ENET1_TD3__NETCMIX_TOP_ETH0_RGMII_TD3		0x11e>,
> +			   <IMX95_PAD_ENET1_TXC__NETCMIX_TOP_ETH0_RGMII_TX_CLK		0x11e>,
> +			   <IMX95_PAD_ENET1_TX_CTL__NETCMIX_TOP_ETH0_RGMII_TX_CTL	0x11e>;
> +	};
> +
> +	pinctrl_enetc1: enetc1grp {
> +		fsl,pins = <IMX95_PAD_ENET2_RD0__NETCMIX_TOP_ETH1_RGMII_RD0		0x1100>,
> +			   <IMX95_PAD_ENET2_RD1__NETCMIX_TOP_ETH1_RGMII_RD1		0x1100>,
> +			   <IMX95_PAD_ENET2_RD2__NETCMIX_TOP_ETH1_RGMII_RD2		0x1100>,
> +			   <IMX95_PAD_ENET2_RD3__NETCMIX_TOP_ETH1_RGMII_RD3		0x1100>,
> +			   <IMX95_PAD_ENET2_RXC__NETCMIX_TOP_ETH1_RGMII_RX_CLK		0x1100>,
> +			   <IMX95_PAD_ENET2_RX_CTL__NETCMIX_TOP_ETH1_RGMII_RX_CTL	0x1100>,
> +			   <IMX95_PAD_ENET2_TD0__NETCMIX_TOP_ETH1_RGMII_TD0		0x11e>,
> +			   <IMX95_PAD_ENET2_TD1__NETCMIX_TOP_ETH1_RGMII_TD1		0x11e>,
> +			   <IMX95_PAD_ENET2_TD2__NETCMIX_TOP_ETH1_RGMII_TD2		0x11e>,
> +			   <IMX95_PAD_ENET2_TD3__NETCMIX_TOP_ETH1_RGMII_TD3		0x11e>,
> +			   <IMX95_PAD_ENET2_TXC__NETCMIX_TOP_ETH1_RGMII_TX_CLK		0x11e>,
> +			   <IMX95_PAD_ENET2_TX_CTL__NETCMIX_TOP_ETH1_RGMII_TX_CTL	0x11e>;
> +	};
> +
> +	pinctrl_ethphy0: ethphy0grp {
> +		fsl,pins = <IMX95_PAD_PDM_BIT_STREAM0__AONMIX_TOP_GPIO1_IO_BIT9		0x1100>;
> +	};
> +
> +	pinctrl_ethphy1: ethphy1grp {
> +		fsl,pins = <IMX95_PAD_ENET1_MDC__GPIO4_IO_BIT0				0x1100>;
> +	};
> +
> +	pinctrl_expander1: expander1grp {
> +		fsl,pins = <IMX95_PAD_GPIO_IO14__GPIO2_IO_BIT14				0x1100>;
> +	};
> +
> +	pinctrl_flexcan1: flexcan1grp {
> +		fsl,pins = <IMX95_PAD_SAI1_TXC__AONMIX_TOP_CAN1_RX		0x1300>,
> +			   <IMX95_PAD_SAI1_TXD0__AONMIX_TOP_CAN1_TX		0x31e>;
> +	};
> +
> +	pinctrl_flexcan2: flexcan2grp {
> +		fsl,pins = <IMX95_PAD_GPIO_IO25__CAN2_TX		0x31e>,
> +			   <IMX95_PAD_GPIO_IO27__CAN2_RX		0x1300>;
> +	};
> +
> +	pinctrl_lpi2c7: lpi2c7grp {
> +		fsl,pins = <IMX95_PAD_GPIO_IO07__LPI2C7_SCL	0x40001b1e>,
> +			   <IMX95_PAD_GPIO_IO06__LPI2C7_SDA	0x40001b1e>;
> +	};
> +
> +	pinctrl_lpi2c7_recovery: lpi2c7recoverygrp {
> +		fsl,pins = <IMX95_PAD_GPIO_IO07__GPIO2_IO_BIT7	0x40001b1e>,
> +			   <IMX95_PAD_GPIO_IO06__GPIO2_IO_BIT6	0x40001b1e>;
> +	};
> +
> +	pinctrl_lpspi4: lpspi4grp {
> +		fsl,pins = <IMX95_PAD_GPIO_IO37__LPSPI4_SCK	0x91e>,
> +			   <IMX95_PAD_GPIO_IO19__LPSPI5_SIN	0x191e>,
> +			   <IMX95_PAD_GPIO_IO36__LPSPI4_SOUT	0x91e>,
> +			   <IMX95_PAD_GPIO_IO34__GPIO5_IO_BIT14	0x91e>,
> +			   <IMX95_PAD_GPIO_IO33__GPIO5_IO_BIT13	0x91e>;
> +	};
> +
> +	pinctrl_lpuart1: lpuart1grp {
> +		fsl,pins = <IMX95_PAD_UART1_TXD__AONMIX_TOP_LPUART1_TX		0x31e>,
> +			   <IMX95_PAD_UART1_RXD__AONMIX_TOP_LPUART1_RX		0x1300>;
> +	};
> +
> +	pinctrl_lpuart2: lpuart2grp {
> +		fsl,pins = <IMX95_PAD_UART2_TXD__AONMIX_TOP_LPUART2_TX		0x31e>,
> +			   <IMX95_PAD_UART2_RXD__AONMIX_TOP_LPUART2_RX		0x1300>;
> +	};
> +
> +	pinctrl_lpuart5: lpuart5grp {
> +		fsl,pins = <IMX95_PAD_GPIO_IO00__LPUART5_TX			0x31e>,
> +			   <IMX95_PAD_GPIO_IO01__LPUART5_RX			0x1300>,
> +			   <IMX95_PAD_GPIO_IO02__LPUART5_CTS_B			0x1300>,
> +			   <IMX95_PAD_GPIO_IO03__LPUART5_RTS_B			0x31e>;
> +	};
> +
> +	pinctrl_lpuart7: lpuart7grp {
> +		fsl,pins = <IMX95_PAD_GPIO_IO08__LPUART7_TX			0x31e>,
> +			   <IMX95_PAD_GPIO_IO09__LPUART7_RX			0x1300>,
> +			   <IMX95_PAD_GPIO_IO10__LPUART7_CTS_B			0x1300>,
> +			   <IMX95_PAD_GPIO_IO11__LPUART7_RTS_B			0x31e>;
> +	};
> +
> +	pinctrl_lpuart8: lpuart8grp {
> +		fsl,pins = <IMX95_PAD_GPIO_IO12__LPUART8_TX			0x31e>,
> +			   <IMX95_PAD_GPIO_IO13__LPUART8_RX			0x1300>,
> +			   <IMX95_PAD_GPIO_IO15__LPUART8_RTS_B			0x31e>;
> +	};
> +
> +	pinctrl_emdio: emdiogrp {
> +		fsl,pins = <IMX95_PAD_ENET2_MDC__NETCMIX_TOP_NETC_MDC		0x51e>,
> +			   <IMX95_PAD_ENET2_MDIO__NETCMIX_TOP_NETC_MDIO		0x51e>;
> +	};
> +
> +	pinctrl_pcie0: pcie0grp {
> +		fsl,pins = <IMX95_PAD_GPIO_IO32__HSIOMIX_TOP_PCIE1_CLKREQ_B	0x111e>;
> +	};
> +
> +	pinctrl_pcie1: pcie1grp {
> +		fsl,pins = <IMX95_PAD_GPIO_IO35__HSIOMIX_TOP_PCIE2_CLKREQ_B	0x111e>;
> +	};
> +
> +	pinctrl_sai3: sai3grp {
> +		fsl,pins = <IMX95_PAD_GPIO_IO16__SAI3_TX_BCLK			0x51e>,
> +			   <IMX95_PAD_GPIO_IO17__SAI3_MCLK			0x51e>,
> +			   <IMX95_PAD_GPIO_IO20__SAI3_RX_DATA_BIT0		0x1300>,
> +			   <IMX95_PAD_GPIO_IO21__SAI3_TX_DATA_BIT0		0x51e>,
> +			   <IMX95_PAD_GPIO_IO26__SAI3_TX_SYNC			0x51e>;
> +	};
> +
> +	pinctrl_retimer: retirmergrp {
> +		fsl,pins = <IMX95_PAD_GPIO_IO29__GPIO2_IO_BIT29			0x1100>;
> +	};
> +
> +	pinctrl_sfp: sfpgrp {
> +		fsl,pins = <IMX95_PAD_GPIO_IO30__GPIO2_IO_BIT30			0x1100>,
> +			   <IMX95_PAD_GPIO_IO31__GPIO2_IO_BIT31			0x1100>;
> +	};
> +
> +	pinctrl_tpm3: tpm3grp {
> +		fsl,pins = <IMX95_PAD_GPIO_IO24__TPM3_CH3			0x51e>;
> +	};
> +
> +	pinctrl_tpm5: tpm5grp {
> +		fsl,pins = <IMX95_PAD_GPIO_IO18__TPM5_CH2			0x51e>;
> +	};
> +
> +	pinctrl_typec: typcegrp {
> +		fsl,pins = <IMX95_PAD_GPIO_IO28__GPIO2_IO_BIT28			0x1100>;
> +	};
> +
> +	pinctrl_usb3: usb3grp {
> +		fsl,pins = <IMX95_PAD_ENET1_MDIO__GPIO4_IO_BIT1			0x31e>;
> +	};
> +
> +	pinctrl_usdhc2: usdhc2grp {
> +		fsl,pins = <IMX95_PAD_SD2_CD_B__GPIO3_IO_BIT0			0x1100>,
> +			   <IMX95_PAD_SD2_CLK__USDHC2_CLK			0x51e>,
> +			   <IMX95_PAD_SD2_CMD__USDHC2_CMD			0x31e>,
> +			   <IMX95_PAD_SD2_DATA0__USDHC2_DATA0			0x131e>,
> +			   <IMX95_PAD_SD2_DATA1__USDHC2_DATA1			0x131e>,
> +			   <IMX95_PAD_SD2_DATA2__USDHC2_DATA2			0x131e>,
> +			   <IMX95_PAD_SD2_DATA3__USDHC2_DATA3			0x131e>,
> +			   <IMX95_PAD_SD2_VSELECT__USDHC2_VSELECT		0x51e>;
> +	};
> +
> +	pinctrl_usdhc2_100mhz: usdhc2-100mhzgrp {
> +		fsl,pins = <IMX95_PAD_SD2_CD_B__GPIO3_IO_BIT0			0x1100>,
> +			   <IMX95_PAD_SD2_CLK__USDHC2_CLK			0x58e>,
> +			   <IMX95_PAD_SD2_CMD__USDHC2_CMD			0x38e>,
> +			   <IMX95_PAD_SD2_DATA0__USDHC2_DATA0			0x138e>,
> +			   <IMX95_PAD_SD2_DATA1__USDHC2_DATA1			0x138e>,
> +			   <IMX95_PAD_SD2_DATA2__USDHC2_DATA2			0x138e>,
> +			   <IMX95_PAD_SD2_DATA3__USDHC2_DATA3			0x138e>,
> +			   <IMX95_PAD_SD2_VSELECT__USDHC2_VSELECT		0x51e>;
> +	};
> +
> +	pinctrl_usdhc2_200mhz: usdhc2-200mhzgrp {
> +		fsl,pins = <IMX95_PAD_SD2_CD_B__GPIO3_IO_BIT0			0x1100>,
> +			   <IMX95_PAD_SD2_CLK__USDHC2_CLK			0x5fe>,
> +			   <IMX95_PAD_SD2_CMD__USDHC2_CMD			0x3fe>,
> +			   <IMX95_PAD_SD2_DATA0__USDHC2_DATA0			0x13fe>,
> +			   <IMX95_PAD_SD2_DATA1__USDHC2_DATA1			0x13fe>,
> +			   <IMX95_PAD_SD2_DATA2__USDHC2_DATA2			0x13fe>,
> +			   <IMX95_PAD_SD2_DATA3__USDHC2_DATA3			0x13fe>,
> +			   <IMX95_PAD_SD2_VSELECT__USDHC2_VSELECT		0x51e>;
> +	};
> +};
> diff --git a/arch/arm64/boot/dts/freescale/imx95-tqma9596la.dtsi b/arch/arm64/boot/dts/freescale/imx95-tqma9596la.dtsi
> new file mode 100644
> index 0000000000000..cc572171bf253
> --- /dev/null
> +++ b/arch/arm64/boot/dts/freescale/imx95-tqma9596la.dtsi
> @@ -0,0 +1,297 @@
> +// SPDX-License-Identifier: (GPL-2.0-or-later OR MIT)
> +/*
> + * Copyright (c) 2024-2026 TQ-Systems GmbH <linux@ew.tq-group.com>,
> + * D-82229 Seefeld, Germany.
> + * Author: Alexander Stein
> + * Author: Markus Niebel
> + */
> +
> +/dts-v1/;
> +
> +#include <dt-bindings/gpio/gpio.h>
> +#include "imx95.dtsi"
> +
> +/ {
> +	memory@80000000 {
> +		device_type = "memory";
> +		/*
> +		 * DRAM base addr, size : 2048 MiB DRAM
> +		 * should be corrected by bootloader
> +		 */
> +		reg = <0 0x80000000 0 0x80000000>;
> +	};
> +
> +	reserved-memory {
> +		#address-cells = <2>;
> +		#size-cells = <2>;
> +		ranges;
> +
> +		linux_cma: linux,cma {
> +			compatible = "shared-dma-pool";
> +			reusable;
> +			size = <0 0x28000000>;
> +			alloc-ranges = <0 0x80000000 0 0x80000000>;
> +			linux,cma-default;
> +		};
> +
> +		vpu_boot: vpu_boot@a0000000 {
> +			reg = <0 0xa0000000 0 0x100000>;
> +			no-map;
> +		};
> +	};
> +
> +	reg_1v8: regulator-1v8 {
> +		compatible = "regulator-fixed";
> +		regulator-name = "V_1V8";
> +		regulator-min-microvolt = <1800000>;
> +		regulator-max-microvolt = <1800000>;
> +		regulator-always-on;
> +	};
> +
> +	reg_3v3: regulator-3v3 {
> +		compatible = "regulator-fixed";
> +		regulator-name = "V_3V3";
> +		regulator-min-microvolt = <3300000>;
> +		regulator-max-microvolt = <3300000>;
> +		regulator-always-on;
> +	};
> +
> +	reg_sdvmmc: regulator-sdvmmc {
> +		compatible = "regulator-fixed";
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&pinctrl_sdvmmc>;
> +		regulator-name = "SD_PWR_EN";
> +		regulator-min-microvolt = <3300000>;
> +		regulator-max-microvolt = <3300000>;
> +		gpio = <&gpio3 7 GPIO_ACTIVE_HIGH>;
> +		off-on-delay-us = <12000>;
> +		enable-active-high;
> +		/* can be enabled by mainboard with SD-Card support */
> +		status = "disabled";
> +	};
> +};
> +
> +&adc1 {
> +	vref-supply = <&reg_1v8>;
> +};
> +
> +&flexspi1 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pinctrl_flexspi1>;
> +	status = "okay";
> +
> +	flash0: flash@0 {
> +		compatible = "jedec,spi-nor";
> +		reg = <0>;
> +		spi-max-frequency = <66000000>;
> +		spi-tx-bus-width = <4>;
> +		spi-rx-bus-width = <4>;
> +		vcc-supply = <&reg_1v8>;
> +
> +		partitions {
> +			compatible = "fixed-partitions";
> +			#address-cells = <1>;
> +			#size-cells = <1>;
> +		};
> +	};
> +};
> +
> +/* System Manager */
> +&gpio1 {
> +	status = "reserved";
> +};
> +
> +/* System Manager */
> +&lpi2c1 {
> +	status = "reserved";
> +};
> +
> +&lpi2c2 {
> +	clock-frequency = <400000>;
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pinctrl_lpi2c2>;
> +	status = "okay";
> +
> +	pcf85063: rtc@51 {
> +		compatible = "nxp,pcf85063a";
> +		reg = <0x51>;
> +		quartz-load-femtofarads = <7000>;
> +	};
> +
> +	m24c64: eeprom@54 {
> +		compatible = "atmel,24c64";
> +		reg = <0x54>;
> +		pagesize = <32>;
> +		vcc-supply = <&reg_3v3>;
> +	};
> +
> +	/* protectable identification memory (part of M24C64-D @54) */
> +	eeprom@5c {
> +		compatible = "atmel,24c64d-wl";
> +		reg = <0x5c>;
> +		pagesize = <32>;
> +		vcc-supply = <&reg_3v3>;
> +	};
> +
> +	imu@6b {
> +		compatible = "st,ism330dhcx";
> +		reg = <0x6b>;
> +		vdd-supply = <&reg_3v3>;
> +		vddio-supply = <&reg_3v3>;
> +	};
> +};
> +
> +&thermal_zones {
> +	pf09-thermal {
> +		polling-delay = <2000>;
> +		polling-delay-passive = <250>;
> +		thermal-sensors = <&scmi_sensor 2>;
> +
> +		trips {
> +			pf09_alert: trip0 {
> +				hysteresis = <2000>;
> +				temperature = <140000>;
> +				type = "passive";
> +			};
> +
> +			pf09_crit: trip1 {
> +				hysteresis = <2000>;
> +				temperature = <155000>;
> +				type = "critical";
> +			};
> +		};
> +	};
> +
> +	pf53arm-thermal {
> +		polling-delay = <2000>;
> +		polling-delay-passive = <250>;
> +		thermal-sensors = <&scmi_sensor 4>;
> +
> +		cooling-maps {
> +			map0 {
> +				trip = <&pf5301_alert>;
> +				cooling-device =
> +					<&A55_0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
> +					<&A55_1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
> +					<&A55_2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
> +					<&A55_3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
> +					<&A55_4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
> +					<&A55_5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
> +			};
> +		};
> +
> +		trips {
> +			pf5301_alert: trip0 {
> +				hysteresis = <2000>;
> +				temperature = <140000>;
> +				type = "passive";
> +			};
> +
> +			pf5301_crit: trip1 {
> +				hysteresis = <2000>;
> +				temperature = <155000>;
> +				type = "critical";
> +			};
> +		};
> +	};
> +
> +	pf53soc-thermal {
> +		polling-delay = <2000>;
> +		polling-delay-passive = <250>;
> +		thermal-sensors = <&scmi_sensor 3>;
> +
> +		trips {
> +			pf5302_alert: trip0 {
> +				hysteresis = <2000>;
> +				temperature = <140000>;
> +				type = "passive";
> +			};
> +
> +			pf5302_crit: trip1 {
> +				hysteresis = <2000>;
> +				temperature = <155000>;
> +				type = "critical";
> +			};
> +		};
> +	};
> +};
> +
> +&usdhc1 {
> +	pinctrl-names = "default", "state_100mhz", "state_200mhz";
> +	pinctrl-0 = <&pinctrl_usdhc1>;
> +	pinctrl-1 = <&pinctrl_usdhc1_100mhz>;
> +	pinctrl-2 = <&pinctrl_usdhc1_200mhz>;
> +	bus-width = <8>;
> +	non-removable;
> +	no-sdio;
> +	no-sd;
> +	status = "okay";
> +};
> +
> +&wdog3 {
> +	status = "okay";
> +};
> +
> +&scmi_iomuxc {
> +	pinctrl_flexspi1: flexspi1grp {
> +		fsl,pins = <IMX95_PAD_XSPI1_SS0_B__FLEXSPI1_A_SS0_B	0x19e>,
> +			   <IMX95_PAD_XSPI1_DATA0__FLEXSPI1_A_DATA_BIT0	0x19e>,
> +			   <IMX95_PAD_XSPI1_DATA1__FLEXSPI1_A_DATA_BIT1	0x19e>,
> +			   <IMX95_PAD_XSPI1_DATA2__FLEXSPI1_A_DATA_BIT2	0x19e>,
> +			   <IMX95_PAD_XSPI1_DATA3__FLEXSPI1_A_DATA_BIT3	0x19e>,
> +			   /* SION to allow clock loopback from pad */
> +			   <IMX95_PAD_XSPI1_SCLK__FLEXSPI1_A_SCLK	0x4000019e>,
> +			   <IMX95_PAD_XSPI1_DQS__FLEXSPI1_A_DQS		0x4000019e>;
> +	};
> +
> +	pinctrl_lpi2c2: lpi2c2grp {
> +		fsl,pins = <IMX95_PAD_I2C2_SCL__AONMIX_TOP_LPI2C2_SCL	0x4000191e>,
> +			   <IMX95_PAD_I2C2_SDA__AONMIX_TOP_LPI2C2_SDA	0x4000191e>;
> +	};
> +
> +	pinctrl_sdvmmc: sdvmmcgrp {
> +		fsl,pins = <IMX95_PAD_SD2_RESET_B__GPIO3_IO_BIT7	0x11e>;
> +	};
> +
> +	pinctrl_usdhc1: usdhc1grp {
> +		fsl,pins = <IMX95_PAD_SD1_CLK__USDHC1_CLK	0x158e>,
> +			   <IMX95_PAD_SD1_CMD__USDHC1_CMD	0x138e>,
> +			   <IMX95_PAD_SD1_DATA0__USDHC1_DATA0	0x138e>,
> +			   <IMX95_PAD_SD1_DATA1__USDHC1_DATA1	0x138e>,
> +			   <IMX95_PAD_SD1_DATA2__USDHC1_DATA2	0x138e>,
> +			   <IMX95_PAD_SD1_DATA3__USDHC1_DATA3	0x138e>,
> +			   <IMX95_PAD_SD1_DATA4__USDHC1_DATA4	0x138e>,
> +			   <IMX95_PAD_SD1_DATA5__USDHC1_DATA5	0x138e>,
> +			   <IMX95_PAD_SD1_DATA6__USDHC1_DATA6	0x138e>,
> +			   <IMX95_PAD_SD1_DATA7__USDHC1_DATA7	0x138e>,
> +			   <IMX95_PAD_SD1_STROBE__USDHC1_STROBE	0x158e>;
> +	};
> +
> +	pinctrl_usdhc1_100mhz: usdhc1-100mhzgrp {
> +		fsl,pins = <IMX95_PAD_SD1_CLK__USDHC1_CLK	0x158e>,
> +			   <IMX95_PAD_SD1_CMD__USDHC1_CMD	0x138e>,
> +			   <IMX95_PAD_SD1_DATA0__USDHC1_DATA0	0x138e>,
> +			   <IMX95_PAD_SD1_DATA1__USDHC1_DATA1	0x138e>,
> +			   <IMX95_PAD_SD1_DATA2__USDHC1_DATA2	0x138e>,
> +			   <IMX95_PAD_SD1_DATA3__USDHC1_DATA3	0x138e>,
> +			   <IMX95_PAD_SD1_DATA4__USDHC1_DATA4	0x138e>,
> +			   <IMX95_PAD_SD1_DATA5__USDHC1_DATA5	0x138e>,
> +			   <IMX95_PAD_SD1_DATA6__USDHC1_DATA6	0x138e>,
> +			   <IMX95_PAD_SD1_DATA7__USDHC1_DATA7	0x138e>,
> +			   <IMX95_PAD_SD1_STROBE__USDHC1_STROBE	0x158e>;
> +	};
> +
> +	pinctrl_usdhc1_200mhz: usdhc1-200mhzgrp {
> +		fsl,pins = <IMX95_PAD_SD1_CLK__USDHC1_CLK	0x15fe>,
> +			   <IMX95_PAD_SD1_CMD__USDHC1_CMD	0x13fe>,
> +			   <IMX95_PAD_SD1_DATA0__USDHC1_DATA0	0x13fe>,
> +			   <IMX95_PAD_SD1_DATA1__USDHC1_DATA1	0x13fe>,
> +			   <IMX95_PAD_SD1_DATA2__USDHC1_DATA2	0x13fe>,
> +			   <IMX95_PAD_SD1_DATA3__USDHC1_DATA3	0x13fe>,
> +			   <IMX95_PAD_SD1_DATA4__USDHC1_DATA4	0x13fe>,
> +			   <IMX95_PAD_SD1_DATA5__USDHC1_DATA5	0x13fe>,
> +			   <IMX95_PAD_SD1_DATA6__USDHC1_DATA6	0x13fe>,
> +			   <IMX95_PAD_SD1_DATA7__USDHC1_DATA7	0x13fe>,
> +			   <IMX95_PAD_SD1_STROBE__USDHC1_STROBE	0x15fe>;
> +	};
> +};
> 


-- 
TQ-Systems GmbH | Mühlstraße 2, Gut Delling | 82229 Seefeld, Germany
Amtsgericht München, HRB 105018
Geschäftsführer: Detlef Schneider, Rüdiger Stahl, Stefan Schneider
http://www.tq-group.com/




^ permalink raw reply

* Re: [RFC PATCH 1/4] security: ima: move ima_init into late_initcall_sync
From: Yeoreum Yun @ 2026-04-21 14:09 UTC (permalink / raw)
  To: Mimi Zohar
  Cc: linux-security-module, linux-kernel, linux-integrity,
	linux-arm-kernel, kvmarm, paul, jmorris, serge, roberto.sassu,
	dmitry.kasatkin, eric.snowberg, peterhuewe, jarkko, jgg,
	sudeep.holla, maz, oupton, joey.gouly, suzuki.poulose, yuzenghui,
	catalin.marinas, will
In-Reply-To: <d6bcc9ef98a1e86887c5a79ff2822e70b5534343.camel@linux.ibm.com>

Hi Mimi,

> On Tue, 2026-04-21 at 13:50 +0100, Yeoreum Yun wrote:
> > Hi Mimi,
> >
> > > On Fri, 2026-04-17 at 18:57 +0100, Yeoreum Yun wrote:
> > > > To generate the boot_aggregate log in the IMA subsystem with TPM PCR values,
> > > > the TPM driver must be built as built-in and
> > > > must be probed before the IMA subsystem is initialized.
> > > >
> > > > However, when the TPM device operates over the FF-A protocol using
> > > > the CRB interface, probing fails and returns -EPROBE_DEFER if
> > > > the tpm_crb_ffa device — an FF-A device that provides the communication
> > > > interface to the tpm_crb driver — has not yet been probed.
> > > >
> > > > To ensure the TPM device operating over the FF-A protocol with
> > > > the CRB interface is probed before IMA initialization,
> > > > the following conditions must be met:
> > > >
> > > >    1. The corresponding ffa_device must be registered,
> > > >       which is done via ffa_init().
> > > >
> > > >    2. The tpm_crb_driver must successfully probe this device via
> > > >       tpm_crb_ffa_init().
> > > >
> > > >    3. The tpm_crb driver using CRB over FF-A can then
> > > >       be probed successfully. (See crb_acpi_add() and
> > > >       tpm_crb_ffa_init() for reference.)
> > > >
> > > > Unfortunately, ffa_init(), tpm_crb_ffa_init(), and crb_acpi_driver_init() are
> > > > all registered with device_initcall, which means crb_acpi_driver_init() may
> > > > be invoked before ffa_init() and tpm_crb_ffa_init() are completed.
> > > >
> > > > When this occurs, probing the TPM device is deferred.
> > > > However, the deferred probe can happen after the IMA subsystem
> > > > has already been initialized, since IMA initialization is performed
> > > > during late_initcall, and deferred_probe_initcall() is performed
> > > > at the same level.
> > > >
> > > > To resolve this, move ima_init() into late_inicall_sync level
> > > > so that let IMA not miss TPM PCR value when generating boot_aggregate
> > > > log though TPM device presents in the system.
> > > >
> > > > Signed-off-by: Yeoreum Yun <yeoreum.yun@arm.com>
> > >
> > > IMA should be initialized as early as possible. I'm really hesitant to defer
> > > ima_init() to late_initcall_sync() for systems that the TPM is currently
> > > initialized in time. For these systems, continue initializing IMA at
> > > late_initcall(). As a compromise for those systems that the TPM isn't properly
> > > initialized in time, define and instantiate the late_initcall_sync().
> > >
> > > ima_init() would need to differentiate between the late_initcall and
> > > late_initcall_sync.  On late_initcall(), instead of saying "No TPM chip found,
> > > activating TPM-bypass!",  it should say "No TPM chip found, deferring to
> > > late_initcall_sync" or something similar.
> >
> > But can we really move those initialisations to be called again?
> >
> > I am referring to functions such as ima_init_crypto(),
> > ima_add_boot_aggregate(), and ima_measure_critical_data() in ima_init()—
> > first without TPM, and then a second time once TPM becomes available.
> > I don’t think that approach would work.
> >
> > In other words, unless tpm_default_chip() can differentiate between a TPM
> > device that is deferred and one that does not exist, we cannot distinguish
> > between the “defer” case and “-EEXIST”.
> >
> > It might be possible if the TPM core tracked the state when a driver returns
> > -EPROBE_DEFER, but I am not sure that is the right approach.
> > For deferred probe cases, the “device initialised in time” check should
> > likely be done at late_initcall_sync, rather than late_initcall.
> >
> > This implies that any such check performed before late_initcall_sync
> > does not reflect a valid state, as it cannot distinguish between “not
> > present” and “deferred”.
> >
> > Therefore, I think the TPM check in IMA should be performed at
> > late_initcall_sync.
> >
> >
> > Am I missing something?
>
> In ima_init() you short circuit out, when called by late_initcall(), if the TPM
> hasn't been initialized.  So the rest of the ima_init() isn't called.  Roughly
> something like this (needs some cleanup):
>
> int __init ima_init(void)
> {
>         static int first = 1;
>         int rc;
>
>         if (ima_tpm_chip)
>                 return 0;
>
>         ima_tpm_chip = tpm_default_chip();
>         if (!ima_tpm_chip && first) {
>                 pr_info("No TPM chip found, deferring te late_initcall_sync()\n");
>                 first = 0;
>                 return 0;
>         }

I see. then I'll respin in v2.

Thanks!

--
Sincerely,
Yeoreum Yun


^ permalink raw reply

* Re: [PATCH v5 04/12] coresight: etm4x: exclude ss_status from drvdata->config
From: Mike Leach @ 2026-04-21 14:16 UTC (permalink / raw)
  To: Yeoreum Yun
  Cc: Suzuki K Poulose, Leo Yan, coresight, linux-arm-kernel,
	linux-kernel, james.clark, alexander.shishkin, jie.gan
In-Reply-To: <aedRqhC1JcoeV+R2@e129823.arm.com>

Hi,

On 4/21/26 11:30, Yeoreum Yun wrote:
>> Hi Mike,
>>
>>> Hi,
>>>
>>> This register [bit 31] indicates if a single shot comparator has matched. So
>>> read-back provides information to the user post run to determine which if
>>> any of the comparators set in this way has actually matched.
>>
>> Okay. so after disable sysfs session, to check former session
>> check whether comprator has matched.
>>
>>>
>>> Moreover, the specification states "Software must reset this bit to 0 to
>>> re-enable single-shot control" and "Reset state is unknown. STATUS must be
>>> written to set an initial state...."
>>>
>>> Therefore this register must be written as part of any configuration so
>>> should be available in the drvdata->config for both read and write,
>>
>> But I don't think this is the reason for locate ss_status into "config"
>> since its write purpose is not to configure but the "clear" former bit.
>> That's why I think it's enough to clear when the new sysfs session starts.
>>
> 
> IOW, I think it's better to remove ss_status from configfs item
> and
>    - add field ss_cmp in etm4_cpas
>    - add another field ss_status under "etm4_drvdata" to show "PENDING
>      and STATUS" bits to sysfs after finishing session.
> 
> Is is valid for you?
> 

No. Why two different locations for a single register read? If I have 
the ETMv4 hardware manual I am going to look for a something that is 
recognizable as being related to the single shot comparator status 
register(s).

So in sysfs I would expect to see all the bits from the register, 
displayed, without masking off the STATUS and PENDING bits as happens now.

In the code I would expect to see a single location with a sensible name 
- ss_cmp doesn't really correlate terribly well with TRCSSCSR. If you do 
not like the original ss_status, then ss_cmp_status may actually be 
better, ss_cmp could be either the ss comparator status or control 
register.

Regards

Mike


>> --
>> Sincerely,
>> Yeoreum Yun
>>
> 
> --
> Sincerely,
> Yeoreum Yun



^ permalink raw reply

* Re: [PATCH v3 4/5] KVM: arm64: Enable HDBSS support and handle HDBSSF events
From: Leonardo Bras @ 2026-04-21 14:18 UTC (permalink / raw)
  To: Tian Zheng
  Cc: Leonardo Bras, maz, oupton, catalin.marinas, corbet, pbonzini,
	will, yuzenghui, wangzhou1, liuyonglong, Jonathan.Cameron,
	yezhenyu2, linuxarm, joey.gouly, kvmarm, kvm, linux-arm-kernel,
	linux-doc, linux-kernel, skhan, suzuki.poulose
In-Reply-To: <acpfD3YjMpEdL5KZ@devkitleo>

On Mon, Mar 30, 2026 at 12:31:28PM +0100, Leonardo Bras wrote:
> On Sat, Mar 28, 2026 at 02:05:25PM +0800, Tian Zheng wrote:
> > 
> > On 3/27/2026 11:00 PM, Leonardo Bras wrote:
> > > On Fri, Mar 27, 2026 at 03:35:29PM +0800, Tian Zheng wrote:
> > > > On 3/26/2026 2:05 AM, Leonardo Bras wrote:
> > > > > Hello Tian,
> > > > > 
> > > > > I am currently working on HACDBS enablement(which will be rebased on top of
> > > > > this patchset) and due to the fact HACDBS and HDBSS are kind of
> > > > > complementary I will sometimes come with some questions for issues I have
> > > > > faced myself on that part. :)
> > > > > 
> > > > > (see below)
> > > > 
> > > > Of course! Happy to exchange ideas and learn together.
> > > :)

Hello Tian,

On the above, HACDBS depends on HACDBSIRQ which can be announced by either 
device-tree or ACPI. 

Do you think it's ok for it to be ACPI only, for now?

Thanks!
Leo


^ permalink raw reply

* Re: [PATCH v5 04/12] coresight: etm4x: exclude ss_status from drvdata->config
From: Yeoreum Yun @ 2026-04-21 14:23 UTC (permalink / raw)
  To: Mike Leach
  Cc: Suzuki K Poulose, Leo Yan, coresight, linux-arm-kernel,
	linux-kernel, james.clark, alexander.shishkin, jie.gan
In-Reply-To: <c4d90a5e-d28c-49b3-ad6e-4f045769a44f@arm.com>

Hi Mike,

> Hi,
>
> On 4/21/26 11:30, Yeoreum Yun wrote:
> > > Hi Mike,
> > >
> > > > Hi,
> > > >
> > > > This register [bit 31] indicates if a single shot comparator has matched. So
> > > > read-back provides information to the user post run to determine which if
> > > > any of the comparators set in this way has actually matched.
> > >
> > > Okay. so after disable sysfs session, to check former session
> > > check whether comprator has matched.
> > >
> > > >
> > > > Moreover, the specification states "Software must reset this bit to 0 to
> > > > re-enable single-shot control" and "Reset state is unknown. STATUS must be
> > > > written to set an initial state...."
> > > >
> > > > Therefore this register must be written as part of any configuration so
> > > > should be available in the drvdata->config for both read and write,
> > >
> > > But I don't think this is the reason for locate ss_status into "config"
> > > since its write purpose is not to configure but the "clear" former bit.
> > > That's why I think it's enough to clear when the new sysfs session starts.
> > >
> >
> > IOW, I think it's better to remove ss_status from configfs item
> > and
> >    - add field ss_cmp in etm4_cpas
> >    - add another field ss_status under "etm4_drvdata" to show "PENDING
> >      and STATUS" bits to sysfs after finishing session.
> >
> > Is is valid for you?
> >
>
> No. Why two different locations for a single register read? If I have the
> ETMv4 hardware manual I am going to look for a something that is
> recognizable as being related to the single shot comparator status
> register(s).
>
> So in sysfs I would expect to see all the bits from the register, displayed,
> without masking off the STATUS and PENDING bits as happens now.
>
> In the code I would expect to see a single location with a sensible name -
> ss_cmp doesn't really correlate terribly well with TRCSSCSR. If you do not
> like the original ss_status, then ss_cmp_status may actually be better,
> ss_cmp could be either the ss comparator status or control register.

Fine. But I'm still we don't need consider ss_status as configfs item.
So it's enough to move ss_status under etm4_drvdata from etm4_config and
use it.


--
Sincerely,
Yeoreum Yun


^ permalink raw reply

* [PATCH] smccc: Replace __ASSEMBLY__ with __ASSEMBLER__
From: Thomas Huth @ 2026-04-21 14:40 UTC (permalink / raw)
  To: Mark Rutland, Lorenzo Pieralisi, Sudeep Holla, Will Deacon
  Cc: linux-arm-kernel, linux-kernel

From: Thomas Huth <thuth@redhat.com>

While the GCC and Clang compilers already define __ASSEMBLER__
automatically when compiling assembly code, __ASSEMBLY__ is a
macro that only gets defined by the Makefiles in the kernel.
This can be very confusing when switching between userspace
and kernelspace coding, or when dealing with uapi headers that
rather should use __ASSEMBLER__ instead. So let's standardize now
on the __ASSEMBLER__ macro that is provided by the compilers.

Signed-off-by: Thomas Huth <thuth@redhat.com>
---
 Note: This patch has been split from an earlier patch series of mine
 to ease reviewing

 include/linux/arm-smccc.h | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/include/linux/arm-smccc.h b/include/linux/arm-smccc.h
index 50b47eba7d015..96d7a61055a70 100644
--- a/include/linux/arm-smccc.h
+++ b/include/linux/arm-smccc.h
@@ -8,7 +8,7 @@
 #include <linux/args.h>
 #include <linux/init.h>
 
-#ifndef __ASSEMBLY__
+#ifndef __ASSEMBLER__
 #include <linux/uuid.h>
 #endif
 
@@ -302,7 +302,7 @@
 #define SMCCC_RET_NOT_REQUIRED			-2
 #define SMCCC_RET_INVALID_PARAMETER		-3
 
-#ifndef __ASSEMBLY__
+#ifndef __ASSEMBLER__
 
 #include <linux/linkage.h>
 #include <linux/types.h>
@@ -353,7 +353,7 @@ s32 arm_smccc_get_soc_id_version(void);
  */
 s32 arm_smccc_get_soc_id_revision(void);
 
-#ifndef __ASSEMBLY__
+#ifndef __ASSEMBLER__
 
 /*
  * Returns whether a specific hypervisor UUID is advertised for the
@@ -402,7 +402,7 @@ static inline u32 smccc_uuid_to_reg(const uuid_t *uuid, int reg)
 	return val;
 }
 
-#endif /* !__ASSEMBLY__ */
+#endif /* !__ASSEMBLER__ */
 
 /**
  * struct arm_smccc_res - Result from SMC/HVC call
@@ -750,5 +750,5 @@ asmlinkage void __arm_smccc_hvc(unsigned long a0, unsigned long a1,
 	})
 #endif /*CONFIG_ARM64*/
 
-#endif /*__ASSEMBLY__*/
+#endif /*__ASSEMBLER__*/
 #endif /*__LINUX_ARM_SMCCC_H*/
-- 
2.53.0



^ permalink raw reply related

* [PATCH 0/4] POE sigreturn fix and extra tests
From: Kevin Brodsky @ 2026-04-21 14:42 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: linux-kernel, Kevin Brodsky, Catalin Marinas, Joey Gouly,
	Mark Brown, Shuah Khan, Will Deacon, linux-kselftest

Commit 2e8a1acea859 ("arm64: signal: Improve POR_EL0 handling to
avoid uaccess failures") introduced special handling for EL0 registers
that impact uaccess. This did not however handle the case where a signal
handler removes the relevant record (poe_context for POE) from the
signal frame; this is clearly not typical behaviour but it is legal.
That commit resulted in arbitrary data from the kernel stack being
written to POR_EL0 in that case.

Patch 1 fixes this by tracking which fields in struct user_access_state
are actually valid. This restores the original behaviour, where POR_EL0
is left untouched if poe_context is removed.

The remaining patches add new tests to the arm64 signal kselftests to
check that POR_EL0 is reset and restored (or preserved) as expected.
---
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Joey Gouly <joey.gouly@arm.com>
Cc: Mark Brown <broonie@kernel.org>
Cc: Shuah Khan <shuah@kernel.org>
Cc: Will Deacon <will@kernel.org>
Cc: linux-kselftest@vger.kernel.org
---
Kevin Brodsky (4):
  arm64: signal: Preserve POR_EL0 if poe_context is missing
  kselftest/arm64: Add POE as a feature in the signal tests
  kselftest/arm64: Add POE helpers to test_signals_utils.h
  kselftest/arm64: Add tests for POR_EL0 save/reset/restore

 arch/arm64/kernel/signal.c                    | 19 +++--
 .../selftests/arm64/signal/test_signals.h     |  2 +
 .../arm64/signal/test_signals_utils.c         |  3 +
 .../arm64/signal/test_signals_utils.h         | 16 ++++
 .../testcases/poe_missing_poe_context.c       | 73 +++++++++++++++++++
 .../arm64/signal/testcases/poe_restore.c      | 64 ++++++++++++++++
 .../arm64/signal/testcases/poe_siginfo.c      | 15 ----
 7 files changed, 172 insertions(+), 20 deletions(-)
 create mode 100644 tools/testing/selftests/arm64/signal/testcases/poe_missing_poe_context.c
 create mode 100644 tools/testing/selftests/arm64/signal/testcases/poe_restore.c


base-commit: 028ef9c96e96197026887c0f092424679298aae8
-- 
2.51.2



^ permalink raw reply

* [PATCH 1/4] arm64: signal: Preserve POR_EL0 if poe_context is missing
From: Kevin Brodsky @ 2026-04-21 14:42 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: linux-kernel, Kevin Brodsky, Catalin Marinas, Joey Gouly,
	Mark Brown, Shuah Khan, Will Deacon, linux-kselftest
In-Reply-To: <20260421144252.1440365-1-kevin.brodsky@arm.com>

Commit 2e8a1acea859 ("arm64: signal: Improve POR_EL0 handling to
avoid uaccess failures") delayed the write to POR_EL0 in
rt_sigreturn to avoid spurious uaccess failures. This change however
relies on the poe_context frame record being present: on a system
supporting POE, calling sigreturn without a poe_context record now
results in writing arbitrary data from the kernel stack into POR_EL0.

Fix this by adding a valid_fields member to struct
user_access_state, and zeroing the struct on allocation.
restore_poe_context() then indicates that the por_el0 field is valid
by setting the corresponding bit in valid_fields, and
restore_user_access_state() only touches POR_EL0 if there is a valid
value to set it to. This is in line with how POR_EL0 was originally
handled; all frame records are currently optional, except
fpsimd_context.

restore_user_access_state() is also called if setting up the signal
frame fails, so we also initialise valid_fields in that case. For
consistency, setup_sigframe() now also checks valid_fields to decide
whether to write a poe_context record, avoiding another call to
system_supports_poe().

Fixes: 2e8a1acea859 ("arm64: signal: Improve POR_EL0 handling to avoid uaccess failures")
Reported-by: Will Deacon <will@kernel.org>
Signed-off-by: Kevin Brodsky <kevin.brodsky@arm.com>
---
 arch/arm64/kernel/signal.c | 19 ++++++++++++++-----
 1 file changed, 14 insertions(+), 5 deletions(-)

diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c
index 08ffc5a5aea4..3f17aed5b4f0 100644
--- a/arch/arm64/kernel/signal.c
+++ b/arch/arm64/kernel/signal.c
@@ -67,6 +67,8 @@ struct rt_sigframe_user_layout {
 	unsigned long end_offset;
 };
 
+#define UA_STATE_HAS_POR_EL0	BIT(0)
+
 /*
  * Holds any EL0-controlled state that influences unprivileged memory accesses.
  * This includes both accesses done in userspace and uaccess done in the kernel.
@@ -74,8 +76,12 @@ struct rt_sigframe_user_layout {
  * This state needs to be carefully managed to ensure that it doesn't cause
  * uaccess to fail when setting up the signal frame, and the signal handler
  * itself also expects a well-defined state when entered.
+ *
+ * The valid_fields member is a bitfield (see UA_STATE_HAS_*), specifying which
+ * of the remaining fields is valid (has been set to a value).
  */
 struct user_access_state {
+	unsigned int valid_fields;
 	u64 por_el0;
 };
 
@@ -95,6 +101,7 @@ static void save_reset_user_access_state(struct user_access_state *ua_state)
 			por_enable_all |= POR_ELx_PERM_PREP(pkey, POE_RWX);
 
 		ua_state->por_el0 = read_sysreg_s(SYS_POR_EL0);
+		ua_state->valid_fields |= UA_STATE_HAS_POR_EL0;
 		write_sysreg_s(por_enable_all, SYS_POR_EL0);
 		/*
 		 * No ISB required as we can tolerate spurious Overlay faults -
@@ -122,7 +129,7 @@ static void set_handler_user_access_state(void)
  */
 static void restore_user_access_state(const struct user_access_state *ua_state)
 {
-	if (system_supports_poe())
+	if (ua_state->valid_fields & UA_STATE_HAS_POR_EL0)
 		write_sysreg_s(ua_state->por_el0, SYS_POR_EL0);
 }
 
@@ -352,8 +359,10 @@ static int restore_poe_context(struct user_ctxs *user,
 		return -EINVAL;
 
 	__get_user_error(por_el0, &(user->poe->por_el0), err);
-	if (!err)
+	if (!err) {
 		ua_state->por_el0 = por_el0;
+		ua_state->valid_fields |= UA_STATE_HAS_POR_EL0;
+	}
 
 	return err;
 }
@@ -1095,7 +1104,7 @@ SYSCALL_DEFINE0(rt_sigreturn)
 {
 	struct pt_regs *regs = current_pt_regs();
 	struct rt_sigframe __user *frame;
-	struct user_access_state ua_state;
+	struct user_access_state ua_state = {0};
 
 	/* Always make any pending restarted system calls return -EINTR */
 	current->restart_block.fn = do_no_restart_syscall;
@@ -1302,7 +1311,7 @@ static int setup_sigframe(struct rt_sigframe_user_layout *user,
 		err |= preserve_fpmr_context(fpmr_ctx);
 	}
 
-	if (system_supports_poe() && err == 0) {
+	if ((ua_state->valid_fields & UA_STATE_HAS_POR_EL0) && err == 0) {
 		struct poe_context __user *poe_ctx =
 			apply_user_offset(user, user->poe_offset);
 
@@ -1507,7 +1516,7 @@ static int setup_rt_frame(int usig, struct ksignal *ksig, sigset_t *set,
 {
 	struct rt_sigframe_user_layout user;
 	struct rt_sigframe __user *frame;
-	struct user_access_state ua_state;
+	struct user_access_state ua_state = {0};
 	int err = 0;
 
 	fpsimd_save_and_flush_current_state();
-- 
2.51.2



^ permalink raw reply related

* [PATCH 3/4] kselftest/arm64: Add POE helpers to test_signals_utils.h
From: Kevin Brodsky @ 2026-04-21 14:42 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: linux-kernel, Kevin Brodsky, Catalin Marinas, Joey Gouly,
	Mark Brown, Shuah Khan, Will Deacon, linux-kselftest
In-Reply-To: <20260421144252.1440365-1-kevin.brodsky@arm.com>

In preparation to adding further POE signal tests, move
get_por_el0() to test_signals_utils.h and add set_por_el0().

Signed-off-by: Kevin Brodsky <kevin.brodsky@arm.com>
---
 .../selftests/arm64/signal/test_signals_utils.h  | 16 ++++++++++++++++
 .../arm64/signal/testcases/poe_siginfo.c         | 15 ---------------
 2 files changed, 16 insertions(+), 15 deletions(-)

diff --git a/tools/testing/selftests/arm64/signal/test_signals_utils.h b/tools/testing/selftests/arm64/signal/test_signals_utils.h
index 36fc12b3cd60..2c7b8c64a35a 100644
--- a/tools/testing/selftests/arm64/signal/test_signals_utils.h
+++ b/tools/testing/selftests/arm64/signal/test_signals_utils.h
@@ -57,6 +57,22 @@ static inline __attribute__((always_inline)) uint64_t get_gcspr_el0(void)
 	return val;
 }
 
+#define SYS_POR_EL0 "S3_3_C10_C2_4"
+
+static inline uint64_t get_por_el0(void)
+{
+	uint64_t val;
+
+	asm volatile("mrs %0, " SYS_POR_EL0 "\n" : "=r"(val));
+
+	return val;
+}
+
+static inline void set_por_el0(uint64_t val)
+{
+	asm volatile("msr " SYS_POR_EL0 ", %0\n" :: "r"(val));
+}
+
 static inline bool feats_ok(struct tdescr *td)
 {
 	if (td->feats_incompatible & td->feats_supported)
diff --git a/tools/testing/selftests/arm64/signal/testcases/poe_siginfo.c b/tools/testing/selftests/arm64/signal/testcases/poe_siginfo.c
index 36bd9940ee05..e15fedf4da6e 100644
--- a/tools/testing/selftests/arm64/signal/testcases/poe_siginfo.c
+++ b/tools/testing/selftests/arm64/signal/testcases/poe_siginfo.c
@@ -21,21 +21,6 @@ static union {
 	char buf[1024 * 128];
 } context;
 
-#define SYS_POR_EL0 "S3_3_C10_C2_4"
-
-static uint64_t get_por_el0(void)
-{
-	uint64_t val;
-
-	asm volatile(
-		"mrs	%0, " SYS_POR_EL0 "\n"
-		: "=r"(val)
-		:
-		: );
-
-	return val;
-}
-
 int poe_present(struct tdescr *td, siginfo_t *si, ucontext_t *uc)
 {
 	struct _aarch64_ctx *head = GET_BUF_RESV_HEAD(context);
-- 
2.51.2



^ permalink raw reply related

* [PATCH 2/4] kselftest/arm64: Add POE as a feature in the signal tests
From: Kevin Brodsky @ 2026-04-21 14:42 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: linux-kernel, Kevin Brodsky, Catalin Marinas, Joey Gouly,
	Mark Brown, Shuah Khan, Will Deacon, linux-kselftest
In-Reply-To: <20260421144252.1440365-1-kevin.brodsky@arm.com>

Add the POE feature to the signal tests framework, to allow tests to
require it.

Signed-off-by: Kevin Brodsky <kevin.brodsky@arm.com>
---
 tools/testing/selftests/arm64/signal/test_signals.h       | 2 ++
 tools/testing/selftests/arm64/signal/test_signals_utils.c | 3 +++
 2 files changed, 5 insertions(+)

diff --git a/tools/testing/selftests/arm64/signal/test_signals.h b/tools/testing/selftests/arm64/signal/test_signals.h
index ee75a2c25ce7..c7c343494cb8 100644
--- a/tools/testing/selftests/arm64/signal/test_signals.h
+++ b/tools/testing/selftests/arm64/signal/test_signals.h
@@ -36,6 +36,7 @@ enum {
 	FSME_FA64_BIT,
 	FSME2_BIT,
 	FGCS_BIT,
+	FPOE_BIT,
 	FMAX_END
 };
 
@@ -45,6 +46,7 @@ enum {
 #define FEAT_SME_FA64		(1UL << FSME_FA64_BIT)
 #define FEAT_SME2		(1UL << FSME2_BIT)
 #define FEAT_GCS		(1UL << FGCS_BIT)
+#define FEAT_POE		(1UL << FPOE_BIT)
 
 /*
  * A descriptor used to describe and configure a test case.
diff --git a/tools/testing/selftests/arm64/signal/test_signals_utils.c b/tools/testing/selftests/arm64/signal/test_signals_utils.c
index 5d3621921cfe..4b12dbd7669d 100644
--- a/tools/testing/selftests/arm64/signal/test_signals_utils.c
+++ b/tools/testing/selftests/arm64/signal/test_signals_utils.c
@@ -31,6 +31,7 @@ static char const *const feats_names[FMAX_END] = {
 	" FA64 ",
 	" SME2 ",
 	" GCS ",
+	" POE ",
 };
 
 #define MAX_FEATS_SZ	128
@@ -341,6 +342,8 @@ int test_init(struct tdescr *td)
 			td->feats_supported |= FEAT_SME2;
 		if (getauxval(AT_HWCAP) & HWCAP_GCS)
 			td->feats_supported |= FEAT_GCS;
+		if (getauxval(AT_HWCAP2) & HWCAP2_POE)
+			td->feats_supported |= FEAT_POE;
 		if (feats_ok(td)) {
 			if (td->feats_required & td->feats_supported)
 				fprintf(stderr,
-- 
2.51.2



^ permalink raw reply related

* [PATCH 4/4] kselftest/arm64: Add tests for POR_EL0 save/reset/restore
From: Kevin Brodsky @ 2026-04-21 14:42 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: linux-kernel, Kevin Brodsky, Catalin Marinas, Joey Gouly,
	Mark Brown, Shuah Khan, Will Deacon, linux-kselftest
In-Reply-To: <20260421144252.1440365-1-kevin.brodsky@arm.com>

POR_EL0 is expected to be:
- Saved in the poe_context record
- Reset to POR_EL0_INIT when invoking the signal handler
- Restored from poe_context when returning from the signal handler

Add a new test, poe_restore, to check that the save/reset/restore
mechanism is working as intended. See commit 2e8a1acea859 ("arm64:
signal: Improve POR_EL0 handling to avoid uaccess failures") for
more details.

This commit did not handle the case where poe_context is missing
correctly. This was recently fixed; add a new test,
poe_missing_poe_context, to check this case.

Note: td->pass is only set to true at the very end, as an unexpected
signal may occur in case of failure (especially in
poe_missing_poe_context if POR_EL0 is restored to an invalid value).
Failures are tracked with a global, failed_check.

Signed-off-by: Kevin Brodsky <kevin.brodsky@arm.com>
---
 .../testcases/poe_missing_poe_context.c       | 73 +++++++++++++++++++
 .../arm64/signal/testcases/poe_restore.c      | 64 ++++++++++++++++
 2 files changed, 137 insertions(+)
 create mode 100644 tools/testing/selftests/arm64/signal/testcases/poe_missing_poe_context.c
 create mode 100644 tools/testing/selftests/arm64/signal/testcases/poe_restore.c

diff --git a/tools/testing/selftests/arm64/signal/testcases/poe_missing_poe_context.c b/tools/testing/selftests/arm64/signal/testcases/poe_missing_poe_context.c
new file mode 100644
index 000000000000..abab7400d9df
--- /dev/null
+++ b/tools/testing/selftests/arm64/signal/testcases/poe_missing_poe_context.c
@@ -0,0 +1,73 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2026 Arm Ltd
+ *
+ * Verify that the POR_EL0 register is left untouched on sigreturn if the
+ * POE frame record is missing.
+ */
+
+#include <asm/sigcontext.h>
+
+#include "test_signals_utils.h"
+#include "testcases.h"
+
+#define POR_EL0_INIT	0x07ul
+#define POR_EL0_CUSTOM	0x77ul
+
+static bool failed_check;
+
+static bool modify_por_el0(struct tdescr *td)
+{
+	set_por_el0(POR_EL0_CUSTOM);
+
+	return true;
+}
+
+static int signal_remove_poe_context(struct tdescr *td, siginfo_t *si,
+				      ucontext_t *uc)
+{
+	struct _aarch64_ctx *ctx = GET_UC_RESV_HEAD(uc);
+	struct _aarch64_ctx *poe_ctx_head;
+
+	poe_ctx_head = get_header(ctx, POE_MAGIC, sizeof(uc->uc_mcontext),
+				  NULL);
+	if (!poe_ctx_head) {
+		fprintf(stderr, "Missing poe_context record\n");
+		failed_check = true;
+		return 0;
+	}
+
+	/*
+	 * Actually removing the record would require moving down the next
+	 * records. An easier option is to turn it into an ESR record, which is
+	 * ignored by sigreturn().
+	 */
+	poe_ctx_head->magic = ESR_MAGIC;
+
+	return 0;
+}
+
+static void check_por_el0_preserved(struct tdescr *td)
+{
+	uint64_t por_el0 = get_por_el0();
+
+	if (por_el0 == POR_EL0_INIT) {
+		fprintf(stderr, "POR_EL0 preserved\n");
+	} else {
+		fprintf(stderr, "POR_EL0 unexpectedly set to %lx\n", por_el0);
+		failed_check = true;
+	}
+
+	td->pass = !failed_check;
+}
+
+struct tdescr tde = {
+	.name = "POR_EL0 missing poe_context",
+	.descr = "Remove poe_context record and check POR_EL0 is preserved",
+	.feats_required = FEAT_POE,
+	.timeout = 3,
+	.sig_trig = SIGUSR1,
+	.init = modify_por_el0,
+	.run = signal_remove_poe_context,
+	.check_result = check_por_el0_preserved,
+};
diff --git a/tools/testing/selftests/arm64/signal/testcases/poe_restore.c b/tools/testing/selftests/arm64/signal/testcases/poe_restore.c
new file mode 100644
index 000000000000..9f9a61a4214d
--- /dev/null
+++ b/tools/testing/selftests/arm64/signal/testcases/poe_restore.c
@@ -0,0 +1,64 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2026 Arm Ltd
+ *
+ * Verify that the POR_EL0 register is saved and restored as expected on signal
+ * entry/return.
+ */
+
+#include <asm/sigcontext.h>
+
+#include "test_signals_utils.h"
+#include "testcases.h"
+
+#define POR_EL0_INIT	0x07ul
+#define POR_EL0_CUSTOM	0x77ul
+
+static bool failed_check;
+
+static bool modify_por_el0(struct tdescr *td)
+{
+	set_por_el0(POR_EL0_CUSTOM);
+
+	return true;
+}
+
+static int signal_check_por_el0_reset(struct tdescr *td, siginfo_t *si,
+				      ucontext_t *uc)
+{
+	uint64_t signal_por_el0 = get_por_el0();
+
+	if (signal_por_el0 != POR_EL0_INIT) {
+		fprintf(stderr, "POR_EL0 is %lx in signal handler (expected %lx)\n",
+			signal_por_el0, POR_EL0_INIT);
+		failed_check = true;
+	}
+
+	return 0;
+}
+
+static void check_por_el0_restored(struct tdescr *td)
+{
+	uint64_t por_el0 = get_por_el0();
+
+	if (por_el0 == POR_EL0_CUSTOM) {
+		fprintf(stderr, "POR_EL0 restored\n");
+	} else {
+		fprintf(stderr, "POR_EL0 was %lx but is now %lx\n",
+			POR_EL0_CUSTOM, por_el0);
+		failed_check = true;
+	}
+
+	td->pass = !failed_check;
+}
+
+struct tdescr tde = {
+	.name = "POR_EL0 restore",
+	.descr = "Validate that POR_EL0 is saved/restored on signal entry/return",
+	.feats_required = FEAT_POE,
+	.timeout = 3,
+	.sig_trig = SIGUSR1,
+	.init = modify_por_el0,
+	.run = signal_check_por_el0_reset,
+	.check_result = check_por_el0_restored,
+};
-- 
2.51.2



^ permalink raw reply related

* Re: [PATCH v2 2/2] arm64: dts: add tqma9596la-mba95xxca
From: Daniel Baluta @ 2026-04-21 14:48 UTC (permalink / raw)
  To: Alexander Stein, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Frank Li, Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam,
	Geert Uytterhoeven, Magnus Damm, Shawn Guo
  Cc: Markus Niebel, devicetree, linux-kernel, imx, linux-arm-kernel,
	linux, linux-renesas-soc
In-Reply-To: <20260326111803.1248934-2-alexander.stein@ew.tq-group.com>

[..]

> +
> +	reserved-memory {
> +		#address-cells = <2>;
> +		#size-cells = <2>;
> +		ranges;
> +
> +		linux_cma: linux,cma {
> +			compatible = "shared-dma-pool";
> +			reusable;
> +			size = <0 0x28000000>;
> +			alloc-ranges = <0 0x80000000 0 0x80000000>;
> +			linux,cma-default;
> +		};
> +
> +		vpu_boot: vpu_boot@a0000000 {

Should this be memory@a0000000 ?



^ permalink raw reply

* Re: [PATCH v2 2/3] pwm: rp1: Add RP1 PWM controller driver
From: Uwe Kleine-König @ 2026-04-21 14:50 UTC (permalink / raw)
  To: Andrea della Porta
  Cc: linux-pwm, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Florian Fainelli, Broadcom internal kernel review list,
	devicetree, linux-rpi-kernel, linux-arm-kernel, linux-kernel,
	Naushir Patuck, Stanimir Varbanov, mbrugger
In-Reply-To: <aeZUAaQkHGqBL8st@apocalypse>

[-- Attachment #1: Type: text/plain, Size: 3719 bytes --]

Hello Andrea,

On Mon, Apr 20, 2026 at 06:27:45PM +0200, Andrea della Porta wrote:
> On 12:50 Fri 17 Apr     , Uwe Kleine-König wrote:
> > What happens if sync is asserted while a disabled channel didn't
> > complete the last period yet?
> 
> The output stops immediately without waiting for the current period to finish.

This is a good info for the Limitations block.

> > Maybe it's worth to test the following procedure for updating duty and
> > period:
> > 
> > 	disable channel
> > 	configure duty
> > 	configure period
> > 	enable
> > 	set update flag
> > 
> > Assumint disable is delayed until the end of the currently running
> > period, the effect of this procedure might be that no glitch happens if
> > the update flag is asserted before the currently running period ends and
> > the anormality is reduced to a longer inactive state if the updates are
> > not that lucky (in contrast to more severe glitches).
> 
> The disable isn't delayed as explained above. Setting just the new period/duty
> (which do not depend on the sync bit) correctly waits for the end of the current
> period without noticeable glitches (tested with a scope).

So if you happen to change both and one is done before the end of the
current period and the other shortly afterwards (which might happen as
those are configured in two different registers and the update trigger
isn't used), you get a mixed output for one cycle, right? If yes, please
also mention that in the Limitations paragraph.

> > > Let's say that teh user want 10 tick period, we have to use
> > > 9 instead to account for the extra tick at the end, so that the complete period
> > > contains that extra tick?
> > 
> > I would describe that a bit differently, but in general: yes.
> > 
> > The more straight forward description is that setting
> > 
> > 	RP1_PWM_RANGE(pwm->hwpwm) := x
> > 
> > results in a period of x + 1 ticks.
> 
> Exactly. So whatever the user request I have to subtract one from the value
> to be written to the RANGE register.

Unless the calculation is already rounded to 0, in that case don't
subtract 1 and let the tohw callback return 1.

> > > This also means that if we ask for 100% duty cycle, the output waveform will
> > > have the high part of the signal lasting one tick less than expected.a I guess
> > > this is the accepted compromise.
> > 
> > I assume you considered something like:
> > 
> > 	RP1_PWM_RANGE(pwm->hwpwm) := 17
> > 	RP1_PWM_DUTY(pwm->hwpwm) := 18
> > 
> > to get a 100% relative duty?
> 
> Ah right! It's working fine and I've got 100% duty. So at hw register level
> the duty can be greater that the period.

In that case please make sure to not use the maximal value for
RP1_PWM_RANGE(pwm->hwpwm) to ensure that for each (possible) period
length a 100% relative duty cycle can be configured.

> > My (not so well articulated) point is: Please be stringent about clock
> > handling to not bank up technical dept more than necessary and such that
> > the driver can be made unbindable if and when syscons grow
> > that feature. Optionally wail at the syscon guys :-)
> 
> Hmmm not sure I've understood your point: is it a requirement that the driver
> must be unbindable? In this case I should avoid registering the syscon. Or
> should I just provide a .remove callback in case there will be a way to
> unregister the syscon (even if this callback will not be called as of now)?

It's a requirement to properly manage the resources you allocate. If a
driver isn't unbindable due to restrictions of other subsystems that's
unfortunate and I don't like it, but I wouldn't block a patch because of
that.

Best regards
Uwe

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply

* Re: [PATCH v3 1/3] dt-bindings: power: Add power-domains-child-ids property
From: Kevin Hilman @ 2026-04-21 14:57 UTC (permalink / raw)
  To: Rob Herring
  Cc: Ulf Hansson, Geert Uytterhoeven, linux-pm, devicetree,
	linux-kernel, arm-scmi, linux-arm-kernel
In-Reply-To: <20260421134949.GA1045294-robh@kernel.org>

Rob Herring <robh@kernel.org> writes:

> On Mon, Apr 20, 2026 at 04:51:17PM -0700, Kevin Hilman (TI) wrote:
>> Add binding documentation for the new power-domains-child-ids property,
>> which works in conjunction with the existing power-domains property to
>> establish parent-child relationships between a multi-domain power domain
>> provider and external parent domains.
>> 
>> Each element in the uint32 array identifies the child domain
>> ID (index) within the provider that should be made a child domain of
>> the corresponding phandle entry in power-domains. The two arrays must
>> have the same number of elements.
>> 
>> Signed-off-by: Kevin Hilman (TI) <khilman@baylibre.com>
>
> Missing my Reviewed-by.

Oops, I thought I had grabbed it with b4, but I didn't.  Sorry.

Kevin


^ permalink raw reply

* Re: [PATCH 2/4] kselftest/arm64: Add POE as a feature in the signal tests
From: Mark Brown @ 2026-04-21 14:58 UTC (permalink / raw)
  To: Kevin Brodsky
  Cc: linux-arm-kernel, linux-kernel, Catalin Marinas, Joey Gouly,
	Shuah Khan, Will Deacon, linux-kselftest
In-Reply-To: <20260421144252.1440365-3-kevin.brodsky@arm.com>

[-- Attachment #1: Type: text/plain, Size: 194 bytes --]

On Tue, Apr 21, 2026 at 03:42:50PM +0100, Kevin Brodsky wrote:
> Add the POE feature to the signal tests framework, to allow tests to
> require it.

Reviewed-by: Mark Brown <broonie@kernel.org>

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply

* Re: [PATCH v2 1/2] kernel: param: handle NULL module_kset in lookup_or_create_module_kobject()
From: Shashank Balaji @ 2026-04-21 14:59 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: Kay Sievers, Rafael J. Wysocki, Danilo Krummrich,
	Suzuki K Poulose, Mike Leach, James Clark, Alexander Shishkin,
	Maxime Coquelin, Alexandre Torgue, Miguel Ojeda, Boqun Feng,
	Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg,
	Alice Ryhl, Trevor Gross, Richard Cochran, Jonathan Corbet,
	Shuah Khan, Rahul Bukte, Daniel Palmer, Tim Bird, linux-kernel,
	driver-core, coresight, linux-arm-kernel, rust-for-linux,
	linux-doc
In-Reply-To: <2026042126-majesty-skyline-b76f@gregkh>

Hi Greg,

Thanks for the quick feedback!

On Tue, Apr 21, 2026 at 08:27:10AM +0200, Greg Kroah-Hartman wrote:
> On Tue, Apr 21, 2026 at 03:02:34PM +0900, Shashank Balaji wrote:
> > module_kset is initialized in a subsys_initcall. If a built-in driver tries to
> > register before subsys_initcall with its struct device_driver's mod_name set,
> > then a null module_kset is dereferenced via this call trace:
> > 
> >      [    0.095865] Call trace:
> >      [    0.095999]  _raw_spin_lock+0x4c/0x6c (P)
> >      [    0.096150]  kset_find_obj+0x24/0x104
> >      [    0.096209]  lookup_or_create_module_kobject+0x2c/0xd8
> >      [    0.096274]  module_add_driver+0xd4/0x138
> >      [    0.096328]  bus_add_driver+0x16c/0x268
> >      [    0.096380]  driver_register+0x68/0x100
> >      [    0.096428]  __platform_driver_register+0x24/0x30
> >      [    0.096486]  tegra194_cbb_init+0x24/0x30
> >      [    0.096540]  do_one_initcall+0xdc/0x250
> >      [    0.096608]  do_initcall_level+0x9c/0xd0
> >      [    0.096660]  do_initcalls+0x54/0x94
> >      [    0.096706]  do_basic_setup+0x20/0x2c
> >      [    0.096753]  kernel_init_freeable+0xc8/0x154
> >      [    0.096807]  kernel_init+0x20/0x1a0
> >      [    0.096851]  ret_from_fork+0x10/0x20
> > 
> > So, return null in lookup_or_create_module_kobject() if module_kset is null.
> > Existing callers handle null already.
> > 
> > Fixes: f30c53a873d0 ("MODULES: add the module name for built in kernel drivers")
> 
> This isn't a bugfix.

I'll drop it in the next version.

> > Co-developed-by: Rahul Bukte <rahul.bukte@sony.com>
> > Signed-off-by: Rahul Bukte <rahul.bukte@sony.com>
> > Signed-off-by: Shashank Balaji <shashank.mahadasyam@sony.com>
> > ---
> > This bug is triggered by the next patch on arm64 defconfig: tegra194-cbb tries
> > to register from a pure_initcall, and with the next patch adding mod_name, this
> > null deref is hit.
> 
> So this isn't a bug, it's a "don't do that" type of thing :)
> 
> > ---
> >  kernel/params.c | 3 +++
> >  1 file changed, 3 insertions(+)
> > 
> > diff --git a/kernel/params.c b/kernel/params.c
> > index 74d620bc2521..881c7328c059 100644
> > --- a/kernel/params.c
> > +++ b/kernel/params.c
> > @@ -752,6 +752,9 @@ lookup_or_create_module_kobject(const char *name)
> >  	struct kobject *kobj;
> >  	int err;
> >  
> > +	if (!module_kset)
> > +		return NULL;
> 
> Are you sure that making this change is going to be ok?
> mod_sysfs_init() should have been called first as the module has to be
> created before it can be looked up.
> 
> As you are wanting "built in" drivers to show up here, you are going to
> beat the call to param_sysfs_init(), so don't do that.  Make sure that
> the drivers are NOT called before then.

The reason lookup_or_create_module_kobject() can be reached with module_kset == NULL
is that some platform drivers register before subsys_initcall: tegra194_cbb and
tegra234_cbb at pure_initcall, plus roughly 375 others at core_initcall/arch_initcall
(208 arch, 154 core, plus 2 pure and 13 _sync variants). These are dominated by
pinctrl, clk, interconnect, gpio, and mailbox drivers across six SoC vendor trees
(Qualcomm, MediaTek, Freescale, Samsung, Tegra, HiSilicon).

Given that, three ways forward:

  1. Move module_kset creation out of param_sysfs_init() (currently
     subsys_initcall) and call it directly from do_basic_setup()
     before do_initcalls(). This is the cleanest fix from a
     correctness angle: every initcall level sees a live
     module_kset. But it touches init/main.c and kernel/params.c,
     crosses two subsystem trees. I haven't fully audited
     dependencies at do_basic_setup() time.

  2. Demote the ~377 early-initcall platform drivers to
     subsys_initcall or later. Impractical at scale given coordination
     across six vendor trees, and many of these levels seem to be
     architecturally required.

  3. (This patch) Guard lookup_or_create_module_kobject() against
     NULL module_kset. Drivers registered before subsys_initcall
     don't get the /sys/.../module symlink, but they don't get it
     today either (drv->mod_name is NULL pre-patch, so the
     else-if (drv->mod_name) branch in module_add_driver() isn't
     taken). Verified on arm64: /sys/module/tegra194_cbb/ does not
     exist on a booted defconfig with or without my series. The
     guard preserves that exact state while letting the
     device_initcall majority get their symlinks as designed.

I went with option 3 because it preserves observable behaviour
everywhere and keeps the series scoped to driver-core. If you'd
rather I do option 1 instead, I'm happy to.

Thanks,
Shashank


^ permalink raw reply

* Re: [PATCH 3/4] kselftest/arm64: Add POE helpers to test_signals_utils.h
From: Mark Brown @ 2026-04-21 15:00 UTC (permalink / raw)
  To: Kevin Brodsky
  Cc: linux-arm-kernel, linux-kernel, Catalin Marinas, Joey Gouly,
	Shuah Khan, Will Deacon, linux-kselftest
In-Reply-To: <20260421144252.1440365-4-kevin.brodsky@arm.com>

[-- Attachment #1: Type: text/plain, Size: 305 bytes --]

On Tue, Apr 21, 2026 at 03:42:51PM +0100, Kevin Brodsky wrote:

> In preparation to adding further POE signal tests, move
> get_por_el0() to test_signals_utils.h and add set_por_el0().

Subject line should probably also say move if there's a v2 but otherwise

Reviewed-by: Mark Brown <broonie@kernel.org>

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ 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