* Re: [PATCH v3 0/3] gpio: Add EIO GPIO support
From: Linus Walleij @ 2026-04-24 7:52 UTC (permalink / raw)
To: Shubhrajyoti Datta
Cc: linux-kernel, git, shubhrajyoti.datta, Srinivas Neeli,
Michal Simek, Bartosz Golaszewski, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, linux-gpio, devicetree,
linux-arm-kernel
In-Reply-To: <20260421104358.2496125-1-shubhrajyoti.datta@amd.com>
On Tue, Apr 21, 2026 at 12:44 PM Shubhrajyoti Datta
<shubhrajyoti.datta@amd.com> wrote:
> Add the EIO GPIO support.
> Add the dt description and the compatible to the driver.
The series:
Reviewed-by: Linus Walleij <linusw@kernel.org>
Yours,
Linus Walleij
^ permalink raw reply
* Re: [REGRESSION] rseq: refactoring in v6.19 broke everyone on arm64 and tcmalloc everywhere
From: Dmitry Vyukov @ 2026-04-24 7:56 UTC (permalink / raw)
To: Thomas Gleixner
Cc: Mathias Stearn, Jinjie Ruan, linux-man, Mark Rutland,
Mathieu Desnoyers, Catalin Marinas, Will Deacon, Boqun Feng,
Paul E. McKenney, Chris Kennelly, regressions, linux-kernel,
linux-arm-kernel, Peter Zijlstra, Ingo Molnar, Blake Oler
In-Reply-To: <87a4ut1njh.ffs@tglx>
On Thu, 23 Apr 2026 at 21:31, Thomas Gleixner <tglx@linutronix.de> wrote:
>
> On Thu, Apr 23 2026 at 12:51, Mathias Stearn wrote:
> > On Thu, Apr 23, 2026 at 12:39 PM Thomas Gleixner <tglx@linutronix.de> wrote:
> >> The kernel clears rseq_cs reliably when user space was interrupted and:
> >>
> >> the task was preempted
> >> or
> >> the return from interrupt delivers a signal
> >>
> >> If the task invoked a syscall then there is absolutely no reason to do
> >> either of this because syscalls from within a critical section are a
> >> bug and catched when enabling rseq debugging.
> >>
> >> The original code did this along with unconditionally updating CPU/MMCID
> >> which resulted in ~15% performance regression on a syscall heavy
> >> database benchmark once glibc started to register rseq.
> >
> > Just to be clear TCMalloc does not need either rseq_cs to be cleared
> > or cpu_id_start to be written to on syscalls because it doesn't do
> > syscalls from critical sections. It will actually benefit (slightly)
> > from not updating cpu_id_start on syscalls.
>
> I know that it does not do syscalls from within critical sections, but
> it relies on cpu_id_start being unconditionally updated in one way or
> the other.
>
> > It is specifically in the cases where an rseq would need to be aborted
> > (preemption, signals, migration, and membarrier IPI with the rseq
> > flag) that TCMalloc relies on cpu_id_start being written. It does rely
> > on that write even when not inside the critical section, because it
> > effectively uses that to detect if there were any would-cause-abort
> > events in between two critical sections. But since it leaves the
> > rseq_cs pointer non-null between critical sections, so you dont need
> > to add _any_ overhead for programs that never make use of rseq after
> > registration, or add any overhead to syscalls even for those who do.
>
> Well. According to the comment in the tcmalloc code:
>
> // Calculation of the address of the current CPU slabs region is needed for
> // allocation/deallocation fast paths, but is quite expensive. Due to variable
> // shift and experimental support for "virtual CPUs", the calculation involves
> // several additional loads and dependent calculations. Pseudo-code for the
> // address calculation is as follows:
> //
> // cpu_offset = TcmallocSlab.virtual_cpu_id_offset_;
> // cpu = *(&__rseq_abi + virtual_cpu_id_offset_);
> // slabs_and_shift = TcmallocSlab.slabs_and_shift_;
> // shift = slabs_and_shift & kShiftMask;
> // shifted_cpu = cpu << shift;
> // slabs = slabs_and_shift & kSlabsMask;
> // slabs += shifted_cpu;
> //
> // To remove this calculation from fast paths, we cache the slabs address
> // for the current CPU in thread local storage. However, when a thread is
> // rescheduled to another CPU, we somehow need to understand that the cached
>
> ^^^^^^^^^^^
>
> // address is not valid anymore. To achieve this, we overlap the top 4 bytes
> // of the cached address with __rseq_abi.cpu_id_start. When a thread is
> // rescheduled the kernel overwrites cpu_id_start with the current CPU number,
> // which gives us the signal that the cached address is not valid anymore.
>
> The kernel still as of today (the arm64 bug aside) updates the
> cpu_id_start and cpu_id fields in rseq when a task is rescheduled to
> another CPU.
>
> So if the code only requires to know when it got rescheduled to another
> CPU then it still should work, no?
This was my first thought too:
https://lore.kernel.org/lkml/CACT4Y+a9GnOh3wHKSRwzoKF6_OSksQ8qehnHfpCgkQSt_OOmYg@mail.gmail.com/
The only problem is with membarrier (it used to force write to
__rseq_abi.cpu_id_start for all threads, but now it does not).
Otherwise the caching scheme works.
I have a tentative fix for tcmalloc:
https://github.com/dvyukov/tcmalloc/commit/58d0eca91503f539b26d20b6f55fb2f6f8bc0c37
The crux is as follows.
Tcmalloc needs to make all threads stop using old cached slab
pointers. The stopping procedure is now:
slab->stopped = true;
membarrier();
and all rseq critical sections now check the stopped flag in the
cached slab pointer. If it's set, the thread does not proceed to use
the slab.
> But it does not, which makes it clear that it relies on this
> undocumented behaviour of the kernel to rewrite rseq::cpu_id_start
> unconditionally. I'm not yet convinced that it relies on it only when
> interrupted between two subsequent critical sections. We'll see.
>
> ....
>
> Now we come to the best part of this comment:
>
> // Note: this makes __rseq_abi.cpu_id_start unusable for its original purpose.
>
> So any code sequence which ends up in:
>
> x = tcmalloc();
> dostuff(x)
> evaluate(rseq::cpu_id_start, rseq::cpu_id)
>
> is doomed. This might be acceptable for Google internal usage where they
> control the full stack and can prevent anyone else to utilize rseq, but
> in an open ecosystem that's obviously a non-starter.
>
> And they definitely forgot to add this to the comment:
>
> // Never enable CONFIG_RSEQ_DEBUG in the kernel when you use tcmalloc as
> // it will expose the blatant ABI abuse and therefore will kill your
> // application.
>
> If your assumption that the rewrite is only required when rseq::rseq_cs
> is non NULL and user space was interrupted is correct, then the obvious
> no-brainer would have been to add:
>
> __u64 rseq_usr_data;
>
> to struct rseq and clear that unconditionally when rseq::rseq_cs is
> cleared.
>
> But that would have been too simple, would work independent of endianess
> and not in the way of anybody else.
>
> But I know that's incompatible with the features first, correctness
> later and we own the world anyway mindset.
>
> Just for giggles I asked Google Gemini about the implications of
> tmalloc's rseq abuse. The answer is pretty clear:
>
> "In short, TCMalloc treats RSEQ as a private optimization rather than
> a shared system resource, which compromises the stability and
> extensibility of any application that needs RSEQ for anything other
> than memory allocation."
>
> It's also very clear about the wilful ignorance of the tcmalloc people:
>
> "In summary, the developers have known for at least 6 years that the
> implementation was non-standard and conflicting with other rseq
> usage. The github issue which requested glibc compatibility was
> opened in 2022 and has been unresolved since then."
>
> Thanks,
>
> tglx
^ permalink raw reply
* Re: [PATCH] watchdog: ixp4xx: fix reference leak on platform_device_register() failure
From: Guangshuo Li @ 2026-04-24 8:00 UTC (permalink / raw)
To: Linus Walleij
Cc: Guenter Roeck, Imre Kaloz, Daniel Lezcano, Thomas Gleixner,
linux-arm-kernel, linux-kernel, stable
In-Reply-To: <CAD++jLkv=5rJhGv6t9H-oP9k5MY8s-fH1=gHVC88ctbiaMPC7A@mail.gmail.com>
Hi Linus, Guenter,
Thanks for reviewing and discussing this.
On Mon, 20 Apr 2026 at 05:34, Linus Walleij <linusw@kernel.org> wrote:
>
> On Sun, Apr 19, 2026 at 11:08 PM Guenter Roeck <linux@roeck-us.net> wrote:
> > On 4/19/26 13:22, Linus Walleij wrote:
>
> > > Hi Guangshuo,
> > >
> > > thanks for your patch!
> > >
> > > On Mon, Apr 13, 2026 at 5:47 PM Guangshuo Li <lgs201920130244@gmail.com> wrote:
> > >
> > >> ixp4xx_timer_probe() directly returns the result of
> > >> platform_device_register(&ixp4xx_watchdog_device). When registration
> > >> fails, the embedded struct device in ixp4xx_watchdog_device has already
> > >> been initialized by device_initialize(), but the failure path does not
> > >> drop the device reference, leading to a reference leak.
> > > (...)
> > >
> > >> - return platform_device_register(&ixp4xx_watchdog_device);
> > >> + ret = platform_device_register(&ixp4xx_watchdog_device);
> > >> + if (ret)
> > >> + platform_device_put(&ixp4xx_watchdog_device);
> > >
> > > If the problem in the description is indeed there, it seems the bug
> > > is inside platform_device_register(), surely a function returning an
> > > error code is supposed to clean up any resources it takes before
> > > returning an error. It seems wrong to try to fix this in all the
> > > consumers.
> > >
> >
> > From platform_device_register():
> >
> > /**
> > * platform_device_register - add a platform-level device
> > * @pdev: platform device we're adding
> > *
> > * NOTE: _Never_ directly free @pdev after calling this function, even if it
> > * returned an error! Always use platform_device_put() to give up the
> > * reference initialised in this function instead.
> > */
> >
> > Not that any code actually does that as far as I can see, but isn't
> > the above doing exactly what the comment suggests ?
>
> Yeah and Johan Hovold wrote that comment and he usually knows
> what he's doing so let's go with this then, I'm convinced!
>
> Reviewed-by: Linus Walleij <linusw@kernel.org>
>
> Yours,
> Linus Walleij
After further checking, this patch is not appropriate for this driver.
ixp4xx_watchdog_device is a static platform_device, and it does not have
a dev.release callback. Calling platform_device_put() on the
platform_device_register() failure path can therefore trigger the missing
release callback warning.
So please disregard this patch. I will drop it and will also go back and
check the other patches I sent for the same pattern, and send follow-ups
where they should be ignored or reverted.
Sorry for the confusion, and thanks again for the review.
Best regards,
Guangshuo Li
^ permalink raw reply
* Re: [PATCH v10 3/6] mfd: max77759: add register bitmasks and modify irq configs for charger
From: Lee Jones @ 2026-04-24 8:26 UTC (permalink / raw)
To: amitsd
Cc: André Draszik, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Greg Kroah-Hartman, Jagan Sridharan, Mark Brown,
Matti Vaittinen, Andrew Morton, Sebastian Reichel,
Heikki Krogerus, Peter Griffin, Tudor Ambarus, Alim Akhtar,
linux-kernel, devicetree, linux-usb, linux-pm, linux-arm-kernel,
linux-samsung-soc, RD Babiera, Kyle Tso
In-Reply-To: <20260331-max77759-charger-v10-3-76f59233c369@google.com>
On Tue, 31 Mar 2026, Amit Sunil Dhamne via B4 Relay wrote:
> From: Amit Sunil Dhamne <amitsd@google.com>
>
> Add register bitmasks for charger function.
> In addition split the charger IRQs further such that each bit represents
> an IRQ downstream of charger regmap irq chip. In addition populate the
> ack_base to offload irq ack to the regmap irq chip framework.
Please reword this commit messages.
Using 'In addition' twice in such close proximity reads a little awkwardly.
> Signed-off-by: Amit Sunil Dhamne <amitsd@google.com>
> Reviewed-by: André Draszik <andre.draszik@linaro.org>
> ---
> drivers/mfd/max77759.c | 95 ++++++++++++++++++++++---
> include/linux/mfd/max77759.h | 166 +++++++++++++++++++++++++++++++++++--------
> 2 files changed, 222 insertions(+), 39 deletions(-)
>
> diff --git a/drivers/mfd/max77759.c b/drivers/mfd/max77759.c
> index a7efe233ec8c..9fa6027a92c4 100644
> --- a/drivers/mfd/max77759.c
> +++ b/drivers/mfd/max77759.c
> @@ -201,8 +201,24 @@ static const struct regmap_config max77759_regmap_config_charger = {
> * - SYSUVLO_INT
> * - FSHIP_NOT_RD
> * - CHGR_INT: charger
> - * - CHG_INT
> - * - CHG_INT2
> + * - INT1
> + * - AICL
> + * - CHGIN
> + * - WCIN
> + * - CHG
> + * - BAT
> + * - INLIM
> + * - THM2
> + * - BYP
> + * - INT2
> + * - INSEL
> + * - SYS_UVLO1
> + * - SYS_UVLO2
> + * - BAT_OILO
> + * - CHG_STA_CC
> + * - CHG_STA_CV
> + * - CHG_STA_TO
> + * - CHG_STA_DONE
> */
> enum {
> MAX77759_INT_MAXQ,
> @@ -228,8 +244,22 @@ enum {
> };
>
> enum {
> - MAX77759_CHARGER_INT_1,
> - MAX77759_CHARGER_INT_2,
> + MAX77759_CHGR_INT1_AICL,
> + MAX77759_CHGR_INT1_CHGIN,
> + MAX77759_CHGR_INT1_WCIN,
> + MAX77759_CHGR_INT1_CHG,
> + MAX77759_CHGR_INT1_BAT,
> + MAX77759_CHGR_INT1_INLIM,
> + MAX77759_CHGR_INT1_THM2,
> + MAX77759_CHGR_INT1_BYP,
> + MAX77759_CHGR_INT2_INSEL,
> + MAX77759_CHGR_INT2_SYS_UVLO1,
> + MAX77759_CHGR_INT2_SYS_UVLO2,
> + MAX77759_CHGR_INT2_BAT_OILO,
> + MAX77759_CHGR_INT2_CHG_STA_CC,
> + MAX77759_CHGR_INT2_CHG_STA_CV,
> + MAX77759_CHGR_INT2_CHG_STA_TO,
> + MAX77759_CHGR_INT2_CHG_STA_DONE,
> };
>
> static const struct regmap_irq max77759_pmic_irqs[] = {
> @@ -256,8 +286,38 @@ static const struct regmap_irq max77759_topsys_irqs[] = {
> };
>
> static const struct regmap_irq max77759_chgr_irqs[] = {
> - REGMAP_IRQ_REG(MAX77759_CHARGER_INT_1, 0, GENMASK(7, 0)),
> - REGMAP_IRQ_REG(MAX77759_CHARGER_INT_2, 1, GENMASK(7, 0)),
> + REGMAP_IRQ_REG(MAX77759_CHGR_INT1_AICL, 0,
> + MAX77759_CHGR_REG_CHG_INT_AICL),
> + REGMAP_IRQ_REG(MAX77759_CHGR_INT1_CHGIN, 0,
> + MAX77759_CHGR_REG_CHG_INT_CHGIN),
> + REGMAP_IRQ_REG(MAX77759_CHGR_INT1_WCIN, 0,
> + MAX77759_CHGR_REG_CHG_INT_WCIN),
> + REGMAP_IRQ_REG(MAX77759_CHGR_INT1_CHG, 0,
> + MAX77759_CHGR_REG_CHG_INT_CHG),
> + REGMAP_IRQ_REG(MAX77759_CHGR_INT1_BAT, 0,
> + MAX77759_CHGR_REG_CHG_INT_BAT),
> + REGMAP_IRQ_REG(MAX77759_CHGR_INT1_INLIM, 0,
> + MAX77759_CHGR_REG_CHG_INT_INLIM),
> + REGMAP_IRQ_REG(MAX77759_CHGR_INT1_THM2, 0,
> + MAX77759_CHGR_REG_CHG_INT_THM2),
> + REGMAP_IRQ_REG(MAX77759_CHGR_INT1_BYP, 0,
> + MAX77759_CHGR_REG_CHG_INT_BYP),
> + REGMAP_IRQ_REG(MAX77759_CHGR_INT2_INSEL, 1,
> + MAX77759_CHGR_REG_CHG_INT2_INSEL),
> + REGMAP_IRQ_REG(MAX77759_CHGR_INT2_SYS_UVLO1, 1,
> + MAX77759_CHGR_REG_CHG_INT2_SYS_UVLO1),
> + REGMAP_IRQ_REG(MAX77759_CHGR_INT2_SYS_UVLO2, 1,
> + MAX77759_CHGR_REG_CHG_INT2_SYS_UVLO2),
> + REGMAP_IRQ_REG(MAX77759_CHGR_INT2_BAT_OILO, 1,
> + MAX77759_CHGR_REG_CHG_INT2_BAT_OILO),
> + REGMAP_IRQ_REG(MAX77759_CHGR_INT2_CHG_STA_CC, 1,
> + MAX77759_CHGR_REG_CHG_INT2_CHG_STA_CC),
> + REGMAP_IRQ_REG(MAX77759_CHGR_INT2_CHG_STA_CV, 1,
> + MAX77759_CHGR_REG_CHG_INT2_CHG_STA_CV),
> + REGMAP_IRQ_REG(MAX77759_CHGR_INT2_CHG_STA_TO, 1,
> + MAX77759_CHGR_REG_CHG_INT2_CHG_STA_TO),
> + REGMAP_IRQ_REG(MAX77759_CHGR_INT2_CHG_STA_DONE, 1,
> + MAX77759_CHGR_REG_CHG_INT2_CHG_STA_DONE),
Can I suggest using the 100-char limit to expand and neaten these up a bit.
> };
>
> static const struct regmap_irq_chip max77759_pmic_irq_chip = {
> @@ -297,11 +357,12 @@ static const struct regmap_irq_chip max77759_topsys_irq_chip = {
> .num_irqs = ARRAY_SIZE(max77759_topsys_irqs),
> };
>
> -static const struct regmap_irq_chip max77759_chrg_irq_chip = {
> +static const struct regmap_irq_chip max77759_chgr_irq_chip = {
This is a sneaky change. If you're going to bundle fixes like this, at
least drop a mention in the commit message.
> .name = "max77759-chgr",
> .domain_suffix = "CHGR",
> .status_base = MAX77759_CHGR_REG_CHG_INT,
> .mask_base = MAX77759_CHGR_REG_CHG_INT_MASK,
> + .ack_base = MAX77759_CHGR_REG_CHG_INT,
> .num_regs = 2,
> .irqs = max77759_chgr_irqs,
> .num_irqs = ARRAY_SIZE(max77759_chgr_irqs),
> @@ -325,8 +386,22 @@ static const struct resource max77759_gpio_resources[] = {
> };
>
> static const struct resource max77759_charger_resources[] = {
> - DEFINE_RES_IRQ_NAMED(MAX77759_CHARGER_INT_1, "INT1"),
> - DEFINE_RES_IRQ_NAMED(MAX77759_CHARGER_INT_2, "INT2"),
> + DEFINE_RES_IRQ_NAMED(MAX77759_CHGR_INT1_AICL, "AICL"),
> + DEFINE_RES_IRQ_NAMED(MAX77759_CHGR_INT1_CHGIN, "CHGIN"),
> + DEFINE_RES_IRQ_NAMED(MAX77759_CHGR_INT1_WCIN, "WCIN"),
> + DEFINE_RES_IRQ_NAMED(MAX77759_CHGR_INT1_CHG, "CHG"),
> + DEFINE_RES_IRQ_NAMED(MAX77759_CHGR_INT1_BAT, "BAT"),
> + DEFINE_RES_IRQ_NAMED(MAX77759_CHGR_INT1_INLIM, "INLIM"),
> + DEFINE_RES_IRQ_NAMED(MAX77759_CHGR_INT1_THM2, "THM2"),
> + DEFINE_RES_IRQ_NAMED(MAX77759_CHGR_INT1_BYP, "BYP"),
> + DEFINE_RES_IRQ_NAMED(MAX77759_CHGR_INT2_INSEL, "INSEL"),
> + DEFINE_RES_IRQ_NAMED(MAX77759_CHGR_INT2_SYS_UVLO1, "SYS_UVLO1"),
> + DEFINE_RES_IRQ_NAMED(MAX77759_CHGR_INT2_SYS_UVLO2, "SYS_UVLO2"),
> + DEFINE_RES_IRQ_NAMED(MAX77759_CHGR_INT2_BAT_OILO, "BAT_OILO"),
> + DEFINE_RES_IRQ_NAMED(MAX77759_CHGR_INT2_CHG_STA_CC, "CHG_STA_CC"),
> + DEFINE_RES_IRQ_NAMED(MAX77759_CHGR_INT2_CHG_STA_CV, "CHG_STA_CV"),
> + DEFINE_RES_IRQ_NAMED(MAX77759_CHGR_INT2_CHG_STA_TO, "CHG_STA_TO"),
> + DEFINE_RES_IRQ_NAMED(MAX77759_CHGR_INT2_CHG_STA_DONE, "CHG_STA_DONE"),
> };
>
> static const struct mfd_cell max77759_cells[] = {
> @@ -567,7 +642,7 @@ static int max77759_add_chained_charger(struct i2c_client *client,
> max77759->regmap_charger,
> MAX77759_INT_CHGR,
> parent,
> - &max77759_chrg_irq_chip,
> + &max77759_chgr_irq_chip,
> &irq_chip_data);
> if (ret)
> return ret;
> diff --git a/include/linux/mfd/max77759.h b/include/linux/mfd/max77759.h
> index c6face34e385..ec19be952877 100644
> --- a/include/linux/mfd/max77759.h
> +++ b/include/linux/mfd/max77759.h
> @@ -59,35 +59,65 @@
> #define MAX77759_MAXQ_REG_AP_DATAIN0 0xb1
> #define MAX77759_MAXQ_REG_UIC_SWRST 0xe0
>
> -#define MAX77759_CHGR_REG_CHG_INT 0xb0
> -#define MAX77759_CHGR_REG_CHG_INT2 0xb1
> -#define MAX77759_CHGR_REG_CHG_INT_MASK 0xb2
> -#define MAX77759_CHGR_REG_CHG_INT2_MASK 0xb3
> -#define MAX77759_CHGR_REG_CHG_INT_OK 0xb4
> -#define MAX77759_CHGR_REG_CHG_DETAILS_00 0xb5
> -#define MAX77759_CHGR_REG_CHG_DETAILS_01 0xb6
> -#define MAX77759_CHGR_REG_CHG_DETAILS_02 0xb7
> -#define MAX77759_CHGR_REG_CHG_DETAILS_03 0xb8
> -#define MAX77759_CHGR_REG_CHG_CNFG_00 0xb9
> -#define MAX77759_CHGR_REG_CHG_CNFG_01 0xba
> -#define MAX77759_CHGR_REG_CHG_CNFG_02 0xbb
> -#define MAX77759_CHGR_REG_CHG_CNFG_03 0xbc
> -#define MAX77759_CHGR_REG_CHG_CNFG_04 0xbd
> -#define MAX77759_CHGR_REG_CHG_CNFG_05 0xbe
> -#define MAX77759_CHGR_REG_CHG_CNFG_06 0xbf
> -#define MAX77759_CHGR_REG_CHG_CNFG_07 0xc0
> -#define MAX77759_CHGR_REG_CHG_CNFG_08 0xc1
> -#define MAX77759_CHGR_REG_CHG_CNFG_09 0xc2
> -#define MAX77759_CHGR_REG_CHG_CNFG_10 0xc3
> -#define MAX77759_CHGR_REG_CHG_CNFG_11 0xc4
> -#define MAX77759_CHGR_REG_CHG_CNFG_12 0xc5
> -#define MAX77759_CHGR_REG_CHG_CNFG_13 0xc6
> -#define MAX77759_CHGR_REG_CHG_CNFG_14 0xc7
> -#define MAX77759_CHGR_REG_CHG_CNFG_15 0xc8
> -#define MAX77759_CHGR_REG_CHG_CNFG_16 0xc9
> -#define MAX77759_CHGR_REG_CHG_CNFG_17 0xca
> -#define MAX77759_CHGR_REG_CHG_CNFG_18 0xcb
> -#define MAX77759_CHGR_REG_CHG_CNFG_19 0xcc
> +#define MAX77759_CHGR_REG_CHG_INT 0xb0
> +#define MAX77759_CHGR_REG_CHG_INT_AICL BIT(7)
> +#define MAX77759_CHGR_REG_CHG_INT_CHGIN BIT(6)
> +#define MAX77759_CHGR_REG_CHG_INT_WCIN BIT(5)
> +#define MAX77759_CHGR_REG_CHG_INT_CHG BIT(4)
> +#define MAX77759_CHGR_REG_CHG_INT_BAT BIT(3)
> +#define MAX77759_CHGR_REG_CHG_INT_INLIM BIT(2)
> +#define MAX77759_CHGR_REG_CHG_INT_THM2 BIT(1)
> +#define MAX77759_CHGR_REG_CHG_INT_BYP BIT(0)
> +#define MAX77759_CHGR_REG_CHG_INT2 0xb1
> +#define MAX77759_CHGR_REG_CHG_INT2_INSEL BIT(7)
> +#define MAX77759_CHGR_REG_CHG_INT2_SYS_UVLO1 BIT(6)
> +#define MAX77759_CHGR_REG_CHG_INT2_SYS_UVLO2 BIT(5)
> +#define MAX77759_CHGR_REG_CHG_INT2_BAT_OILO BIT(4)
> +#define MAX77759_CHGR_REG_CHG_INT2_CHG_STA_CC BIT(3)
> +#define MAX77759_CHGR_REG_CHG_INT2_CHG_STA_CV BIT(2)
> +#define MAX77759_CHGR_REG_CHG_INT2_CHG_STA_TO BIT(1)
> +#define MAX77759_CHGR_REG_CHG_INT2_CHG_STA_DONE BIT(0)
> +#define MAX77759_CHGR_REG_CHG_INT_MASK 0xb2
> +#define MAX77759_CHGR_REG_CHG_INT2_MASK 0xb3
> +#define MAX77759_CHGR_REG_CHG_INT_OK 0xb4
> +#define MAX77759_CHGR_REG_CHG_DETAILS_00 0xb5
> +#define MAX77759_CHGR_REG_CHG_DETAILS_00_CHGIN_DTLS GENMASK(6, 5)
> +#define MAX77759_CHGR_REG_CHG_DETAILS_01 0xb6
> +#define MAX77759_CHGR_REG_CHG_DETAILS_01_BAT_DTLS GENMASK(6, 4)
> +#define MAX77759_CHGR_REG_CHG_DETAILS_01_CHG_DTLS GENMASK(3, 0)
> +#define MAX77759_CHGR_REG_CHG_DETAILS_02 0xb7
> +#define MAX77759_CHGR_REG_CHG_DETAILS_02_CHGIN_STS BIT(5)
> +#define MAX77759_CHGR_REG_CHG_DETAILS_03 0xb8
> +#define MAX77759_CHGR_REG_CHG_CNFG_00 0xb9
> +#define MAX77759_CHGR_REG_CHG_CNFG_00_MODE GENMASK(3, 0)
> +#define MAX77759_CHGR_REG_CHG_CNFG_01 0xba
> +#define MAX77759_CHGR_REG_CHG_CNFG_02 0xbb
> +#define MAX77759_CHGR_REG_CHG_CNFG_02_CHGCC GENMASK(5, 0)
> +#define MAX77759_CHGR_REG_CHG_CNFG_03 0xbc
> +#define MAX77759_CHGR_REG_CHG_CNFG_04 0xbd
> +#define MAX77759_CHGR_REG_CHG_CNFG_04_CHG_CV_PRM GENMASK(5, 0)
> +#define MAX77759_CHGR_REG_CHG_CNFG_05 0xbe
> +#define MAX77759_CHGR_REG_CHG_CNFG_06 0xbf
> +#define MAX77759_CHGR_REG_CHG_CNFG_06_CHGPROT GENMASK(3, 2)
> +#define MAX77759_CHGR_REG_CHG_CNFG_07 0xc0
> +#define MAX77759_CHGR_REG_CHG_CNFG_08 0xc1
> +#define MAX77759_CHGR_REG_CHG_CNFG_09 0xc2
> +#define MAX77759_CHGR_REG_CHG_CNFG_09_CHGIN_ILIM GENMASK(6, 0)
> +#define MAX77759_CHGR_REG_CHG_CNFG_10 0xc3
> +#define MAX77759_CHGR_REG_CHG_CNFG_11 0xc4
> +#define MAX77759_CHGR_REG_CHG_CNFG_12 0xc5
> +/* Wireless Charging input channel select */
> +#define MAX77759_CHGR_REG_CHG_CNFG_12_WCINSEL BIT(6)
> +/* CHGIN/USB input channel select */
> +#define MAX77759_CHGR_REG_CHG_CNFG_12_CHGINSEL BIT(5)
Should we ensure these comments are formatted as complete sentences with a full
stop at the end, to comply with our documentation guidelines?
> +#define MAX77759_CHGR_REG_CHG_CNFG_13 0xc6
> +#define MAX77759_CHGR_REG_CHG_CNFG_14 0xc7
> +#define MAX77759_CHGR_REG_CHG_CNFG_15 0xc8
> +#define MAX77759_CHGR_REG_CHG_CNFG_16 0xc9
> +#define MAX77759_CHGR_REG_CHG_CNFG_17 0xca
> +#define MAX77759_CHGR_REG_CHG_CNFG_18 0xcb
> +#define MAX77759_CHGR_REG_CHG_CNFG_18_WDTEN BIT(0)
> +#define MAX77759_CHGR_REG_CHG_CNFG_19 0xcc
>
> /* MaxQ opcodes for max77759_maxq_command() */
> #define MAX77759_MAXQ_OPCODE_MAXLENGTH (MAX77759_MAXQ_REG_AP_DATAOUT32 - \
> @@ -101,6 +131,84 @@
> #define MAX77759_MAXQ_OPCODE_USER_SPACE_READ 0x81
> #define MAX77759_MAXQ_OPCODE_USER_SPACE_WRITE 0x82
>
> +/**
> + * enum max77759_chgr_chgin_dtls_status - Charger Input Status
> + * @MAX77759_CHGR_CHGIN_DTLS_VBUS_UNDERVOLTAGE:
> + * Charger input voltage (Vchgin) < Under Voltage Threshold (Vuvlo)
> + * @MAX77759_CHGR_CHGIN_DTLS_VBUS_MARGINAL_VOLTAGE:
> + * Vchgin > Vuvlo and Vchgin < (Battery Voltage (Vbatt) + system voltage (Vsys))
> + * @MAX77759_CHGR_CHGIN_DTLS_VBUS_OVERVOLTAGE:
> + * Vchgin > Over Voltage threshold (Vovlo)
> + * @MAX77759_CHGR_CHGIN_DTLS_VBUS_VALID:
> + * Vchgin > Vuvlo, Vchgin < Vovlo and Vchgin > (Vsys + Vbatt)
> + */
> +enum max77759_chgr_chgin_dtls_status {
> + MAX77759_CHGR_CHGIN_DTLS_VBUS_UNDERVOLTAGE,
> + MAX77759_CHGR_CHGIN_DTLS_VBUS_MARGINAL_VOLTAGE,
> + MAX77759_CHGR_CHGIN_DTLS_VBUS_OVERVOLTAGE,
> + MAX77759_CHGR_CHGIN_DTLS_VBUS_VALID,
> +};
> +
> +/**
> + * enum max77759_chgr_bat_dtls_states - Battery Details
> + * @MAX77759_CHGR_BAT_DTLS_NO_BATT_CHG_SUSP: No battery and the charger suspended
> + * @MAX77759_CHGR_BAT_DTLS_DEAD_BATTERY: Vbatt < Vtrickle
> + * @MAX77759_CHGR_BAT_DTLS_BAT_CHG_TIMER_FAULT: Charging suspended due to timer fault
> + * @MAX77759_CHGR_BAT_DTLS_BAT_OKAY: Battery okay and Vbatt > Min Sys Voltage (Vsysmin)
> + * @MAX77759_CHGR_BAT_DTLS_BAT_UNDERVOLTAGE: Battery is okay. Vtrickle < Vbatt < Vsysmin
> + * @MAX77759_CHGR_BAT_DTLS_BAT_OVERVOLTAGE: Battery voltage > Overvoltage threshold
> + * @MAX77759_CHGR_BAT_DTLS_BAT_OVERCURRENT: Battery current exceeds overcurrent threshold
> + * @MAX77759_CHGR_BAT_DTLS_BAT_ONLY_MODE: Battery only mode and battery level not available
> + */
> +enum max77759_chgr_bat_dtls_states {
> + MAX77759_CHGR_BAT_DTLS_NO_BATT_CHG_SUSP,
> + MAX77759_CHGR_BAT_DTLS_DEAD_BATTERY,
> + MAX77759_CHGR_BAT_DTLS_BAT_CHG_TIMER_FAULT,
> + MAX77759_CHGR_BAT_DTLS_BAT_OKAY,
> + MAX77759_CHGR_BAT_DTLS_BAT_UNDERVOLTAGE,
> + MAX77759_CHGR_BAT_DTLS_BAT_OVERVOLTAGE,
> + MAX77759_CHGR_BAT_DTLS_BAT_OVERCURRENT,
> + MAX77759_CHGR_BAT_DTLS_BAT_ONLY_MODE,
> +};
> +
> +/**
> + * enum max77759_chgr_chg_dtls_states - Charger Details
> + * @MAX77759_CHGR_CHG_DTLS_PREQUAL: Charger in prequalification mode
> + * @MAX77759_CHGR_CHG_DTLS_CC: Charger in fast charge const curr mode
> + * @MAX77759_CHGR_CHG_DTLS_CV: Charger in fast charge const voltage mode
> + * @MAX77759_CHGR_CHG_DTLS_TO: Charger is in top off mode
> + * @MAX77759_CHGR_CHG_DTLS_DONE: Charger is done
> + * @MAX77759_CHGR_CHG_DTLS_RSVD_1: Reserved
> + * @MAX77759_CHGR_CHG_DTLS_TIMER_FAULT: Charger is in timer fault mode
> + * @MAX77759_CHGR_CHG_DTLS_SUSP_BATT_THM: Charger is suspended as battery removal detected
> + * @MAX77759_CHGR_CHG_DTLS_OFF: Charger is off. Input invalid or charger disabled
> + * @MAX77759_CHGR_CHG_DTLS_RSVD_2: Reserved
> + * @MAX77759_CHGR_CHG_DTLS_RSVD_3: Reserved
> + * @MAX77759_CHGR_CHG_DTLS_OFF_WDOG_TIMER: Charger is off as watchdog timer expired
> + * @MAX77759_CHGR_CHG_DTLS_SUSP_JEITA: Charger is in JEITA control mode
> + */
> +enum max77759_chgr_chg_dtls_states {
> + MAX77759_CHGR_CHG_DTLS_PREQUAL,
> + MAX77759_CHGR_CHG_DTLS_CC,
> + MAX77759_CHGR_CHG_DTLS_CV,
> + MAX77759_CHGR_CHG_DTLS_TO,
> + MAX77759_CHGR_CHG_DTLS_DONE,
> + MAX77759_CHGR_CHG_DTLS_RSVD_1,
> + MAX77759_CHGR_CHG_DTLS_TIMER_FAULT,
> + MAX77759_CHGR_CHG_DTLS_SUSP_BATT_THM,
> + MAX77759_CHGR_CHG_DTLS_OFF,
> + MAX77759_CHGR_CHG_DTLS_RSVD_2,
> + MAX77759_CHGR_CHG_DTLS_RSVD_3,
> + MAX77759_CHGR_CHG_DTLS_OFF_WDOG_TIMER,
> + MAX77759_CHGR_CHG_DTLS_SUSP_JEITA,
> +};
> +
> +enum max77759_chgr_mode {
> + MAX77759_CHGR_MODE_OFF,
> + MAX77759_CHGR_MODE_CHG_BUCK_ON = 0x5,
> + MAX77759_CHGR_MODE_OTG_BOOST_ON = 0xA,
> +};
Would it be safer to explicitly initialise 'MAX77759_CHGR_MODE_OFF' to 0 here?
Relying on implicit zero initialisation whilst explicitly setting other values
can sometimes lead to unexpected behaviour if new entries are added.
--
Lee Jones
^ permalink raw reply
* Re: [REGRESSION] rseq: refactoring in v6.19 broke everyone on arm64 and tcmalloc everywhere
From: Mathias Stearn @ 2026-04-24 8:32 UTC (permalink / raw)
To: Dmitry Vyukov
Cc: Thomas Gleixner, Jinjie Ruan, linux-man, Mark Rutland,
Mathieu Desnoyers, Catalin Marinas, Will Deacon, Boqun Feng,
Paul E. McKenney, Chris Kennelly, regressions, linux-kernel,
linux-arm-kernel, Peter Zijlstra, Ingo Molnar, Blake Oler
In-Reply-To: <CACT4Y+bBD7uCHXKqGo=epBXeEmsZ67Og2YO9kjNMT3ryjUY_sA@mail.gmail.com>
On Fri, Apr 24, 2026 at 9:57 AM Dmitry Vyukov <dvyukov@google.com> wrote:
> > So if the code only requires to know when it got rescheduled to another
> > CPU then it still should work, no?
>
> This was my first thought too:
> https://lore.kernel.org/lkml/CACT4Y+a9GnOh3wHKSRwzoKF6_OSksQ8qehnHfpCgkQSt_OOmYg@mail.gmail.com/
> The only problem is with membarrier (it used to force write to
> __rseq_abi.cpu_id_start for all threads, but now it does not).
> Otherwise the caching scheme works.
I almost wrote a message last night saying that we didn't need
cpu_id_start invalidation on preemption. However, I remembered that
the Grow() function[1] does a load outside of a critical section then
stores a derived value inside the critical section, guarded only by
the cpu_id_start invalidation check in StoreCurrentCpu[2]. It really
should be doing a compare against the original value inside the
critical section (or just do the whole thing inside), but it doesn't.
I haven't reasoned end-to-end through this fully to prove corruption
is possible, but I suspect that it is if another thread same-cpu
preempts between the loads and the store and updates the header before
the original thread resumes and writes its original intended header
value. Ditto for signals, which sometimes allocate even though they
shouldn't.
I was really hoping that we would only need to do the "redundant"
cpu_id_start writes would only be needed on membarrier_rseq IPIs where
it really is a pay-for-what-you-use functionality, I think existing
binaries depend on invalidation on preemption. Luckily that should be
cheap enough to be ~free.
[1] https://github.com/google/tcmalloc/blob/8e98046ec5639bffbe70a53770a2699dd355b26d/tcmalloc/internal/percpu_tcmalloc.h#L964-L980
[2] https://github.com/google/tcmalloc/blob/8e98046ec5639bffbe70a53770a2699dd355b26d/tcmalloc/internal/percpu_tcmalloc.h#L551-L605
^ permalink raw reply
* Re: [PATCH v2 15/20] drm/drv: Call drm_mode_config_create_state() by default
From: Maxime Ripard @ 2026-04-24 8:44 UTC (permalink / raw)
To: Thomas Zimmermann
Cc: Maarten Lankhorst, David Airlie, Simona Vetter, Jonathan Corbet,
Shuah Khan, Dmitry Baryshkov, Jyri Sarha, Tomi Valkeinen,
Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
Jonas Karlman, Jernej Skrabec, Simon Ser, Harry Wentland,
Melissa Wen, Sebastian Wick, Alex Hung, Jani Nikula, Rodrigo Vivi,
Joonas Lahtinen, Tvrtko Ursulin, Chen-Yu Tsai, Samuel Holland,
Dave Stevenson, Maíra Canal, Raspberry Pi Kernel Maintenance,
dri-devel, linux-doc, linux-kernel, Daniel Stone, intel-gfx,
intel-xe, linux-arm-kernel, linux-sunxi
In-Reply-To: <79cc30d5-80b5-4d87-a3ad-36d6fad98853@suse.de>
[-- Attachment #1: Type: text/plain, Size: 2088 bytes --]
Hi,
On Tue, Apr 21, 2026 at 03:38:16PM +0200, Thomas Zimmermann wrote:
> Am 20.03.26 um 17:27 schrieb Maxime Ripard:
> > Almost all drivers, and our documented skeleton, call
> > drm_mode_config_reset() prior to calling drm_dev_register() to
> > initialize its DRM object states.
> >
> > Now that we have drm_mode_config_create_state() to create that initial
> > state if it doesn't exist, we can call it directly in
> > drm_dev_register(). That way, we know that the initial atomic state will
> > always be allocated without any boilerplate.
> >
> > Signed-off-by: Maxime Ripard <mripard@kernel.org>
> > ---
> > drivers/gpu/drm/drm_drv.c | 4 ++++
> > 1 file changed, 4 insertions(+)
> >
> > diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
> > index 2915118436ce8a6640cfb0c59936031990727ed1..820106d56ab399a39cac56d98662b5ddbcae8ded 100644
> > --- a/drivers/gpu/drm/drm_drv.c
> > +++ b/drivers/gpu/drm/drm_drv.c
> > @@ -1097,10 +1097,14 @@ int drm_dev_register(struct drm_device *dev, unsigned long flags)
> > if (drm_core_check_feature(dev, DRIVER_MODESET)) {
> > ret = drm_modeset_register_all(dev);
> > if (ret)
> > goto err_unload;
> > +
> > + ret = drm_mode_config_create_state(dev);
> > + if (ret)
> > + goto err_unload;
>
> Way too late.
Yeah... I think that was Ville's main objection too.
> Lets rather go through drivers and call this where they currently call
> drm_mode_config_reset() for initialization.
I was really hoping to remove the boilerplate from drivers, but I don't
really see a good place for it then. drm_mode_config_init() could be
another candidate, but it looks weird to put it there too.
I'll drop that then.
> This can be a single-patch mass conversion IMHO.
I'm not really sure? For it to work we'd need to convert these drivers
objects from reset to atomic_create_state too. I absolutely want to do
it next, but I don't think it will be as trivial as a sed call, and it
would probably be best done by driver to allow reverts if we screw up.
Maxime
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 273 bytes --]
^ permalink raw reply
* [PATCH 0/6] KVM: arm64: pKVM init and feature detection fixes
From: Fuad Tabba @ 2026-04-24 8:49 UTC (permalink / raw)
To: kvmarm, linux-arm-kernel, linux-kernel
Cc: tabba, catalin.marinas, will, maz, oupton, qperret,
suzuki.poulose, joey.gouly, yuzenghui
Hi folks,
These six patches are standalone correctness fixes I'd like to land
before posting a follow-up to Will's pKVM infrastructure series [1]
that moves vCPU state management to EL2. Sending them separately keeps
the bigger series focused, but they are all valid fixes to have
regardless.
The first patch fixes feature detection for FEAT_Debugv8p9: it was
checking the wrong field in ID_AA64DFR0_EL1, causing KVM to treat
certain EL2 control bits as RES0 on hardware that implements the
feature.
The second patch is a trivial typo fix in comments.
The third patch fixes feature detection for FEAT_SPE_FnE, which was
also checking the wrong field.
The last three fix bugs in the pKVM vCPU and hypervisor initialisation
paths: a latent macro parameter bug, a pin-reference leak with a
publication ordering issue in __pkvm_init_vcpu(), and a call-ordering
hazard in __pkvm_init_finalise() that is benign today but becomes a
crash once fix_host_ownership() is extended to operate on a non-empty
page-table.
[1] https://lore.kernel.org/all/20260105154939.11041-1-will@kernel.org/
Cheers,
/fuad
Fuad Tabba (5):
KVM: arm64: Fix FEAT_Debugv8p9 to check DebugVer, not PMUVer
KVM: arm64: Fix typo in feature check comments
KVM: arm64: Fix FEAT_SPE_FnE to use PMSIDR_EL1.FnE, not PMSVer
KVM: arm64: Fix kvm_vcpu_initialized() macro parameter
KVM: arm64: Fix pin leak and publication ordering in
__pkvm_init_vcpu()
Quentin Perret (1):
KVM: arm64: Fix initialisation order in __pkvm_init_finalise()
arch/arm64/include/asm/kvm_host.h | 2 +-
arch/arm64/kvm/config.c | 23 +++++++++++++------
arch/arm64/kvm/hyp/nvhe/pkvm.c | 38 ++++++++++++++++++++-----------
arch/arm64/kvm/hyp/nvhe/setup.c | 8 +++----
4 files changed, 46 insertions(+), 25 deletions(-)
--
2.54.0.rc2.544.gc7ae2d5bb8-goog
^ permalink raw reply
* [PATCH 1/6] KVM: arm64: Fix FEAT_Debugv8p9 to check DebugVer, not PMUVer
From: Fuad Tabba @ 2026-04-24 8:49 UTC (permalink / raw)
To: kvmarm, linux-arm-kernel, linux-kernel
Cc: tabba, catalin.marinas, will, maz, oupton, qperret,
suzuki.poulose, joey.gouly, yuzenghui
In-Reply-To: <20260424084908.370776-1-tabba@google.com>
FEAT_Debugv8p9 is incorrectly defined against ID_AA64DFR0_EL1.PMUVer
instead of ID_AA64DFR0_EL1.DebugVer. All three consumers of the macro
gate features that are architecturally tied to FEAT_Debugv8p9
(DebugVer = 0b1011, DDI0487 M.b A2.2.10):
- HDFGRTR2_EL2.nMDSELR_EL1, HDFGWTR2_EL2.nMDSELR_EL1: MDSELR_EL1
is present only when FEAT_Debugv8p9 is implemented (D24.3.21).
- MDCR_EL2.EBWE: the Extended Breakpoint and Watchpoint Enable bit
is RES0 unless FEAT_Debugv8p9 is implemented (D24.3.17).
Neither register has any dependency on PMUVer.
FEAT_Debugv8p9 and FEAT_PMUv3p9 are independent. Per DDI0487 M.b
A2.2.10, FEAT_Debugv8p9 is unconditionally mandatory from Armv8.9,
whereas FEAT_PMUv3p9 is mandatory only when FEAT_PMUv3 is implemented.
An Armv8.9 CPU without a PMU has DebugVer = 0b1011 but PMUVer = 0b0000,
so the wrong field check would cause KVM to incorrectly treat EBWE and
MDSELR_EL1 as RES0 on such hardware.
Fixes: 4bc0fe089840 ("KVM: arm64: Add sanitisation for FEAT_FGT2 registers")
Signed-off-by: Fuad Tabba <tabba@google.com>
---
arch/arm64/kvm/config.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm64/kvm/config.c b/arch/arm64/kvm/config.c
index f35b8dddd7c1..093290b366e6 100644
--- a/arch/arm64/kvm/config.c
+++ b/arch/arm64/kvm/config.c
@@ -192,7 +192,7 @@ struct reg_feat_map_desc {
#define FEAT_SRMASK ID_AA64MMFR4_EL1, SRMASK, IMP
#define FEAT_PoPS ID_AA64MMFR4_EL1, PoPS, IMP
#define FEAT_PFAR ID_AA64PFR1_EL1, PFAR, IMP
-#define FEAT_Debugv8p9 ID_AA64DFR0_EL1, PMUVer, V3P9
+#define FEAT_Debugv8p9 ID_AA64DFR0_EL1, DebugVer, V8P9
#define FEAT_PMUv3_SS ID_AA64DFR0_EL1, PMSS, IMP
#define FEAT_SEBEP ID_AA64DFR0_EL1, SEBEP, IMP
#define FEAT_EBEP ID_AA64DFR1_EL1, EBEP, IMP
--
2.54.0.rc2.544.gc7ae2d5bb8-goog
^ permalink raw reply related
* [PATCH 3/6] KVM: arm64: Fix FEAT_SPE_FnE to use PMSIDR_EL1.FnE, not PMSVer
From: Fuad Tabba @ 2026-04-24 8:49 UTC (permalink / raw)
To: kvmarm, linux-arm-kernel, linux-kernel
Cc: tabba, catalin.marinas, will, maz, oupton, qperret,
suzuki.poulose, joey.gouly, yuzenghui
In-Reply-To: <20260424084908.370776-1-tabba@google.com>
FEAT_SPE_FnE is architecturally detected via PMSIDR_EL1.FnE [6], not
ID_AA64DFR0_EL1.PMSVer. The FEAT_X macro form (register, field, value)
cannot encode a PMSIDR_EL1-based feature, so FEAT_SPE_FnE was defined
identically to FEAT_SPEv1p2 (ID_AA64DFR0_EL1, PMSVer, V1P2), producing
a duplicate that used PMSVer >= V1P2 as a proxy.
Replace the macro with feat_spe_fne(), following the same pattern as
the sibling feat_spe_fds(): guard on FEAT_SPEv1p2 and read
PMSIDR_EL1.FnE [6] directly. Wire the two NEEDS_FEAT consumers to use
the new function.
Remove the now-unused FEAT_SPE_FnE macro.
Fixes: 63d423a7635b ("KVM: arm64: Switch to table-driven FGU configuration")
Signed-off-by: Fuad Tabba <tabba@google.com>
---
arch/arm64/kvm/config.c | 15 ++++++++++++---
1 file changed, 12 insertions(+), 3 deletions(-)
diff --git a/arch/arm64/kvm/config.c b/arch/arm64/kvm/config.c
index a722ea178f68..0622162b089e 100644
--- a/arch/arm64/kvm/config.c
+++ b/arch/arm64/kvm/config.c
@@ -131,7 +131,6 @@ struct reg_feat_map_desc {
}
#define FEAT_SPE ID_AA64DFR0_EL1, PMSVer, IMP
-#define FEAT_SPE_FnE ID_AA64DFR0_EL1, PMSVer, V1P2
#define FEAT_BRBE ID_AA64DFR0_EL1, BRBE, IMP
#define FEAT_TRC_SR ID_AA64DFR0_EL1, TraceVer, IMP
#define FEAT_PMUv3 ID_AA64DFR0_EL1, PMUVer, IMP
@@ -302,6 +301,16 @@ static bool feat_spe_fds(struct kvm *kvm)
(read_sysreg_s(SYS_PMSIDR_EL1) & PMSIDR_EL1_FDS));
}
+static bool feat_spe_fne(struct kvm *kvm)
+{
+ /*
+ * Revisit this if KVM ever supports SPE -- this really should
+ * look at the guest's view of PMSIDR_EL1.
+ */
+ return (kvm_has_feat(kvm, FEAT_SPEv1p2) &&
+ (read_sysreg_s(SYS_PMSIDR_EL1) & PMSIDR_EL1_FnE));
+}
+
static bool feat_trbe_mpam(struct kvm *kvm)
{
/*
@@ -537,7 +546,7 @@ static const struct reg_bits_to_feat_map hdfgrtr_feat_map[] = {
HDFGRTR_EL2_PMBPTR_EL1 |
HDFGRTR_EL2_PMBLIMITR_EL1,
FEAT_SPE),
- NEEDS_FEAT(HDFGRTR_EL2_nPMSNEVFR_EL1, FEAT_SPE_FnE),
+ NEEDS_FEAT(HDFGRTR_EL2_nPMSNEVFR_EL1, feat_spe_fne),
NEEDS_FEAT(HDFGRTR_EL2_nBRBDATA |
HDFGRTR_EL2_nBRBCTL |
HDFGRTR_EL2_nBRBIDR,
@@ -605,7 +614,7 @@ static const struct reg_bits_to_feat_map hdfgwtr_feat_map[] = {
HDFGWTR_EL2_PMBPTR_EL1 |
HDFGWTR_EL2_PMBLIMITR_EL1,
FEAT_SPE),
- NEEDS_FEAT(HDFGWTR_EL2_nPMSNEVFR_EL1, FEAT_SPE_FnE),
+ NEEDS_FEAT(HDFGWTR_EL2_nPMSNEVFR_EL1, feat_spe_fne),
NEEDS_FEAT(HDFGWTR_EL2_nBRBDATA |
HDFGWTR_EL2_nBRBCTL,
FEAT_BRBE),
--
2.54.0.rc2.544.gc7ae2d5bb8-goog
^ permalink raw reply related
* [PATCH 5/6] KVM: arm64: Fix pin leak and publication ordering in __pkvm_init_vcpu()
From: Fuad Tabba @ 2026-04-24 8:49 UTC (permalink / raw)
To: kvmarm, linux-arm-kernel, linux-kernel
Cc: tabba, catalin.marinas, will, maz, oupton, qperret,
suzuki.poulose, joey.gouly, yuzenghui
In-Reply-To: <20260424084908.370776-1-tabba@google.com>
Two bugs exist in the vCPU initialisation path:
1. If a check fails after hyp_pin_shared_mem() succeeds, the cleanup
path jumps to 'unlock' without calling unpin_host_vcpu() or
unpin_host_sve_state(), permanently leaking pin references on the
host vCPU and SVE state pages.
Extract a register_hyp_vcpu() helper that performs the checks and
the store. When register_hyp_vcpu() returns an error, call
unpin_host_vcpu() and unpin_host_sve_state() inline before falling
through to the existing 'unlock' label.
2. register_hyp_vcpu() publishes the new vCPU pointer into
'hyp_vm->vcpus[]' with a bare store, allowing a concurrent caller
of pkvm_load_hyp_vcpu() to observe a partially initialised vCPU
object.
Ensure the store uses smp_store_release() and the load uses
smp_load_acquire(). While 'vm_table_lock' currently serialises the
store and the load, these barriers ensure the reader sees the fully
initialised 'hyp_vcpu' object even if there were a lockless path or
if the lock's own ordering guarantees were insufficient for nested
object initialization.
Fixes: 49af6ddb8e5c ("KVM: arm64: Add infrastructure to create and track pKVM instances at EL2")
Reported-by: Ben Simner <ben.simner@cl.cam.ac.uk>
Co-developed-by: Will Deacon <willdeacon@google.com>
Signed-off-by: Will Deacon <willdeacon@google.com>
Signed-off-by: Fuad Tabba <tabba@google.com>
---
arch/arm64/kvm/hyp/nvhe/pkvm.c | 38 ++++++++++++++++++++++------------
1 file changed, 25 insertions(+), 13 deletions(-)
diff --git a/arch/arm64/kvm/hyp/nvhe/pkvm.c b/arch/arm64/kvm/hyp/nvhe/pkvm.c
index 7ed96d64d611..e7496eb85628 100644
--- a/arch/arm64/kvm/hyp/nvhe/pkvm.c
+++ b/arch/arm64/kvm/hyp/nvhe/pkvm.c
@@ -266,7 +266,8 @@ struct pkvm_hyp_vcpu *pkvm_load_hyp_vcpu(pkvm_handle_t handle,
if (hyp_vm->kvm.created_vcpus <= vcpu_idx)
goto unlock;
- hyp_vcpu = hyp_vm->vcpus[vcpu_idx];
+ /* Pairs with smp_store_release() in register_hyp_vcpu(). */
+ hyp_vcpu = smp_load_acquire(&hyp_vm->vcpus[vcpu_idx]);
if (!hyp_vcpu)
goto unlock;
@@ -860,12 +861,30 @@ int __pkvm_init_vm(struct kvm *host_kvm, unsigned long vm_hva,
* the page-aligned size of 'struct pkvm_hyp_vcpu'.
* Return 0 on success, negative error code on failure.
*/
+static int register_hyp_vcpu(struct pkvm_hyp_vm *hyp_vm,
+ struct pkvm_hyp_vcpu *hyp_vcpu)
+{
+ unsigned int idx = hyp_vcpu->vcpu.vcpu_idx;
+
+ if (idx >= hyp_vm->kvm.created_vcpus)
+ return -EINVAL;
+
+ if (hyp_vm->vcpus[idx])
+ return -EINVAL;
+
+ /*
+ * Ensure the hyp_vcpu is initialised before publishing it to
+ * the vCPU-load path via 'hyp_vm->vcpus[]'.
+ */
+ smp_store_release(&hyp_vm->vcpus[idx], hyp_vcpu);
+ return 0;
+}
+
int __pkvm_init_vcpu(pkvm_handle_t handle, struct kvm_vcpu *host_vcpu,
unsigned long vcpu_hva)
{
struct pkvm_hyp_vcpu *hyp_vcpu;
struct pkvm_hyp_vm *hyp_vm;
- unsigned int idx;
int ret;
hyp_vcpu = map_donated_memory(vcpu_hva, sizeof(*hyp_vcpu));
@@ -884,18 +903,11 @@ int __pkvm_init_vcpu(pkvm_handle_t handle, struct kvm_vcpu *host_vcpu,
if (ret)
goto unlock;
- idx = hyp_vcpu->vcpu.vcpu_idx;
- if (idx >= hyp_vm->kvm.created_vcpus) {
- ret = -EINVAL;
- goto unlock;
+ ret = register_hyp_vcpu(hyp_vm, hyp_vcpu);
+ if (ret) {
+ unpin_host_vcpu(host_vcpu);
+ unpin_host_sve_state(hyp_vcpu);
}
-
- if (hyp_vm->vcpus[idx]) {
- ret = -EINVAL;
- goto unlock;
- }
-
- hyp_vm->vcpus[idx] = hyp_vcpu;
unlock:
hyp_spin_unlock(&vm_table_lock);
--
2.54.0.rc2.544.gc7ae2d5bb8-goog
^ permalink raw reply related
* [PATCH 4/6] KVM: arm64: Fix kvm_vcpu_initialized() macro parameter
From: Fuad Tabba @ 2026-04-24 8:49 UTC (permalink / raw)
To: kvmarm, linux-arm-kernel, linux-kernel
Cc: tabba, catalin.marinas, will, maz, oupton, qperret,
suzuki.poulose, joey.gouly, yuzenghui
In-Reply-To: <20260424084908.370776-1-tabba@google.com>
The macro is defined with parameter 'v' but the body references the
literal token 'vcpu' instead, causing it to silently operate on whatever
'vcpu' resolves to in the caller's scope rather than the value passed by
the caller. All current call sites happen to use a variable named 'vcpu',
so the bug is latent.
Fixes: e016333745c7 ("KVM: arm64: Only reset vCPU-scoped feature ID regs once")
Signed-off-by: Fuad Tabba <tabba@google.com>
---
arch/arm64/include/asm/kvm_host.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 851f6171751c..0e5dbc1c5879 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -1548,7 +1548,7 @@ static inline bool __vcpu_has_feature(const struct kvm_arch *ka, int feature)
#define kvm_vcpu_has_feature(k, f) __vcpu_has_feature(&(k)->arch, (f))
#define vcpu_has_feature(v, f) __vcpu_has_feature(&(v)->kvm->arch, (f))
-#define kvm_vcpu_initialized(v) vcpu_get_flag(vcpu, VCPU_INITIALIZED)
+#define kvm_vcpu_initialized(v) vcpu_get_flag(v, VCPU_INITIALIZED)
int kvm_trng_call(struct kvm_vcpu *vcpu);
#ifdef CONFIG_KVM
--
2.54.0.rc2.544.gc7ae2d5bb8-goog
^ permalink raw reply related
* [PATCH 2/6] KVM: arm64: Fix typo in feature check comments
From: Fuad Tabba @ 2026-04-24 8:49 UTC (permalink / raw)
To: kvmarm, linux-arm-kernel, linux-kernel
Cc: tabba, catalin.marinas, will, maz, oupton, qperret,
suzuki.poulose, joey.gouly, yuzenghui
In-Reply-To: <20260424084908.370776-1-tabba@google.com>
Revists -> Revisit. The following patch will add another similar line.
No functional change intended.
Signed-off-by: Fuad Tabba <tabba@google.com>
---
arch/arm64/kvm/config.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/arch/arm64/kvm/config.c b/arch/arm64/kvm/config.c
index 093290b366e6..a722ea178f68 100644
--- a/arch/arm64/kvm/config.c
+++ b/arch/arm64/kvm/config.c
@@ -283,7 +283,7 @@ static bool feat_anerr(struct kvm *kvm)
static bool feat_sme_smps(struct kvm *kvm)
{
/*
- * Revists this if KVM ever supports SME -- this really should
+ * Revisit this if KVM ever supports SME -- this really should
* look at the guest's view of SMIDR_EL1. Funnily enough, this
* is not captured in the JSON file, but only as a note in the
* ARM ARM.
@@ -295,7 +295,7 @@ static bool feat_sme_smps(struct kvm *kvm)
static bool feat_spe_fds(struct kvm *kvm)
{
/*
- * Revists this if KVM ever supports SPE -- this really should
+ * Revisit this if KVM ever supports SPE -- this really should
* look at the guest's view of PMSIDR_EL1.
*/
return (kvm_has_feat(kvm, FEAT_SPEv1p4) &&
@@ -305,7 +305,7 @@ static bool feat_spe_fds(struct kvm *kvm)
static bool feat_trbe_mpam(struct kvm *kvm)
{
/*
- * Revists this if KVM ever supports both MPAM and TRBE --
+ * Revisit this if KVM ever supports both MPAM and TRBE --
* this really should look at the guest's view of TRBIDR_EL1.
*/
return (kvm_has_feat(kvm, FEAT_TRBE) &&
--
2.54.0.rc2.544.gc7ae2d5bb8-goog
^ permalink raw reply related
* [PATCH 6/6] KVM: arm64: Fix initialisation order in __pkvm_init_finalise()
From: Fuad Tabba @ 2026-04-24 8:49 UTC (permalink / raw)
To: kvmarm, linux-arm-kernel, linux-kernel
Cc: tabba, catalin.marinas, will, maz, oupton, qperret,
suzuki.poulose, joey.gouly, yuzenghui
In-Reply-To: <20260424084908.370776-1-tabba@google.com>
From: Quentin Perret <qperret@google.com>
fix_host_ownership() walks the hypervisor's stage-1 page-table to
adjust the host's stage-2 accordingly. Any such adjustment that
requires cache maintenance operations depends on the per-CPU hyp
fixmap being present. However, fix_host_ownership() is currently
called before fix_hyp_pgtable_refcnt() and hyp_create_fixmap(), so
the fixmap does not yet exist when it runs.
This is benign today because the host stage-2 starts empty and no
CMOs are needed, but it becomes a latent crash as soon as
fix_host_ownership() is extended to operate on a non-empty
page-table.
Reorder the calls so that fix_hyp_pgtable_refcnt() and
hyp_create_fixmap() complete before fix_host_ownership() is invoked.
Fixes: 0d16d12eb26e ("KVM: arm64: Fix-up hyp stage-1 refcounts for all pages mapped at EL2")
Signed-off-by: Quentin Perret <qperret@google.com>
Signed-off-by: Fuad Tabba <tabba@google.com>
---
arch/arm64/kvm/hyp/nvhe/setup.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/arch/arm64/kvm/hyp/nvhe/setup.c b/arch/arm64/kvm/hyp/nvhe/setup.c
index d8e5b563fd3d..d461981616d9 100644
--- a/arch/arm64/kvm/hyp/nvhe/setup.c
+++ b/arch/arm64/kvm/hyp/nvhe/setup.c
@@ -312,10 +312,6 @@ void __noreturn __pkvm_init_finalise(void)
};
pkvm_pgtable.mm_ops = &pkvm_pgtable_mm_ops;
- ret = fix_host_ownership();
- if (ret)
- goto out;
-
ret = fix_hyp_pgtable_refcnt();
if (ret)
goto out;
@@ -324,6 +320,10 @@ void __noreturn __pkvm_init_finalise(void)
if (ret)
goto out;
+ ret = fix_host_ownership();
+ if (ret)
+ goto out;
+
ret = hyp_ffa_init(ffa_proxy_pages);
if (ret)
goto out;
--
2.54.0.rc2.544.gc7ae2d5bb8-goog
^ permalink raw reply related
* [PATCH RFC] iommu: Enable per-device SSID space for SVA
From: Joonwon Kang @ 2026-04-24 8:50 UTC (permalink / raw)
To: will, robin.murphy, joro
Cc: jgg, nicolinc, praan, kees, amhetre, Alexander.Grest, baolu.lu,
smostafa, linux-arm-kernel, iommu, linux-kernel, Joonwon Kang
For SVA, the IOMMU core always allocates PASID from the global PASID
space. The use of this global PASID space comes from the limitation of
the ENQCMD instruction in Intel CPUs that it fetches its PASID operand
from IA32_PASID, which is per-task.
Due to this nature, SVA with ARM SMMU v3 has been found not working in
our environment when other modules/devices compete for PASID. The
environment looks as follows:
- The device is not a PCIe device.
- The device is to use SVA.
- The supported SSID/PASID space is very small for the device; only 1 to
3 SSIDs are supported.
- There is a custom way of transmitting the SSID from the kernel to the
device.
With this setup, when other modules have allocated all the PASIDs that
our device is expected to use from the global PASID space via APIs like
iommu_alloc_global_pasid() or iommu_sva_bind_device(), SVA binding to
our device fails due to the lack of available PASIDs.
Since SSID/PASID is supported per-SID in ARM SMMU v3, this commit
leverages the fact and lifts the use of the global PASID space if
possible. What it does includes:
- Introduce a new IOMMU capability IOMMU_CAP_PER_DEV_PASID_SPACE, which
represents whether the IOMMU supports an independent PASID space per-
device, not shared across devices. ARM SMMU v3 is the case.
- Open a new API iommu_attach_device_pasid_any() to allocate any
available PASID and attach an IOMMU domain to it.
- Opt out the use of the global PASID space for SVA if the IOMMU has
that capability, and use the new API to allocate a PASID in that case.
Signed-off-by: Joonwon Kang <joonwonkang@google.com>
---
v1: Request comments for this approach, other possible approaches and/or
other aspects to consider more. Code is not sanitized and commits are
not separated appropriately in this version.
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 2 +
drivers/iommu/iommu-sva.c | 44 +++++++----
drivers/iommu/iommu.c | 85 ++++++++++++++++++++-
include/linux/iommu.h | 5 ++
4 files changed, 121 insertions(+), 15 deletions(-)
diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
index 4d00d796f078..3a700ab0b5c7 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -2494,6 +2494,8 @@ static bool arm_smmu_capable(struct device *dev, enum iommu_cap cap)
return true;
case IOMMU_CAP_DIRTY_TRACKING:
return arm_smmu_dbm_capable(master->smmu);
+ case IOMMU_CAP_PER_DEV_PASID_SPACE:
+ return true;
default:
return false;
}
diff --git a/drivers/iommu/iommu-sva.c b/drivers/iommu/iommu-sva.c
index 07d64908a05f..637d8fd29cbf 100644
--- a/drivers/iommu/iommu-sva.c
+++ b/drivers/iommu/iommu-sva.c
@@ -21,6 +21,7 @@ static struct iommu_mm_data *iommu_alloc_mm_data(struct mm_struct *mm, struct de
{
struct iommu_mm_data *iommu_mm;
ioasid_t pasid;
+ const struct iommu_ops *ops = dev_iommu_ops(dev);
lockdep_assert_held(&iommu_sva_lock);
@@ -39,11 +40,18 @@ static struct iommu_mm_data *iommu_alloc_mm_data(struct mm_struct *mm, struct de
if (!iommu_mm)
return ERR_PTR(-ENOMEM);
- pasid = iommu_alloc_global_pasid(dev);
- if (pasid == IOMMU_PASID_INVALID) {
- kfree(iommu_mm);
- return ERR_PTR(-ENOSPC);
+ if (ops->capable && ops->capable(dev, IOMMU_CAP_PER_DEV_PASID_SPACE)) {
+ pasid = IOMMU_NO_PASID;
+ iommu_mm->pasid_global = false;
+ } else {
+ pasid = iommu_alloc_global_pasid(dev);
+ if (pasid == IOMMU_PASID_INVALID) {
+ kfree(iommu_mm);
+ return ERR_PTR(-ENOSPC);
+ }
+ iommu_mm->pasid_global = true;
}
+
iommu_mm->pasid = pasid;
iommu_mm->mm = mm;
INIT_LIST_HEAD(&iommu_mm->sva_domains);
@@ -114,13 +122,15 @@ struct iommu_sva *iommu_sva_bind_device(struct device *dev, struct mm_struct *mm
goto out_unlock;
}
- /* Search for an existing domain. */
- list_for_each_entry(domain, &mm->iommu_mm->sva_domains, next) {
- ret = iommu_attach_device_pasid(domain, dev, iommu_mm->pasid,
- &handle->handle);
- if (!ret) {
- domain->users++;
- goto out;
+ if (iommu_mm->pasid != IOMMU_NO_PASID) {
+ /* Search for an existing domain. */
+ list_for_each_entry(domain, &mm->iommu_mm->sva_domains, next) {
+ ret = iommu_attach_device_pasid(domain, dev, iommu_mm->pasid,
+ &handle->handle);
+ if (!ret) {
+ domain->users++;
+ goto out;
+ }
}
}
@@ -131,8 +141,13 @@ struct iommu_sva *iommu_sva_bind_device(struct device *dev, struct mm_struct *mm
goto out_free_handle;
}
- ret = iommu_attach_device_pasid(domain, dev, iommu_mm->pasid,
- &handle->handle);
+ if (iommu_mm->pasid != IOMMU_NO_PASID) {
+ ret = iommu_attach_device_pasid(domain, dev, iommu_mm->pasid,
+ &handle->handle);
+ } else {
+ ret = iommu_attach_device_pasid_any(domain, dev, &iommu_mm->pasid,
+ &handle->handle);
+ }
if (ret)
goto out_free_domain;
domain->users = 1;
@@ -211,7 +226,8 @@ void mm_pasid_drop(struct mm_struct *mm)
if (!iommu_mm)
return;
- iommu_free_global_pasid(iommu_mm->pasid);
+ if (iommu_mm->pasid_global)
+ iommu_free_global_pasid(iommu_mm->pasid);
kfree(iommu_mm);
}
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 35db51780954..b882ecad7f57 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -1061,7 +1061,7 @@ struct iommu_group *iommu_group_alloc(void)
mutex_init(&group->mutex);
INIT_LIST_HEAD(&group->devices);
INIT_LIST_HEAD(&group->entry);
- xa_init(&group->pasid_array);
+ xa_init_flags(&group->pasid_array, XA_FLAGS_ALLOC);
ret = ida_alloc(&iommu_group_ida, GFP_KERNEL);
if (ret < 0) {
@@ -3619,6 +3619,89 @@ int iommu_attach_device_pasid(struct iommu_domain *domain,
}
EXPORT_SYMBOL_GPL(iommu_attach_device_pasid);
+/**
+ * iommu_attach_device_pasid_any() - Allocate a pasid of device and attach a
+ * domain to it
+ * @domain: the iommu domain.
+ * @dev: the attached device.
+ * @pasid: pointer to the pasid of the device to be allocated.
+ * @handle: the attach handle.
+ *
+ * Caller should always provide a new handle to avoid race with the paths
+ * that have lockless reference to handle if it intends to pass a valid handle.
+ *
+ * Return: 0 on success, or an error.
+ */
+int iommu_attach_device_pasid_any(struct iommu_domain *domain,
+ struct device *dev,
+ ioasid_t *pasid,
+ struct iommu_attach_handle *handle)
+{
+ /* Caller must be a probed driver on dev */
+ struct iommu_group *group = dev->iommu_group;
+ const struct iommu_ops *ops;
+ void *entry;
+ u32 new_pasid;
+ int ret;
+
+ if (!group)
+ return -ENODEV;
+
+ ops = dev_iommu_ops(dev);
+
+ if (!domain->ops->set_dev_pasid ||
+ !ops->blocked_domain ||
+ !ops->blocked_domain->ops->set_dev_pasid)
+ return -EOPNOTSUPP;
+
+ if (!domain_iommu_ops_compatible(ops, domain) || !pasid)
+ return -EINVAL;
+
+ mutex_lock(&group->mutex);
+
+ /*
+ * This is a concurrent attach during a device reset. Reject it until
+ * pci_dev_reset_iommu_done() attaches the device to group->domain.
+ */
+ if (group->resetting_domain) {
+ ret = -EBUSY;
+ goto out_unlock;
+ }
+
+ entry = iommu_make_pasid_array_entry(domain, handle);
+
+ struct xa_limit limit = {
+ .min = IOMMU_FIRST_GLOBAL_PASID,
+ .max = dev->iommu->max_pasids - 1,
+ };
+
+ ret = xa_alloc(&group->pasid_array, &new_pasid, XA_ZERO_ENTRY, limit, GFP_KERNEL);
+ if (ret)
+ goto out_unlock;
+
+ ret = __iommu_set_group_pasid(domain, group, new_pasid, NULL);
+ if (ret) {
+ xa_release(&group->pasid_array, new_pasid);
+ goto out_unlock;
+ }
+
+ /*
+ * The xa_insert() above reserved the memory, and the group->mutex is
+ * held, this cannot fail. The new domain cannot be visible until the
+ * operation succeeds as we cannot tolerate PRIs becoming concurrently
+ * queued and then failing attach.
+ */
+ WARN_ON(xa_is_err(xa_store(&group->pasid_array,
+ new_pasid, entry, GFP_KERNEL)));
+
+ *pasid = new_pasid;
+
+out_unlock:
+ mutex_unlock(&group->mutex);
+ return ret;
+}
+EXPORT_SYMBOL_GPL(iommu_attach_device_pasid_any);
+
/**
* iommu_replace_device_pasid - Replace the domain that a specific pasid
* of the device is attached to
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 54b8b48c762e..1665f9fe1d8a 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -271,6 +271,7 @@ enum iommu_cap {
*/
IOMMU_CAP_DEFERRED_FLUSH,
IOMMU_CAP_DIRTY_TRACKING, /* IOMMU supports dirty tracking */
+ IOMMU_CAP_PER_DEV_PASID_SPACE, /* IOMMU supports per-device PASID space */
};
/* These are the possible reserved region types */
@@ -1136,6 +1137,7 @@ struct iommu_sva {
struct iommu_mm_data {
u32 pasid;
+ bool pasid_global;
struct mm_struct *mm;
struct list_head sva_domains;
struct list_head mm_list_elm;
@@ -1184,6 +1186,9 @@ void iommu_device_release_dma_owner(struct device *dev);
int iommu_attach_device_pasid(struct iommu_domain *domain,
struct device *dev, ioasid_t pasid,
struct iommu_attach_handle *handle);
+int iommu_attach_device_pasid_any(struct iommu_domain *domain,
+ struct device *dev, ioasid_t *pasid,
+ struct iommu_attach_handle *handle);
void iommu_detach_device_pasid(struct iommu_domain *domain,
struct device *dev, ioasid_t pasid);
ioasid_t iommu_alloc_global_pasid(struct device *dev);
--
2.54.0.545.g6539524ca2-goog
^ permalink raw reply related
* [PATCH RFC] iommu: Enable per-device SSID space for SVA
From: Joonwon Kang @ 2026-04-24 8:53 UTC (permalink / raw)
To: will, robin.murphy, joro, jpb
Cc: jgg, nicolinc, praan, kees, amhetre, Alexander.Grest, baolu.lu,
smostafa, linux-arm-kernel, iommu, linux-kernel, Joonwon Kang
For SVA, the IOMMU core always allocates PASID from the global PASID
space. The use of this global PASID space comes from the limitation of
the ENQCMD instruction in Intel CPUs that it fetches its PASID operand
from IA32_PASID, which is per-task.
Due to this nature, SVA with ARM SMMU v3 has been found not working in
our environment when other modules/devices compete for PASID. The
environment looks as follows:
- The device is not a PCIe device.
- The device is to use SVA.
- The supported SSID/PASID space is very small for the device; only 1 to
3 SSIDs are supported.
- There is a custom way of transmitting the SSID from the kernel to the
device.
With this setup, when other modules have allocated all the PASIDs that
our device is expected to use from the global PASID space via APIs like
iommu_alloc_global_pasid() or iommu_sva_bind_device(), SVA binding to
our device fails due to the lack of available PASIDs.
Since SSID/PASID is supported per-SID in ARM SMMU v3, this commit
leverages the fact and lifts the use of the global PASID space if
possible. What it does includes:
- Introduce a new IOMMU capability IOMMU_CAP_PER_DEV_PASID_SPACE, which
represents whether the IOMMU supports an independent PASID space per-
device, not shared across devices. ARM SMMU v3 is the case.
- Open a new API iommu_attach_device_pasid_any() to allocate any
available PASID and attach an IOMMU domain to it.
- Opt out the use of the global PASID space for SVA if the IOMMU has
that capability, and use the new API to allocate a PASID in that case.
Signed-off-by: Joonwon Kang <joonwonkang@google.com>
---
v1: Request comments for this approach, other possible approaches and/or
other aspects to consider more. Code is not sanitized and commits are
not separated appropriately in this version.
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 2 +
drivers/iommu/iommu-sva.c | 44 +++++++----
drivers/iommu/iommu.c | 85 ++++++++++++++++++++-
include/linux/iommu.h | 5 ++
4 files changed, 121 insertions(+), 15 deletions(-)
diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
index 4d00d796f078..3a700ab0b5c7 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -2494,6 +2494,8 @@ static bool arm_smmu_capable(struct device *dev, enum iommu_cap cap)
return true;
case IOMMU_CAP_DIRTY_TRACKING:
return arm_smmu_dbm_capable(master->smmu);
+ case IOMMU_CAP_PER_DEV_PASID_SPACE:
+ return true;
default:
return false;
}
diff --git a/drivers/iommu/iommu-sva.c b/drivers/iommu/iommu-sva.c
index 07d64908a05f..637d8fd29cbf 100644
--- a/drivers/iommu/iommu-sva.c
+++ b/drivers/iommu/iommu-sva.c
@@ -21,6 +21,7 @@ static struct iommu_mm_data *iommu_alloc_mm_data(struct mm_struct *mm, struct de
{
struct iommu_mm_data *iommu_mm;
ioasid_t pasid;
+ const struct iommu_ops *ops = dev_iommu_ops(dev);
lockdep_assert_held(&iommu_sva_lock);
@@ -39,11 +40,18 @@ static struct iommu_mm_data *iommu_alloc_mm_data(struct mm_struct *mm, struct de
if (!iommu_mm)
return ERR_PTR(-ENOMEM);
- pasid = iommu_alloc_global_pasid(dev);
- if (pasid == IOMMU_PASID_INVALID) {
- kfree(iommu_mm);
- return ERR_PTR(-ENOSPC);
+ if (ops->capable && ops->capable(dev, IOMMU_CAP_PER_DEV_PASID_SPACE)) {
+ pasid = IOMMU_NO_PASID;
+ iommu_mm->pasid_global = false;
+ } else {
+ pasid = iommu_alloc_global_pasid(dev);
+ if (pasid == IOMMU_PASID_INVALID) {
+ kfree(iommu_mm);
+ return ERR_PTR(-ENOSPC);
+ }
+ iommu_mm->pasid_global = true;
}
+
iommu_mm->pasid = pasid;
iommu_mm->mm = mm;
INIT_LIST_HEAD(&iommu_mm->sva_domains);
@@ -114,13 +122,15 @@ struct iommu_sva *iommu_sva_bind_device(struct device *dev, struct mm_struct *mm
goto out_unlock;
}
- /* Search for an existing domain. */
- list_for_each_entry(domain, &mm->iommu_mm->sva_domains, next) {
- ret = iommu_attach_device_pasid(domain, dev, iommu_mm->pasid,
- &handle->handle);
- if (!ret) {
- domain->users++;
- goto out;
+ if (iommu_mm->pasid != IOMMU_NO_PASID) {
+ /* Search for an existing domain. */
+ list_for_each_entry(domain, &mm->iommu_mm->sva_domains, next) {
+ ret = iommu_attach_device_pasid(domain, dev, iommu_mm->pasid,
+ &handle->handle);
+ if (!ret) {
+ domain->users++;
+ goto out;
+ }
}
}
@@ -131,8 +141,13 @@ struct iommu_sva *iommu_sva_bind_device(struct device *dev, struct mm_struct *mm
goto out_free_handle;
}
- ret = iommu_attach_device_pasid(domain, dev, iommu_mm->pasid,
- &handle->handle);
+ if (iommu_mm->pasid != IOMMU_NO_PASID) {
+ ret = iommu_attach_device_pasid(domain, dev, iommu_mm->pasid,
+ &handle->handle);
+ } else {
+ ret = iommu_attach_device_pasid_any(domain, dev, &iommu_mm->pasid,
+ &handle->handle);
+ }
if (ret)
goto out_free_domain;
domain->users = 1;
@@ -211,7 +226,8 @@ void mm_pasid_drop(struct mm_struct *mm)
if (!iommu_mm)
return;
- iommu_free_global_pasid(iommu_mm->pasid);
+ if (iommu_mm->pasid_global)
+ iommu_free_global_pasid(iommu_mm->pasid);
kfree(iommu_mm);
}
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 35db51780954..b882ecad7f57 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -1061,7 +1061,7 @@ struct iommu_group *iommu_group_alloc(void)
mutex_init(&group->mutex);
INIT_LIST_HEAD(&group->devices);
INIT_LIST_HEAD(&group->entry);
- xa_init(&group->pasid_array);
+ xa_init_flags(&group->pasid_array, XA_FLAGS_ALLOC);
ret = ida_alloc(&iommu_group_ida, GFP_KERNEL);
if (ret < 0) {
@@ -3619,6 +3619,89 @@ int iommu_attach_device_pasid(struct iommu_domain *domain,
}
EXPORT_SYMBOL_GPL(iommu_attach_device_pasid);
+/**
+ * iommu_attach_device_pasid_any() - Allocate a pasid of device and attach a
+ * domain to it
+ * @domain: the iommu domain.
+ * @dev: the attached device.
+ * @pasid: pointer to the pasid of the device to be allocated.
+ * @handle: the attach handle.
+ *
+ * Caller should always provide a new handle to avoid race with the paths
+ * that have lockless reference to handle if it intends to pass a valid handle.
+ *
+ * Return: 0 on success, or an error.
+ */
+int iommu_attach_device_pasid_any(struct iommu_domain *domain,
+ struct device *dev,
+ ioasid_t *pasid,
+ struct iommu_attach_handle *handle)
+{
+ /* Caller must be a probed driver on dev */
+ struct iommu_group *group = dev->iommu_group;
+ const struct iommu_ops *ops;
+ void *entry;
+ u32 new_pasid;
+ int ret;
+
+ if (!group)
+ return -ENODEV;
+
+ ops = dev_iommu_ops(dev);
+
+ if (!domain->ops->set_dev_pasid ||
+ !ops->blocked_domain ||
+ !ops->blocked_domain->ops->set_dev_pasid)
+ return -EOPNOTSUPP;
+
+ if (!domain_iommu_ops_compatible(ops, domain) || !pasid)
+ return -EINVAL;
+
+ mutex_lock(&group->mutex);
+
+ /*
+ * This is a concurrent attach during a device reset. Reject it until
+ * pci_dev_reset_iommu_done() attaches the device to group->domain.
+ */
+ if (group->resetting_domain) {
+ ret = -EBUSY;
+ goto out_unlock;
+ }
+
+ entry = iommu_make_pasid_array_entry(domain, handle);
+
+ struct xa_limit limit = {
+ .min = IOMMU_FIRST_GLOBAL_PASID,
+ .max = dev->iommu->max_pasids - 1,
+ };
+
+ ret = xa_alloc(&group->pasid_array, &new_pasid, XA_ZERO_ENTRY, limit, GFP_KERNEL);
+ if (ret)
+ goto out_unlock;
+
+ ret = __iommu_set_group_pasid(domain, group, new_pasid, NULL);
+ if (ret) {
+ xa_release(&group->pasid_array, new_pasid);
+ goto out_unlock;
+ }
+
+ /*
+ * The xa_insert() above reserved the memory, and the group->mutex is
+ * held, this cannot fail. The new domain cannot be visible until the
+ * operation succeeds as we cannot tolerate PRIs becoming concurrently
+ * queued and then failing attach.
+ */
+ WARN_ON(xa_is_err(xa_store(&group->pasid_array,
+ new_pasid, entry, GFP_KERNEL)));
+
+ *pasid = new_pasid;
+
+out_unlock:
+ mutex_unlock(&group->mutex);
+ return ret;
+}
+EXPORT_SYMBOL_GPL(iommu_attach_device_pasid_any);
+
/**
* iommu_replace_device_pasid - Replace the domain that a specific pasid
* of the device is attached to
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 54b8b48c762e..1665f9fe1d8a 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -271,6 +271,7 @@ enum iommu_cap {
*/
IOMMU_CAP_DEFERRED_FLUSH,
IOMMU_CAP_DIRTY_TRACKING, /* IOMMU supports dirty tracking */
+ IOMMU_CAP_PER_DEV_PASID_SPACE, /* IOMMU supports per-device PASID space */
};
/* These are the possible reserved region types */
@@ -1136,6 +1137,7 @@ struct iommu_sva {
struct iommu_mm_data {
u32 pasid;
+ bool pasid_global;
struct mm_struct *mm;
struct list_head sva_domains;
struct list_head mm_list_elm;
@@ -1184,6 +1186,9 @@ void iommu_device_release_dma_owner(struct device *dev);
int iommu_attach_device_pasid(struct iommu_domain *domain,
struct device *dev, ioasid_t pasid,
struct iommu_attach_handle *handle);
+int iommu_attach_device_pasid_any(struct iommu_domain *domain,
+ struct device *dev, ioasid_t *pasid,
+ struct iommu_attach_handle *handle);
void iommu_detach_device_pasid(struct iommu_domain *domain,
struct device *dev, ioasid_t pasid);
ioasid_t iommu_alloc_global_pasid(struct device *dev);
--
2.54.0.545.g6539524ca2-goog
^ permalink raw reply related
* Re: [PATCH v5 8/8] ARM: defconfig: Add a zx29 defconfig file
From: Arnd Bergmann @ 2026-04-24 8:54 UTC (permalink / raw)
To: Linus Walleij, Stefan Dösinger
Cc: Jonathan Corbet, Shuah Khan, Russell King, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Krzysztof Kozlowski,
Alexandre Belloni, Drew Fustini, Greg Kroah-Hartman, Jiri Slaby,
linux-doc, linux-kernel, linux-arm-kernel, devicetree, soc,
linux-serial
In-Reply-To: <CAD++jL=_eDY_mG_QBreSrZiho0hUrDSciedq=vrxXaTiMwrSyg@mail.gmail.com>
On Fri, Apr 24, 2026, at 09:13, Linus Walleij wrote:
> On Tue, Apr 21, 2026 at 10:24 PM Stefan Dösinger
> <stefandoesinger@gmail.com> wrote:
>
>> This enables existing drivers that already are (UART) or will be (USB,
>> GPIO) necessary to operate this board even if they aren't declared in
>> the DTS yet.
>>
>> Signed-off-by: Stefan Dösinger <stefandoesinger@gmail.com>
>
> *I* personally (as SoC maintainer) think that having a few more defconfigs
> is fine, even helpful.
>
> But I would defer this to the more senior SoC maintainers because I think
> their stance is something like:
>
> - We have multi_v7_defconfig for compile testing
>
> - We know that binary gets way to big for your system: it's for build
> testing and perhaps booting in QEMU or systems with many MB of
> RAM, not for actually running it on products.
>
> - You are encouraged to keep your own defconfig out-of-tree.
Right, we clearly need to do something better than what we are with
the general defconfigs, as I'm sure many of the existing ones are
never actually used for booting a machine, and are horribly out of
date with the Kconfig options.
I wouldn't object to adding another defconfig for a new (or revived)
soc family, but I don't want to have more per-board ones.
Overall, we have about 70 defconfigs and 55 soc families that have their
own mach-* directory (plus a few without code), and the number of
defconfigs alone makes it hard to keep them up to date.
> However I even challenged this myself by adding a defconfig for memory
> constrained Broadcoms a while back (NACKed/ignored ;) so if it was all
> up to me I would merge this.
I don't even remember that discussion ;-)
One idea might be to have a tiny base defconfig, plus platform
specific fragments that add drivers. The problem is agreeing
what bits are essential enough to still get enabled in the
tiny config.
Arnd
^ permalink raw reply
* Re: [PATCH RFC] iommu: Enable per-device SSID space for SVA
From: Joonwon Kang @ 2026-04-24 8:57 UTC (permalink / raw)
To: joonwonkang
Cc: Alexander.Grest, amhetre, baolu.lu, iommu, jgg, joro, kees,
linux-arm-kernel, linux-kernel, nicolinc, praan, robin.murphy,
smostafa, will
In-Reply-To: <20260424085011.3502295-1-joonwonkang@google.com>
> For SVA, the IOMMU core always allocates PASID from the global PASID
> space. The use of this global PASID space comes from the limitation of
> the ENQCMD instruction in Intel CPUs that it fetches its PASID operand
> from IA32_PASID, which is per-task.
>
> Due to this nature, SVA with ARM SMMU v3 has been found not working in
> our environment when other modules/devices compete for PASID. The
> environment looks as follows:
>
> - The device is not a PCIe device.
> - The device is to use SVA.
> - The supported SSID/PASID space is very small for the device; only 1 to
> 3 SSIDs are supported.
> - There is a custom way of transmitting the SSID from the kernel to the
> device.
>
> With this setup, when other modules have allocated all the PASIDs that
> our device is expected to use from the global PASID space via APIs like
> iommu_alloc_global_pasid() or iommu_sva_bind_device(), SVA binding to
> our device fails due to the lack of available PASIDs.
>
> Since SSID/PASID is supported per-SID in ARM SMMU v3, this commit
> leverages the fact and lifts the use of the global PASID space if
> possible. What it does includes:
>
> - Introduce a new IOMMU capability IOMMU_CAP_PER_DEV_PASID_SPACE, which
> represents whether the IOMMU supports an independent PASID space per-
> device, not shared across devices. ARM SMMU v3 is the case.
> - Open a new API iommu_attach_device_pasid_any() to allocate any
> available PASID and attach an IOMMU domain to it.
> - Opt out the use of the global PASID space for SVA if the IOMMU has
> that capability, and use the new API to allocate a PASID in that case.
>
> Signed-off-by: Joonwon Kang <joonwonkang@google.com>
Please disregard this RFC as I have sent a new one with more recipients.
Thanks,
Joonwon Kang
^ permalink raw reply
* [PATCH net] net: airoha: Do not read uninitialized fragment address in airoha_dev_xmit()
From: Lorenzo Bianconi @ 2026-04-24 9:00 UTC (permalink / raw)
To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni
Cc: Simon Horman, linux-arm-kernel, linux-mediatek, netdev,
Lorenzo Bianconi
The transmit loop in airoha_dev_xmit() reads fragment address and length
during its final iteration, when the loop index equals
skb_shinfo(skb)->nr_frags, at which point the fragment data is
uninitialized. While these values are never consumed, the read itself is
unsafe and may trigger a page fault. Fix this by avoiding the fragment
read on the last iteration.
Additionally, move the skb pointer from the first to the last used packet
descriptor, so that airoha_qdma_tx_napi_poll() defers freeing the skb
until the final descriptor is processed.
Fixes: 23020f0493270 ("net: airoha: Introduce ethernet support for EN7581 SoC")
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
drivers/net/ethernet/airoha/airoha_eth.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/airoha/airoha_eth.c b/drivers/net/ethernet/airoha/airoha_eth.c
index 2bb0a3ff9810..d3a841908c82 100644
--- a/drivers/net/ethernet/airoha/airoha_eth.c
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
@@ -1997,8 +1997,8 @@ static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb,
struct netdev_queue *txq;
struct airoha_queue *q;
LIST_HEAD(tx_list);
+ int i = 0, qid;
void *data;
- int i, qid;
u16 index;
u8 fport;
@@ -2057,7 +2057,7 @@ static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb,
list);
index = e - q->entry;
- for (i = 0; i < nr_frags; i++) {
+ while (true) {
struct airoha_qdma_desc *desc = &q->desc[index];
skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
dma_addr_t addr;
@@ -2069,7 +2069,7 @@ static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb,
goto error_unmap;
list_move_tail(&e->list, &tx_list);
- e->skb = i ? NULL : skb;
+ e->skb = i == nr_frags - 1 ? skb : NULL;
e->dma_addr = addr;
e->dma_len = len;
@@ -2088,6 +2088,9 @@ static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb,
WRITE_ONCE(desc->msg1, cpu_to_le32(msg1));
WRITE_ONCE(desc->msg2, cpu_to_le32(0xffff));
+ if (++i == nr_frags)
+ break;
+
data = skb_frag_address(frag);
len = skb_frag_size(frag);
}
---
base-commit: e728258debd553c95d2e70f9cd97c9fde27c7130
change-id: 20260423-airoha-xmit-fix-read-frag-dc6aa001ca4b
Best regards,
--
Lorenzo Bianconi <lorenzo@kernel.org>
^ permalink raw reply related
* Re: [PATCH v3 1/4] kernel: param: initialize module_kset on-demand
From: Shashank Balaji @ 2026-04-24 9:16 UTC (permalink / raw)
To: Suzuki K Poulose, Mike Leach, James Clark, Alexander Shishkin,
Maxime Coquelin, Alexandre Torgue, Greg Kroah-Hartman,
Rafael J. Wysocki, Danilo Krummrich, Miguel Ojeda, Boqun Feng,
Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg,
Alice Ryhl, Trevor Gross, Richard Cochran, Jonathan Corbet,
Shuah Khan
Cc: Rahul Bukte, linux-kernel, coresight, linux-arm-kernel,
driver-core, rust-for-linux, linux-doc, Daniel Palmer, Tim Bird
In-Reply-To: <20260422-acpi_mod_name-v3-1-a184eff9ff6f@sony.com>
On Wed, Apr 22, 2026 at 06:49:03PM +0900, Shashank Balaji wrote:
> module_kset is initialized in param_sysfs_init(), a subsys_initcall. A number
> of platform drivers register themselves prior to subsys_initcalls. With an
> upcoming patch ("driver core: platform: set mod_name in driver registration")
> that sets their mod_name in struct device_driver, lookup_or_create_module()
> will be called for those drivers, which calls kset_find_object(module_kset, mod_name).
> This fails because module_kset isn't alive yet.
>
> Fix this by initializing module_kset on-demand in lookup_or_create_module().
> Retain the param_sysfs_init() subsys_initcall to ensure that module_kset is
> live after subsys_initcalls (assuming no OOM) for any users who may need it,
> on the off chance that it wasn't init'd on-demand because of no
> pre-subsys_initcall drivers.
>
> This on-demand path can trigger before subsys_initcall. kset_create_and_add()
> be should safe in those contexts because the allocator is up and running by then,
> no userspace to start uevent helper or listen to a uevent socket.
>
> Suggested-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> 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>
>
> ---
>
> Patch 3 depends on this patch.
> ---
> kernel/params.c | 41 +++++++++++++++++++++++++----------------
> 1 file changed, 25 insertions(+), 16 deletions(-)
>
> diff --git a/kernel/params.c b/kernel/params.c
> index 74d620bc2521..f25d6fda159c 100644
> --- a/kernel/params.c
> +++ b/kernel/params.c
> @@ -745,6 +745,26 @@ void module_param_sysfs_remove(struct module *mod)
> }
> #endif
>
> +static int uevent_filter(const struct kobject *kobj)
> +{
> + const struct kobj_type *ktype = get_ktype(kobj);
> +
> + if (ktype == &module_ktype)
> + return 1;
> + return 0;
> +}
> +
> +static const struct kset_uevent_ops module_uevent_ops = {
> + .filter = uevent_filter,
> +};
> +
> +static struct kset *__init_or_module ensure_module_kset(void)
> +{
> + if (!module_kset)
> + module_kset = kset_create_and_add("module", &module_uevent_ops, NULL);
> + return module_kset;
> +}
Sashiko's review [1]:
Could this cause a race condition if multiple threads try to initialize
module_kset concurrently?
If asynchronous driver registration triggers this path concurrently before
subsys_initcalls, is it possible for both threads to see module_kset as NULL:
Thread 1
if (!module_kset)
module_kset = kset_create_and_add("module", &module_uevent_ops, NULL);
/* Succeeds and assigns a valid kset */
Thread 2
if (!module_kset)
module_kset = kset_create_and_add("module", &module_uevent_ops, NULL);
/* Fails due to duplicate name and returns NULL */
If Thread 2 overwrites module_kset with NULL after Thread 1 succeeds, wouldn't
this orphan the kset created by Thread 1 and cause all subsequent callers to
fail? Does this initialization need synchronization to prevent this?
While all pre-subsys_initcall platform driver registration happens
synchronously now, on the boot cpu, asynchronous registration may be
introduced in the future which would silently break this patch. Either
way, it would be better to be safe with a mutex.
I also noticed another problem with this patch: kset_create_and_add() is
called as long as module_kset is not set. So in the case of OOM, init
will be attempted as long as it succeeds, even beyond subsys_initcall.
While the current behaviour is to init only in subsys_initcall.
Both of these can be fixed with a DO_ONCE_SLEEPABLE-based
initialization.
[1] https://sashiko.dev/#/patchset/20260422-acpi_mod_name-v3-0-a184eff9ff6f@sony.com?part=1
^ permalink raw reply
* Re: [PATCH 1/4] arm64: signal: Preserve POR_EL0 if poe_context is missing
From: Kevin Brodsky @ 2026-04-24 9:24 UTC (permalink / raw)
To: Will Deacon
Cc: linux-arm-kernel, linux-kernel, Catalin Marinas, Joey Gouly,
Mark Brown, Shuah Khan, linux-kselftest
In-Reply-To: <aeoTX_6nK6oHw5OE@willie-the-truck>
On 23/04/2026 14:41, Will Deacon wrote:
> On Wed, Apr 22, 2026 at 04:55:05PM +0200, Kevin Brodsky wrote:
>> On 22/04/2026 14:19, Will Deacon wrote:
>>>> @@ -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;
>>>> };
>>> Do you think it would be worth adding some accessors to make it easier
>>> to keep the flags in sync? For example:
>>>
>>> /* Stores por_el0 into uas->por_el0 and sets UA_STATE_HAS_POR_EL0 */
>>> void set_ua_state_por_el0(struct user_access_state *uas, u64 por_el0);
>>>
>>> /*
>>> * If UA_STATE_HAS_POR_EL0, *por_el0 = uas->por_el0 and return 0.
>>> * Otherwise, return -ENOENT.
>>> */
>>> int get_ua_state_por_el0(struct user_access_state *uas, u64 *por_el0);
>>>
>>> WDYT?
>> I did get a feeling having helpers would be a good idea. I wonder if
>> getters/setters aren't a bit overkill though, as they make accesses to
>> the struct more cumbersome and we'd need a pair for every member (unless
>> we use some macro magic).
> We only have one struct member, so it's probably fine for now, and we
> could group related members together in sub-structures to help in future.
> But it's up to you -- I don't feel strongly about it, but requiring the
> caller to update the flag manually is going to be a bug magnet.
>
>> Maybe it would be sufficient to have say
>> ua_state_has_field(POR_EL0) to check if the bit is set, and
>> ua_state_set_field_valid(POR_EL0) to set the bit?
> I don't think that really helps with my concern. I'd like to avoid callers
> having to remember to deal with the flags when they update the data.
Got it. I can't think of a better way to do this so I'll just go ahead
with your suggestion, and prefix all members of the struct with __ to
make it clear they shouldn't be accessed directly. The macro magic can
wait until we have more than one struct member ;)
I've also reconsidered setup_sigframe() and realised using valid_fields
there is not a great idea, because the record is allocated in
setup_sigframe_layout() based on system_supports_poe(), and leaving a
record uninitialised would be bad™. I'll remove that change and I'll
have preserve_poe_context() fail with a WARN_ON() if
get_ua_state_por_el0() somehow returns an error.
- Kevin
^ permalink raw reply
* [PATCH v4 0/2] Add Meta(Facebook) ventura2 BMC(AST2600)
From: Kyle Hsieh @ 2026-04-24 9:30 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Joel Stanley,
Andrew Jeffery
Cc: devicetree, linux-arm-kernel, linux-aspeed, linux-kernel,
Kyle Hsieh, Krzysztof Kozlowski
Summary:
Add linux device tree entry related to Meta(Facebook) ventura2.
specific devices connected to BMC(AST2600) SoC.
Signed-off-by: Kyle Hsieh <kylehsieh1995@gmail.com>
---
Changes in v4:
- Fixed capitalization: "ventura2" -> "Ventura2".
- Reordered I2C child nodes in ascending order of unit addresses.
- Enable PECI, LPC control, and KCS3 interfaces for host communication.
- Configure MCTP controller on I2C4 and enable MCTP support for specific mux channels.
- Add Infineon TDA38640 and TI INA230 power monitor nodes.
- GPIO and Pinmux cleanup for PVT:
- Aligned gpio-line-names as requested.
- Remove unused or non-existent GPIO line names to align with Ventura2 PVT.
- Update specific GPIO pins to empty strings where signals were removed or consolidated.
- Adjust SGPIOM frequency to 200kHz and update signal line names.
- Enable UART3 and add serial2 alias.
- Link to v3: https://lore.kernel.org/r/20260113-ventura2_initial_dts-v3-0-2dbfda6a5b47@gmail.com
Changes in v3:
- Add annotation for marvel 88e6393x
- Modify the gpio-line-name
- Modify the node order alphabetically
- Modify dt-bindings document for rmc instead of bmc
- Move the gpio-line-names to original node
- Link to v2: https://lore.kernel.org/r/20251224-ventura2_initial_dts-v2-0-f193ba5d4073@gmail.com
Changes in v2:
- Remove unused mdio
- Link to v1: https://lore.kernel.org/r/20251222-ventura2_initial_dts-v1-0-1f06166c78a3@gmail.com
---
Kyle Hsieh (2):
dt-bindings: arm: aspeed: add Meta ventura2 board
ARM: dts: aspeed: ventura2: Add Meta ventura2 BMC
.../devicetree/bindings/arm/aspeed/aspeed.yaml | 1 +
arch/arm/boot/dts/aspeed/Makefile | 1 +
.../dts/aspeed/aspeed-bmc-facebook-ventura2.dts | 2925 ++++++++++++++++++++
3 files changed, 2927 insertions(+)
---
base-commit: 9448598b22c50c8a5bb77a9103e2d49f134c9578
change-id: 20251222-ventura2_initial_dts-909b3277d665
Best regards,
--
Kyle Hsieh <kylehsieh1995@gmail.com>
^ permalink raw reply
* [PATCH v4 1/2] dt-bindings: arm: aspeed: add Meta ventura2 board
From: Kyle Hsieh @ 2026-04-24 9:30 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Joel Stanley,
Andrew Jeffery
Cc: devicetree, linux-arm-kernel, linux-aspeed, linux-kernel,
Kyle Hsieh, Krzysztof Kozlowski
In-Reply-To: <20260424-ventura2_initial_dts-v4-0-806b00ea4314@gmail.com>
Document the new compatibles used on Facebook ventura2.
Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
Signed-off-by: Kyle Hsieh <kylehsieh1995@gmail.com>
---
Documentation/devicetree/bindings/arm/aspeed/aspeed.yaml | 1 +
1 file changed, 1 insertion(+)
diff --git a/Documentation/devicetree/bindings/arm/aspeed/aspeed.yaml b/Documentation/devicetree/bindings/arm/aspeed/aspeed.yaml
index 9298c1a75dd1..d48607c86e8e 100644
--- a/Documentation/devicetree/bindings/arm/aspeed/aspeed.yaml
+++ b/Documentation/devicetree/bindings/arm/aspeed/aspeed.yaml
@@ -92,6 +92,7 @@ properties:
- facebook,harma-bmc
- facebook,minerva-cmc
- facebook,santabarbara-bmc
+ - facebook,ventura2-rmc
- facebook,yosemite4-bmc
- facebook,yosemite5-bmc
- ibm,balcones-bmc
--
2.34.1
^ permalink raw reply related
* [PATCH v4 2/2] ARM: dts: aspeed: ventura2: Add Meta ventura2 BMC
From: Kyle Hsieh @ 2026-04-24 9:30 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Joel Stanley,
Andrew Jeffery
Cc: devicetree, linux-arm-kernel, linux-aspeed, linux-kernel,
Kyle Hsieh
In-Reply-To: <20260424-ventura2_initial_dts-v4-0-806b00ea4314@gmail.com>
Add linux device tree entry related to the Meta(Facebook) rmc-node.
The system use an AT2600 BMC.
This node is named "ventura2".
Signed-off-by: Kyle Hsieh <kylehsieh1995@gmail.com>
---
arch/arm/boot/dts/aspeed/Makefile | 1 +
.../dts/aspeed/aspeed-bmc-facebook-ventura2.dts | 2925 ++++++++++++++++++++
2 files changed, 2926 insertions(+)
diff --git a/arch/arm/boot/dts/aspeed/Makefile b/arch/arm/boot/dts/aspeed/Makefile
index 9adf9278dc94..6b96997629d4 100644
--- a/arch/arm/boot/dts/aspeed/Makefile
+++ b/arch/arm/boot/dts/aspeed/Makefile
@@ -32,6 +32,7 @@ dtb-$(CONFIG_ARCH_ASPEED) += \
aspeed-bmc-facebook-minipack.dtb \
aspeed-bmc-facebook-santabarbara.dtb \
aspeed-bmc-facebook-tiogapass.dtb \
+ aspeed-bmc-facebook-ventura2.dtb \
aspeed-bmc-facebook-wedge40.dtb \
aspeed-bmc-facebook-wedge100.dtb \
aspeed-bmc-facebook-wedge400-data64.dtb \
diff --git a/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-ventura2.dts b/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-ventura2.dts
new file mode 100644
index 000000000000..8d4ddb473862
--- /dev/null
+++ b/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-ventura2.dts
@@ -0,0 +1,2925 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) 2023 Facebook Inc.
+/dts-v1/;
+
+#include "aspeed-g6.dtsi"
+#include <dt-bindings/i2c/i2c.h>
+#include <dt-bindings/gpio/aspeed-gpio.h>
+
+/ {
+ model = "Facebook Ventura2 RMC";
+ compatible = "facebook,ventura2-rmc", "aspeed,ast2600";
+ aliases {
+ serial2 = &uart3;
+ serial4 = &uart5;
+
+ /*
+ * i2c switch 0-0077, pca9548, 8 child channels assigned
+ * with bus number 16-23.
+ */
+ i2c16 = &i2c0mux0ch0;
+ i2c17 = &i2c0mux0ch1;
+ i2c18 = &i2c0mux0ch2;
+ i2c19 = &i2c0mux0ch3;
+ i2c20 = &i2c0mux0ch4;
+ i2c21 = &i2c0mux0ch5;
+ i2c22 = &i2c0mux0ch6;
+ i2c23 = &i2c0mux0ch7;
+
+ /*
+ * i2c switch 1-0077, pca9548, 8 child channels assigned
+ * with bus number 24-31.
+ */
+ i2c24 = &i2c1mux0ch0;
+ i2c25 = &i2c1mux0ch1;
+ i2c26 = &i2c1mux0ch2;
+ i2c27 = &i2c1mux0ch3;
+ i2c28 = &i2c1mux0ch4;
+ i2c29 = &i2c1mux0ch5;
+ i2c30 = &i2c1mux0ch6;
+ i2c31 = &i2c1mux0ch7;
+
+ /*
+ * i2c switch 4-0077, pca9548, 8 child channels assigned
+ * with bus number 32-39.
+ */
+ i2c32 = &i2c4mux0ch0;
+ i2c33 = &i2c4mux0ch1;
+ i2c34 = &i2c4mux0ch2;
+ i2c35 = &i2c4mux0ch3;
+ i2c36 = &i2c4mux0ch4;
+ i2c37 = &i2c4mux0ch5;
+ i2c38 = &i2c4mux0ch6;
+ i2c39 = &i2c4mux0ch7;
+
+ /*
+ * i2c switch 5-0077, pca9548, 8 child channels assigned
+ * with bus number 40-47.
+ */
+ i2c40 = &i2c5mux0ch0;
+ i2c41 = &i2c5mux0ch1;
+ i2c42 = &i2c5mux0ch2;
+ i2c43 = &i2c5mux0ch3;
+ i2c44 = &i2c5mux0ch4;
+ i2c45 = &i2c5mux0ch5;
+ i2c46 = &i2c5mux0ch6;
+ i2c47 = &i2c5mux0ch7;
+
+ /*
+ * i2c switch 8-0077, pca9548, 8 child channels assigned
+ * with bus number 48-55.
+ */
+ i2c48 = &i2c8mux0ch0;
+ i2c49 = &i2c8mux0ch1;
+ i2c50 = &i2c8mux0ch2;
+ i2c51 = &i2c8mux0ch3;
+ i2c52 = &i2c8mux0ch4;
+ i2c53 = &i2c8mux0ch5;
+ i2c54 = &i2c8mux0ch6;
+ i2c55 = &i2c8mux0ch7;
+
+ /*
+ * i2c switch 11-0077, pca9548, 8 child channels assigned
+ * with bus number 56-63.
+ */
+ i2c56 = &i2c11mux0ch0;
+ i2c57 = &i2c11mux0ch1;
+ i2c58 = &i2c11mux0ch2;
+ i2c59 = &i2c11mux0ch3;
+ i2c60 = &i2c11mux0ch4;
+ i2c61 = &i2c11mux0ch5;
+ i2c62 = &i2c11mux0ch6;
+ i2c63 = &i2c11mux0ch7;
+
+ /*
+ * i2c switch 13-0077, pca9548, 8 child channels assigned
+ * with bus number 64-71.
+ */
+ i2c64 = &i2c13mux0ch0;
+ i2c65 = &i2c13mux0ch1;
+ i2c66 = &i2c13mux0ch2;
+ i2c67 = &i2c13mux0ch3;
+ i2c68 = &i2c13mux0ch4;
+ i2c69 = &i2c13mux0ch5;
+ i2c70 = &i2c13mux0ch6;
+ i2c71 = &i2c13mux0ch7;
+
+ /*
+ * i2c switch 15-0077, pca9548, 8 child channels assigned
+ * with bus number 72-79.
+ */
+ i2c72 = &i2c15mux0ch0;
+ i2c73 = &i2c15mux0ch1;
+ i2c74 = &i2c15mux0ch2;
+ i2c75 = &i2c15mux0ch3;
+ i2c76 = &i2c15mux0ch4;
+ i2c77 = &i2c15mux0ch5;
+ i2c78 = &i2c15mux0ch6;
+ i2c79 = &i2c15mux0ch7;
+ };
+
+ chosen {
+ stdout-path = "serial4:57600n8";
+ };
+
+ fan_leds {
+ compatible = "gpio-leds";
+
+ led-0 {
+ label = "fcb0fan0_ledd1_blue";
+ default-state = "off";
+ gpios = <&fan_io_expander0 0 GPIO_ACTIVE_LOW>;
+ };
+
+ led-1 {
+ label = "fcb0fan1_ledd2_blue";
+ default-state = "off";
+ gpios = <&fan_io_expander0 1 GPIO_ACTIVE_LOW>;
+ };
+
+ led-2 {
+ label = "fcb0fan2_ledd3_blue";
+ default-state = "off";
+ gpios = <&fan_io_expander1 0 GPIO_ACTIVE_LOW>;
+ };
+
+ led-3 {
+ label = "fcb0fan3_ledd4_blue";
+ default-state = "off";
+ gpios = <&fan_io_expander1 1 GPIO_ACTIVE_LOW>;
+ };
+
+ led-4 {
+ label = "fcb0fan0_ledd1_amber";
+ default-state = "off";
+ gpios = <&fan_io_expander0 4 GPIO_ACTIVE_LOW>;
+ };
+
+ led-5 {
+ label = "fcb0fan1_ledd2_amber";
+ default-state = "off";
+ gpios = <&fan_io_expander0 5 GPIO_ACTIVE_LOW>;
+ };
+
+ led-6 {
+ label = "fcb0fan2_ledd3_amber";
+ default-state = "off";
+ gpios = <&fan_io_expander1 4 GPIO_ACTIVE_LOW>;
+ };
+
+ led-7 {
+ label = "fcb0fan3_ledd4_amber";
+ default-state = "off";
+ gpios = <&fan_io_expander1 5 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+ iio-hwmon {
+ compatible = "iio-hwmon";
+ io-channels = <&adc0 0>, <&adc0 1>, <&adc0 2>, <&adc0 3>,
+ <&adc0 4>, <&adc0 5>, <&adc0 6>, <&adc0 7>,
+ <&adc1 2>;
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ led-0 {
+ label = "bmc_heartbeat_amber";
+ gpios = <&gpio0 ASPEED_GPIO(P, 7) GPIO_ACTIVE_LOW>;
+ linux,default-trigger = "heartbeat";
+ };
+
+ led-1 {
+ label = "fp_id_amber";
+ default-state = "off";
+ gpios = <&gpio0 ASPEED_GPIO(B, 5) GPIO_ACTIVE_HIGH>;
+ };
+
+ led-2 {
+ label = "bmc_ready_noled";
+ default-state = "on";
+ gpios = <&gpio0 ASPEED_GPIO(B, 3) (GPIO_ACTIVE_HIGH|GPIO_TRANSITORY)>;
+ };
+
+ led-3 {
+ label = "power_blue";
+ default-state = "off";
+ gpios = <&gpio0 ASPEED_GPIO(P, 4) GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ memory@80000000 {
+ device_type = "memory";
+ reg = <0x80000000 0x80000000>;
+ };
+
+ p1v8_bmc_aux: regulator-p1v8-bmc-aux {
+ compatible = "regulator-fixed";
+ regulator-name = "p1v8_bmc_aux";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ p2v5_bmc_aux: regulator-p2v5-bmc-aux {
+ compatible = "regulator-fixed";
+ regulator-name = "p2v5_bmc_aux";
+ regulator-min-microvolt = <2500000>;
+ regulator-max-microvolt = <2500000>;
+ regulator-always-on;
+ };
+
+ p5v_dac_aux: regulator-p5v-bmc-aux {
+ compatible = "regulator-fixed";
+ regulator-name = "p5v_dac_aux";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ };
+
+ spi1_gpio: spi {
+ compatible = "spi-gpio";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ sck-gpios = <&gpio0 ASPEED_GPIO(Z, 3) GPIO_ACTIVE_HIGH>;
+ mosi-gpios = <&gpio0 ASPEED_GPIO(Z, 4) GPIO_ACTIVE_HIGH>;
+ miso-gpios = <&gpio0 ASPEED_GPIO(Z, 5) GPIO_ACTIVE_HIGH>;
+ cs-gpios = <&gpio0 ASPEED_GPIO(Z, 0) GPIO_ACTIVE_LOW>;
+ num-chipselects = <1>;
+
+ tpm@0 {
+ compatible = "infineon,slb9670", "tcg,tpm_tis-spi";
+ spi-max-frequency = <33000000>;
+ reg = <0>;
+ };
+ };
+};
+
+&adc0 {
+ vref-supply = <&p1v8_bmc_aux>;
+ status = "okay";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_adc0_default &pinctrl_adc1_default
+ &pinctrl_adc2_default &pinctrl_adc3_default
+ &pinctrl_adc4_default &pinctrl_adc5_default
+ &pinctrl_adc6_default &pinctrl_adc7_default>;
+};
+
+&adc1 {
+ vref-supply = <&p2v5_bmc_aux>;
+ status = "okay";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_adc8_default &pinctrl_adc10_default>;
+};
+
+&ehci0 {
+ status = "okay";
+};
+
+&ehci1 {
+ status = "okay";
+};
+
+&fmc {
+ status = "okay";
+ flash@0 {
+ status = "okay";
+ m25p,fast-read;
+ label = "bmc";
+ spi-max-frequency = <50000000>;
+ #include "openbmc-flash-layout-128.dtsi"
+ };
+ flash@1 {
+ status = "okay";
+ m25p,fast-read;
+ label = "alt-bmc";
+ spi-max-frequency = <50000000>;
+ };
+};
+
+&peci0 {
+ status = "okay";
+};
+
+&gpio0 {
+ gpio-line-names =
+ /*A0-A7*/ "","","","","","","","",
+ /*B0-B7*/ "BATTERY_DETECT","","","BMC_READY_R",
+ "","FM_ID_LED","","",
+ /*C0-C7*/ "","","","","","","","",
+ /*D0-D7*/ "","","","","","","","",
+ /*E0-E7*/ "","","","","","","","",
+ /*F0-F7*/ "","","","","","","","",
+ /*G0-G7*/ "FM_MUX1_SEL_R","","","",
+ "","","","",
+ /*H0-H7*/ "","","","","","","","",
+ /*I0-I7*/ "","","","","","","","",
+ /*J0-J7*/ "","","","","","","","",
+ /*K0-K7*/ "","","","","","","","",
+ /*L0-L7*/ "","","","","","","","",
+ /*M0-M7*/ "","","","","STBY_POWER_PG_3V3","","","",
+ /*N0-N7*/ "LED_POSTCODE_0","LED_POSTCODE_1",
+ "LED_POSTCODE_2","LED_POSTCODE_3",
+ "LED_POSTCODE_4","LED_POSTCODE_5",
+ "LED_POSTCODE_6","LED_POSTCODE_7",
+ /*O0-O7*/ "","","","","","","","debug-card-mux",
+ /*P0-P7*/ "PWR_BTN_BMC_BUF_N","","ID_RST_BTN_BMC_N","",
+ "PWR_LED","","","BMC_HEARTBEAT_N",
+ /*Q0-Q7*/ "","","","","","","","",
+ /*R0-R7*/ "","","","","","","","",
+ /*S0-S7*/ "","","SYS_BMC_PWRBTN_R_N","","","","","",
+ /*T0-T7*/ "","","","","","","","",
+ /*U0-U7*/ "","","","","","","","",
+ /*V0-V7*/ "","","","","","","","",
+ /*W0-W7*/ "","","","","","","","",
+ /*X0-X7*/ "","","","","","","","",
+ /*Y0-Y7*/ "","","","","","","","",
+ /*Z0-Z7*/ "","","","","","","","";
+};
+
+&gpio1 {
+ gpio-line-names =
+ /*18A0-18A7*/ "","","","","","","","",
+ /*18B0-18B7*/ "","","","",
+ "FM_BOARD_BMC_REV_ID0","FM_BOARD_BMC_REV_ID1",
+ "FM_BOARD_BMC_REV_ID2","",
+ /*18C0-18C7*/ "SPI_BMC_BIOS_ROM_IRQ0_R_N","","","","","","","",
+ /*18D0-18D7*/ "","","","","","","","",
+ /*18E0-18E3*/ "FM_BMC_PROT_LS_EN","AC_PWR_BMC_BTN_R_N","","";
+};
+
+&i2c0 {
+ status = "okay";
+
+ i2c-mux@77 {
+ compatible = "nxp,pca9548";
+ reg = <0x77>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ i2c-mux-idle-disconnect;
+
+ i2c0mux0ch0: i2c@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>;
+ temp-sensor@4c {
+ compatible = "adi,adt7461";
+ reg = <0x4c>;
+ };
+ };
+
+ i2c0mux0ch1: i2c@1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <1>;
+ temp-sensor@4c {
+ compatible = "adi,adt7461";
+ reg = <0x4c>;
+ };
+ };
+
+ i2c0mux0ch2: i2c@2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <2>;
+ };
+
+ i2c0mux0ch3: i2c@3 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <3>;
+ status = "okay";
+ };
+
+ i2c0mux0ch4: i2c@4 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <4>;
+ status = "okay";
+ };
+
+ i2c0mux0ch5: i2c@5 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <5>;
+ status = "okay";
+
+ eeprom@56 {
+ compatible = "atmel,24c128";
+ reg = <0x56>;
+ };
+ };
+
+ i2c0mux0ch6: i2c@6 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <6>;
+
+ eeprom@56 {
+ compatible = "atmel,24c128";
+ reg = <0x56>;
+ };
+
+ fan_io_expander0: gpio@20 {
+ compatible = "nxp,pca9555";
+ reg = <0x20>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ fan_io_expander1: gpio@21 {
+ compatible = "nxp,pca9555";
+ reg = <0x21>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ adc@1d {
+ compatible = "ti,adc128d818";
+ reg = <0x1d>;
+ ti,mode = /bits/ 8 <1>;
+ };
+
+ adc@35 {
+ compatible = "maxim,max11617";
+ reg = <0x35>;
+ };
+ };
+
+ i2c0mux0ch7: i2c@7 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <7>;
+
+ fanctl0: fan-controller@20 {
+ compatible = "maxim,max31790";
+ reg = <0x20>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ channel@2 {
+ reg = <2>;
+ sensor-type = "TACH";
+ };
+ channel@5 {
+ reg = <5>;
+ sensor-type = "TACH";
+ };
+ };
+
+ fanctl1: fan-controller@23 {
+ compatible = "nuvoton,nct7363";
+ reg = <0x23>;
+ #pwm-cells = <2>;
+
+ fan-9 {
+ pwms = <&fanctl1 0 20000>;
+ tach-ch = /bits/ 8 <0x09>;
+ };
+
+ fan-11 {
+ pwms = <&fanctl1 0 20000>;
+ tach-ch = /bits/ 8 <0x0B>;
+ };
+
+ fan-10 {
+ pwms = <&fanctl1 4 20000>;
+ tach-ch = /bits/ 8 <0x0A>;
+ };
+
+ fan-13 {
+ pwms = <&fanctl1 4 20000>;
+ tach-ch = /bits/ 8 <0x0D>;
+ };
+
+ fan-15 {
+ pwms = <&fanctl1 6 20000>;
+ tach-ch = /bits/ 8 <0x0F>;
+ };
+
+ fan-1 {
+ pwms = <&fanctl1 6 20000>;
+ tach-ch = /bits/ 8 <0x01>;
+ };
+
+ fan-0 {
+ pwms = <&fanctl1 10 20000>;
+ tach-ch = /bits/ 8 <0x00>;
+ };
+
+ fan-3 {
+ pwms = <&fanctl1 10 20000>;
+ tach-ch = /bits/ 8 <0x03>;
+ };
+ };
+ };
+ };
+};
+
+&i2c1 {
+ status = "okay";
+
+ i2c-mux@77 {
+ compatible = "nxp,pca9548";
+ reg = <0x77>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ i2c-mux-idle-disconnect;
+
+ i2c1mux0ch0: i2c@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>;
+ status = "okay";
+ };
+
+ i2c1mux0ch1: i2c@1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <1>;
+ status = "okay";
+ };
+
+ i2c1mux0ch2: i2c@2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <2>;
+ status = "okay";
+ };
+
+ i2c1mux0ch3: i2c@3 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <3>;
+ status = "okay";
+ };
+
+ i2c1mux0ch4: i2c@4 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <4>;
+ status = "okay";
+ };
+
+ i2c1mux0ch5: i2c@5 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <5>;
+ status = "okay";
+ };
+
+ i2c1mux0ch6: i2c@6 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <6>;
+ status = "okay";
+ };
+
+ i2c1mux0ch7: i2c@7 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <7>;
+ status = "okay";
+ };
+ };
+};
+
+&i2c2 {
+ status = "okay";
+ bus-frequency = <400000>;
+};
+
+&i2c3 {
+ status = "okay";
+ bus-frequency = <400000>;
+
+ dac@c {
+ reg = <0x0c>;
+ compatible = "adi,ad5612";
+ vcc-supply = <&p5v_dac_aux>;
+ };
+
+ dac@e {
+ reg = <0x0e>;
+ compatible = "adi,ad5612";
+ vcc-supply = <&p5v_dac_aux>;
+ };
+
+ dac@f {
+ reg = <0x0f>;
+ compatible = "adi,ad5612";
+ vcc-supply = <&p5v_dac_aux>;
+ };
+
+ io_expander6: gpio@23 {
+ compatible = "nxp,pca9555";
+ reg = <0x23>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-parent = <&io_expander7>;
+ interrupts = <6 IRQ_TYPE_LEVEL_LOW>;
+ };
+
+ prsnt_io_expander0: gpio@40 {
+ compatible = "nxp,pca9698";
+ reg = <0x40>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-parent = <&sgpiom0>;
+ interrupts = <48 IRQ_TYPE_LEVEL_LOW>;
+
+ gpio-line-names =
+ "CAN1_TRAY1_PRSNT", "CAN1_TRAY2_PRSNT",
+ "CAN1_TRAY3_PRSNT", "CAN1_TRAY4_PRSNT",
+ "CAN1_TRAY5_PRSNT", "CAN1_TRAY6_PRSNT",
+ "CAN1_TRAY7_PRSNT", "CAN1_TRAY8_PRSNT",
+ "CAN1_TRAY9_PRSNT", "CAN1_TRAY10_PRSNT",
+ "CAN1_TRAY11_PRSNT", "CAN1_TRAY12_PRSNT",
+ "CAN1_TRAY13_PRSNT", "CAN1_TRAY14_PRSNT",
+ "CAN1_TRAY15_PRSNT", "CAN1_TRAY16_PRSNT",
+ "CAN1_TRAY17_PRSNT", "CAN1_TRAY18_PRSNT",
+ "CAN1_TRAY19_PRSNT", "CAN1_TRAY20_PRSNT",
+ "CAN1_TRAY21_PRSNT", "CAN1_TRAY22_PRSNT",
+ "CAN1_TRAY23_PRSNT", "CAN1_TRAY24_PRSNT",
+ "CAN1_TRAY25_PRSNT", "CAN1_TRAY26_PRSNT",
+ "CAN1_TRAY27_PRSNT", "CAN1_TRAY28_PRSNT",
+ "CAN1_TRAY29_PRSNT", "CAN1_TRAY30_PRSNT",
+ "CAN1_TRAY31_PRSNT", "CAN1_TRAY32_PRSNT",
+ "", "",
+ "", "",
+ "", "",
+ "", "";
+ };
+
+ prsnt_io_expander1: gpio@41 {
+ compatible = "nxp,pca9698";
+ reg = <0x41>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-parent = <&sgpiom0>;
+ interrupts = <56 IRQ_TYPE_LEVEL_LOW>;
+
+ gpio-line-names =
+ "CAN2_TRAY1_PRSNT", "CAN2_TRAY2_PRSNT",
+ "CAN2_TRAY3_PRSNT", "CAN2_TRAY4_PRSNT",
+ "CAN2_TRAY5_PRSNT", "CAN2_TRAY6_PRSNT",
+ "CAN2_TRAY7_PRSNT", "CAN2_TRAY8_PRSNT",
+ "CAN2_TRAY9_PRSNT", "CAN2_TRAY10_PRSNT",
+ "CAN2_TRAY11_PRSNT", "CAN2_TRAY12_PRSNT",
+ "CAN2_TRAY13_PRSNT", "CAN2_TRAY14_PRSNT",
+ "CAN2_TRAY15_PRSNT", "CAN2_TRAY16_PRSNT",
+ "CAN2_TRAY17_PRSNT", "CAN2_TRAY18_PRSNT",
+ "CAN2_TRAY19_PRSNT", "CAN2_TRAY20_PRSNT",
+ "CAN2_TRAY21_PRSNT", "CAN2_TRAY22_PRSNT",
+ "CAN2_TRAY23_PRSNT", "CAN2_TRAY24_PRSNT",
+ "CAN2_TRAY25_PRSNT", "CAN2_TRAY26_PRSNT",
+ "CAN2_TRAY27_PRSNT", "CAN2_TRAY28_PRSNT",
+ "CAN2_TRAY29_PRSNT", "CAN2_TRAY30_PRSNT",
+ "CAN2_TRAY31_PRSNT", "CAN2_TRAY32_PRSNT",
+ "", "",
+ "", "",
+ "", "",
+ "", "";
+ };
+
+ prsnt_io_expander2: gpio@42 {
+ compatible = "nxp,pca9698";
+ reg = <0x42>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-parent = <&sgpiom0>;
+ interrupts = <64 IRQ_TYPE_LEVEL_LOW>;
+
+ gpio-line-names =
+ "CAN3_TRAY1_PRSNT", "CAN3_TRAY2_PRSNT",
+ "CAN3_TRAY3_PRSNT", "CAN3_TRAY4_PRSNT",
+ "CAN3_TRAY5_PRSNT", "CAN3_TRAY6_PRSNT",
+ "CAN3_TRAY7_PRSNT", "CAN3_TRAY8_PRSNT",
+ "CAN3_TRAY9_PRSNT", "CAN3_TRAY10_PRSNT",
+ "CAN3_TRAY11_PRSNT", "CAN3_TRAY12_PRSNT",
+ "CAN3_TRAY13_PRSNT", "CAN3_TRAY14_PRSNT",
+ "CAN3_TRAY15_PRSNT", "CAN3_TRAY16_PRSNT",
+ "CAN3_TRAY17_PRSNT", "CAN3_TRAY18_PRSNT",
+ "CAN3_TRAY19_PRSNT", "CAN3_TRAY20_PRSNT",
+ "CAN3_TRAY21_PRSNT", "CAN3_TRAY22_PRSNT",
+ "CAN3_TRAY23_PRSNT", "CAN3_TRAY24_PRSNT",
+ "CAN3_TRAY25_PRSNT", "CAN3_TRAY26_PRSNT",
+ "CAN3_TRAY27_PRSNT", "CAN3_TRAY28_PRSNT",
+ "CAN3_TRAY29_PRSNT", "CAN3_TRAY30_PRSNT",
+ "CAN3_TRAY31_PRSNT", "CAN3_TRAY32_PRSNT",
+ "", "",
+ "", "",
+ "", "",
+ "", "";
+ };
+
+ prsnt_io_expander3: gpio@43 {
+ compatible = "nxp,pca9698";
+ reg = <0x43>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-parent = <&sgpiom0>;
+ interrupts = <72 IRQ_TYPE_LEVEL_LOW>;
+
+ gpio-line-names =
+ "CAN4_TRAY1_PRSNT", "CAN4_TRAY2_PRSNT",
+ "CAN4_TRAY3_PRSNT", "CAN4_TRAY4_PRSNT",
+ "CAN4_TRAY5_PRSNT", "CAN4_TRAY6_PRSNT",
+ "CAN4_TRAY7_PRSNT", "CAN4_TRAY8_PRSNT",
+ "CAN4_TRAY9_PRSNT", "CAN4_TRAY10_PRSNT",
+ "CAN4_TRAY11_PRSNT", "CAN4_TRAY12_PRSNT",
+ "CAN4_TRAY13_PRSNT", "CAN4_TRAY14_PRSNT",
+ "CAN4_TRAY15_PRSNT", "CAN4_TRAY16_PRSNT",
+ "CAN4_TRAY17_PRSNT", "CAN4_TRAY18_PRSNT",
+ "CAN4_TRAY19_PRSNT", "CAN4_TRAY20_PRSNT",
+ "CAN4_TRAY21_PRSNT", "CAN4_TRAY22_PRSNT",
+ "CAN4_TRAY23_PRSNT", "CAN4_TRAY24_PRSNT",
+ "CAN4_TRAY25_PRSNT", "CAN4_TRAY26_PRSNT",
+ "CAN4_TRAY27_PRSNT", "CAN4_TRAY28_PRSNT",
+ "CAN4_TRAY29_PRSNT", "CAN4_TRAY30_PRSNT",
+ "CAN4_TRAY31_PRSNT", "CAN4_TRAY32_PRSNT",
+ "", "",
+ "", "",
+ "", "",
+ "", "";
+ };
+
+ prsnt_io_expander4: gpio@44 {
+ compatible = "nxp,pca9698";
+ reg = <0x44>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-parent = <&sgpiom0>;
+ interrupts = <80 IRQ_TYPE_LEVEL_LOW>;
+
+ gpio-line-names =
+ "CAN5_TRAY1_PRSNT", "CAN5_TRAY2_PRSNT",
+ "CAN5_TRAY3_PRSNT", "CAN5_TRAY4_PRSNT",
+ "CAN5_TRAY5_PRSNT", "CAN5_TRAY6_PRSNT",
+ "CAN5_TRAY7_PRSNT", "CAN5_TRAY8_PRSNT",
+ "CAN5_TRAY9_PRSNT", "CAN5_TRAY10_PRSNT",
+ "CAN5_TRAY11_PRSNT", "CAN5_TRAY12_PRSNT",
+ "CAN5_TRAY13_PRSNT", "CAN5_TRAY14_PRSNT",
+ "CAN5_TRAY15_PRSNT", "CAN5_TRAY16_PRSNT",
+ "CAN5_TRAY17_PRSNT", "CAN5_TRAY18_PRSNT",
+ "CAN5_TRAY19_PRSNT", "CAN5_TRAY20_PRSNT",
+ "CAN5_TRAY21_PRSNT", "CAN5_TRAY22_PRSNT",
+ "CAN5_TRAY23_PRSNT", "CAN5_TRAY24_PRSNT",
+ "CAN5_TRAY25_PRSNT", "CAN5_TRAY26_PRSNT",
+ "CAN5_TRAY27_PRSNT", "CAN5_TRAY28_PRSNT",
+ "CAN5_TRAY29_PRSNT", "CAN5_TRAY30_PRSNT",
+ "CAN5_TRAY31_PRSNT", "CAN5_TRAY32_PRSNT",
+ "", "",
+ "", "",
+ "", "",
+ "", "";
+ };
+
+ prsnt_io_expander5: gpio@45 {
+ compatible = "nxp,pca9698";
+ reg = <0x45>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-parent = <&sgpiom0>;
+ interrupts = <88 IRQ_TYPE_LEVEL_LOW>;
+
+ gpio-line-names =
+ "CAN6_TRAY1_PRSNT", "CAN6_TRAY2_PRSNT",
+ "CAN6_TRAY3_PRSNT", "CAN6_TRAY4_PRSNT",
+ "CAN6_TRAY5_PRSNT", "CAN6_TRAY6_PRSNT",
+ "CAN6_TRAY7_PRSNT", "CAN6_TRAY8_PRSNT",
+ "CAN6_TRAY9_PRSNT", "CAN6_TRAY10_PRSNT",
+ "CAN6_TRAY11_PRSNT", "CAN6_TRAY12_PRSNT",
+ "CAN6_TRAY13_PRSNT", "CAN6_TRAY14_PRSNT",
+ "CAN6_TRAY15_PRSNT", "CAN6_TRAY16_PRSNT",
+ "CAN6_TRAY17_PRSNT", "CAN6_TRAY18_PRSNT",
+ "CAN6_TRAY19_PRSNT", "CAN6_TRAY20_PRSNT",
+ "CAN6_TRAY21_PRSNT", "CAN6_TRAY22_PRSNT",
+ "CAN6_TRAY23_PRSNT", "CAN6_TRAY24_PRSNT",
+ "CAN6_TRAY25_PRSNT", "CAN6_TRAY26_PRSNT",
+ "CAN6_TRAY27_PRSNT", "CAN6_TRAY28_PRSNT",
+ "CAN6_TRAY29_PRSNT", "CAN6_TRAY30_PRSNT",
+ "CAN6_TRAY31_PRSNT", "CAN6_TRAY32_PRSNT",
+ "", "",
+ "", "",
+ "", "",
+ "", "";
+ };
+
+ prsnt_io_expander6: gpio@46 {
+ compatible = "nxp,pca9698";
+ reg = <0x46>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-parent = <&sgpiom0>;
+ interrupts = <96 IRQ_TYPE_LEVEL_LOW>;
+
+ gpio-line-names =
+ "CAN7_TRAY1_PRSNT", "CAN7_TRAY2_PRSNT",
+ "CAN7_TRAY3_PRSNT", "CAN7_TRAY4_PRSNT",
+ "CAN7_TRAY5_PRSNT", "CAN7_TRAY6_PRSNT",
+ "CAN7_TRAY7_PRSNT", "CAN7_TRAY8_PRSNT",
+ "CAN7_TRAY9_PRSNT", "CAN7_TRAY10_PRSNT",
+ "CAN7_TRAY11_PRSNT", "CAN7_TRAY12_PRSNT",
+ "CAN7_TRAY13_PRSNT", "CAN7_TRAY14_PRSNT",
+ "CAN7_TRAY15_PRSNT", "CAN7_TRAY16_PRSNT",
+ "CAN7_TRAY17_PRSNT", "CAN7_TRAY18_PRSNT",
+ "CAN7_TRAY19_PRSNT", "CAN7_TRAY20_PRSNT",
+ "CAN7_TRAY21_PRSNT", "CAN7_TRAY22_PRSNT",
+ "CAN7_TRAY23_PRSNT", "CAN7_TRAY24_PRSNT",
+ "CAN7_TRAY25_PRSNT", "CAN7_TRAY26_PRSNT",
+ "CAN7_TRAY27_PRSNT", "CAN7_TRAY28_PRSNT",
+ "CAN7_TRAY29_PRSNT", "CAN7_TRAY30_PRSNT",
+ "CAN7_TRAY31_PRSNT", "CAN7_TRAY32_PRSNT",
+ "", "",
+ "", "",
+ "", "",
+ "", "";
+ };
+
+ prsnt_io_expander7: gpio@47 {
+ compatible = "nxp,pca9698";
+ reg = <0x47>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-parent = <&sgpiom0>;
+ interrupts = <104 IRQ_TYPE_LEVEL_LOW>;
+
+ gpio-line-names =
+ "CAN8_TRAY1_PRSNT", "CAN8_TRAY2_PRSNT",
+ "CAN8_TRAY3_PRSNT", "CAN8_TRAY4_PRSNT",
+ "CAN8_TRAY5_PRSNT", "CAN8_TRAY6_PRSNT",
+ "CAN8_TRAY7_PRSNT", "CAN8_TRAY8_PRSNT",
+ "CAN8_TRAY9_PRSNT", "CAN8_TRAY10_PRSNT",
+ "CAN8_TRAY11_PRSNT", "CAN8_TRAY12_PRSNT",
+ "CAN8_TRAY13_PRSNT", "CAN8_TRAY14_PRSNT",
+ "CAN8_TRAY15_PRSNT", "CAN8_TRAY16_PRSNT",
+ "CAN8_TRAY17_PRSNT", "CAN8_TRAY18_PRSNT",
+ "CAN8_TRAY19_PRSNT", "CAN8_TRAY20_PRSNT",
+ "CAN8_TRAY21_PRSNT", "CAN8_TRAY22_PRSNT",
+ "CAN8_TRAY23_PRSNT", "CAN8_TRAY24_PRSNT",
+ "CAN8_TRAY25_PRSNT", "CAN8_TRAY26_PRSNT",
+ "CAN8_TRAY27_PRSNT", "CAN8_TRAY28_PRSNT",
+ "CAN8_TRAY29_PRSNT", "CAN8_TRAY30_PRSNT",
+ "CAN8_TRAY31_PRSNT", "CAN8_TRAY32_PRSNT",
+ "", "",
+ "", "",
+ "", "",
+ "", "";
+ };
+
+ pwrgd_io_expander0: gpio@48 {
+ compatible = "nxp,pca9698";
+ reg = <0x48>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-parent = <&sgpiom0>;
+ interrupts = <50 IRQ_TYPE_LEVEL_LOW>;
+
+ gpio-line-names =
+ "CAN1_TRAY1_PWRGD", "CAN1_TRAY2_PWRGD",
+ "CAN1_TRAY3_PWRGD", "CAN1_TRAY4_PWRGD",
+ "CAN1_TRAY5_PWRGD", "CAN1_TRAY6_PWRGD",
+ "CAN1_TRAY7_PWRGD", "CAN1_TRAY8_PWRGD",
+ "CAN1_TRAY9_PWRGD", "CAN1_TRAY10_PWRGD",
+ "CAN1_TRAY11_PWRGD", "CAN1_TRAY12_PWRGD",
+ "CAN1_TRAY13_PWRGD", "CAN1_TRAY14_PWRGD",
+ "CAN1_TRAY15_PWRGD", "CAN1_TRAY16_PWRGD",
+ "CAN1_TRAY17_PWRGD", "CAN1_TRAY18_PWRGD",
+ "CAN1_TRAY19_PWRGD", "CAN1_TRAY20_PWRGD",
+ "CAN1_TRAY21_PWRGD", "CAN1_TRAY22_PWRGD",
+ "CAN1_TRAY23_PWRGD", "CAN1_TRAY24_PWRGD",
+ "CAN1_TRAY25_PWRGD", "CAN1_TRAY26_PWRGD",
+ "CAN1_TRAY27_PWRGD", "CAN1_TRAY28_PWRGD",
+ "CAN1_TRAY29_PWRGD", "CAN1_TRAY30_PWRGD",
+ "CAN1_TRAY31_PWRGD", "CAN1_TRAY32_PWRGD",
+ "", "",
+ "", "",
+ "", "",
+ "", "";
+ };
+
+ pwrgd_io_expander1: gpio@49 {
+ compatible = "nxp,pca9698";
+ reg = <0x49>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-parent = <&sgpiom0>;
+ interrupts = <58 IRQ_TYPE_LEVEL_LOW>;
+
+ gpio-line-names =
+ "CAN2_TRAY1_PWRGD", "CAN2_TRAY2_PWRGD",
+ "CAN2_TRAY3_PWRGD", "CAN2_TRAY4_PWRGD",
+ "CAN2_TRAY5_PWRGD", "CAN2_TRAY6_PWRGD",
+ "CAN2_TRAY7_PWRGD", "CAN2_TRAY8_PWRGD",
+ "CAN2_TRAY9_PWRGD", "CAN2_TRAY10_PWRGD",
+ "CAN2_TRAY11_PWRGD", "CAN2_TRAY12_PWRGD",
+ "CAN2_TRAY13_PWRGD", "CAN2_TRAY14_PWRGD",
+ "CAN2_TRAY15_PWRGD", "CAN2_TRAY16_PWRGD",
+ "CAN2_TRAY17_PWRGD", "CAN2_TRAY18_PWRGD",
+ "CAN2_TRAY19_PWRGD", "CAN2_TRAY20_PWRGD",
+ "CAN2_TRAY21_PWRGD", "CAN2_TRAY22_PWRGD",
+ "CAN2_TRAY23_PWRGD", "CAN2_TRAY24_PWRGD",
+ "CAN2_TRAY25_PWRGD", "CAN2_TRAY26_PWRGD",
+ "CAN2_TRAY27_PWRGD", "CAN2_TRAY28_PWRGD",
+ "CAN2_TRAY29_PWRGD", "CAN2_TRAY30_PWRGD",
+ "CAN2_TRAY31_PWRGD", "CAN2_TRAY32_PWRGD",
+ "", "",
+ "", "",
+ "", "",
+ "", "";
+ };
+
+ pwrgd_io_expander2: gpio@4a {
+ compatible = "nxp,pca9698";
+ reg = <0x4a>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-parent = <&sgpiom0>;
+ interrupts = <66 IRQ_TYPE_LEVEL_LOW>;
+
+ gpio-line-names =
+ "CAN3_TRAY1_PWRGD", "CAN3_TRAY2_PWRGD",
+ "CAN3_TRAY3_PWRGD", "CAN3_TRAY4_PWRGD",
+ "CAN3_TRAY5_PWRGD", "CAN3_TRAY6_PWRGD",
+ "CAN3_TRAY7_PWRGD", "CAN3_TRAY8_PWRGD",
+ "CAN3_TRAY9_PWRGD", "CAN3_TRAY10_PWRGD",
+ "CAN3_TRAY11_PWRGD", "CAN3_TRAY12_PWRGD",
+ "CAN3_TRAY13_PWRGD", "CAN3_TRAY14_PWRGD",
+ "CAN3_TRAY15_PWRGD", "CAN3_TRAY16_PWRGD",
+ "CAN3_TRAY17_PWRGD", "CAN3_TRAY18_PWRGD",
+ "CAN3_TRAY19_PWRGD", "CAN3_TRAY20_PWRGD",
+ "CAN3_TRAY21_PWRGD", "CAN3_TRAY22_PWRGD",
+ "CAN3_TRAY23_PWRGD", "CAN3_TRAY24_PWRGD",
+ "CAN3_TRAY25_PWRGD", "CAN3_TRAY26_PWRGD",
+ "CAN3_TRAY27_PWRGD", "CAN3_TRAY28_PWRGD",
+ "CAN3_TRAY29_PWRGD", "CAN3_TRAY30_PWRGD",
+ "CAN3_TRAY31_PWRGD", "CAN3_TRAY32_PWRGD",
+ "", "",
+ "", "",
+ "", "",
+ "", "";
+ };
+
+ pwrgd_io_expander3: gpio@4b {
+ compatible = "nxp,pca9698";
+ reg = <0x4b>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-parent = <&sgpiom0>;
+ interrupts = <74 IRQ_TYPE_LEVEL_LOW>;
+
+ gpio-line-names =
+ "CAN4_TRAY1_PWRGD", "CAN4_TRAY2_PWRGD",
+ "CAN4_TRAY3_PWRGD", "CAN4_TRAY4_PWRGD",
+ "CAN4_TRAY5_PWRGD", "CAN4_TRAY6_PWRGD",
+ "CAN4_TRAY7_PWRGD", "CAN4_TRAY8_PWRGD",
+ "CAN4_TRAY9_PWRGD", "CAN4_TRAY10_PWRGD",
+ "CAN4_TRAY11_PWRGD", "CAN4_TRAY12_PWRGD",
+ "CAN4_TRAY13_PWRGD", "CAN4_TRAY14_PWRGD",
+ "CAN4_TRAY15_PWRGD", "CAN4_TRAY16_PWRGD",
+ "CAN4_TRAY17_PWRGD", "CAN4_TRAY18_PWRGD",
+ "CAN4_TRAY19_PWRGD", "CAN4_TRAY20_PWRGD",
+ "CAN4_TRAY21_PWRGD", "CAN4_TRAY22_PWRGD",
+ "CAN4_TRAY23_PWRGD", "CAN4_TRAY24_PWRGD",
+ "CAN4_TRAY25_PWRGD", "CAN4_TRAY26_PWRGD",
+ "CAN4_TRAY27_PWRGD", "CAN4_TRAY28_PWRGD",
+ "CAN4_TRAY29_PWRGD", "CAN4_TRAY30_PWRGD",
+ "CAN4_TRAY31_PWRGD", "CAN4_TRAY32_PWRGD",
+ "", "",
+ "", "",
+ "", "",
+ "", "";
+ };
+
+ pwrgd_io_expander4: gpio@4c {
+ compatible = "nxp,pca9698";
+ reg = <0x4c>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-parent = <&sgpiom0>;
+ interrupts = <82 IRQ_TYPE_LEVEL_LOW>;
+
+ gpio-line-names =
+ "CAN5_TRAY1_PWRGD", "CAN5_TRAY2_PWRGD",
+ "CAN5_TRAY3_PWRGD", "CAN5_TRAY4_PWRGD",
+ "CAN5_TRAY5_PWRGD", "CAN5_TRAY6_PWRGD",
+ "CAN5_TRAY7_PWRGD", "CAN5_TRAY8_PWRGD",
+ "CAN5_TRAY9_PWRGD", "CAN5_TRAY10_PWRGD",
+ "CAN5_TRAY11_PWRGD", "CAN5_TRAY12_PWRGD",
+ "CAN5_TRAY13_PWRGD", "CAN5_TRAY14_PWRGD",
+ "CAN5_TRAY15_PWRGD", "CAN5_TRAY16_PWRGD",
+ "CAN5_TRAY17_PWRGD", "CAN5_TRAY18_PWRGD",
+ "CAN5_TRAY19_PWRGD", "CAN5_TRAY20_PWRGD",
+ "CAN5_TRAY21_PWRGD", "CAN5_TRAY22_PWRGD",
+ "CAN5_TRAY23_PWRGD", "CAN5_TRAY24_PWRGD",
+ "CAN5_TRAY25_PWRGD", "CAN5_TRAY26_PWRGD",
+ "CAN5_TRAY27_PWRGD", "CAN5_TRAY28_PWRGD",
+ "CAN5_TRAY29_PWRGD", "CAN5_TRAY30_PWRGD",
+ "CAN5_TRAY31_PWRGD", "CAN5_TRAY32_PWRGD",
+ "", "",
+ "", "",
+ "", "",
+ "", "";
+ };
+
+ pwrgd_io_expander5: gpio@4d {
+ compatible = "nxp,pca9698";
+ reg = <0x4d>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-parent = <&sgpiom0>;
+ interrupts = <90 IRQ_TYPE_LEVEL_LOW>;
+
+ gpio-line-names =
+ "CAN6_TRAY1_PWRGD", "CAN6_TRAY2_PWRGD",
+ "CAN6_TRAY3_PWRGD", "CAN6_TRAY4_PWRGD",
+ "CAN6_TRAY5_PWRGD", "CAN6_TRAY6_PWRGD",
+ "CAN6_TRAY7_PWRGD", "CAN6_TRAY8_PWRGD",
+ "CAN6_TRAY9_PWRGD", "CAN6_TRAY10_PWRGD",
+ "CAN6_TRAY11_PWRGD", "CAN6_TRAY12_PWRGD",
+ "CAN6_TRAY13_PWRGD", "CAN6_TRAY14_PWRGD",
+ "CAN6_TRAY15_PWRGD", "CAN6_TRAY16_PWRGD",
+ "CAN6_TRAY17_PWRGD", "CAN6_TRAY18_PWRGD",
+ "CAN6_TRAY19_PWRGD", "CAN6_TRAY20_PWRGD",
+ "CAN6_TRAY21_PWRGD", "CAN6_TRAY22_PWRGD",
+ "CAN6_TRAY23_PWRGD", "CAN6_TRAY24_PWRGD",
+ "CAN6_TRAY25_PWRGD", "CAN6_TRAY26_PWRGD",
+ "CAN6_TRAY27_PWRGD", "CAN6_TRAY28_PWRGD",
+ "CAN6_TRAY29_PWRGD", "CAN6_TRAY30_PWRGD",
+ "CAN6_TRAY31_PWRGD", "CAN6_TRAY32_PWRGD",
+ "", "",
+ "", "",
+ "", "",
+ "", "";
+ };
+
+ pwrgd_io_expander6: gpio@4e {
+ compatible = "nxp,pca9698";
+ reg = <0x4e>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-parent = <&sgpiom0>;
+ interrupts = <98 IRQ_TYPE_LEVEL_LOW>;
+
+ gpio-line-names =
+ "CAN7_TRAY1_PWRGD", "CAN7_TRAY2_PWRGD",
+ "CAN7_TRAY3_PWRGD", "CAN7_TRAY4_PWRGD",
+ "CAN7_TRAY5_PWRGD", "CAN7_TRAY6_PWRGD",
+ "CAN7_TRAY7_PWRGD", "CAN7_TRAY8_PWRGD",
+ "CAN7_TRAY9_PWRGD", "CAN7_TRAY10_PWRGD",
+ "CAN7_TRAY11_PWRGD", "CAN7_TRAY12_PWRGD",
+ "CAN7_TRAY13_PWRGD", "CAN7_TRAY14_PWRGD",
+ "CAN7_TRAY15_PWRGD", "CAN7_TRAY16_PWRGD",
+ "CAN7_TRAY17_PWRGD", "CAN7_TRAY18_PWRGD",
+ "CAN7_TRAY19_PWRGD", "CAN7_TRAY20_PWRGD",
+ "CAN7_TRAY21_PWRGD", "CAN7_TRAY22_PWRGD",
+ "CAN7_TRAY23_PWRGD", "CAN7_TRAY24_PWRGD",
+ "CAN7_TRAY25_PWRGD", "CAN7_TRAY26_PWRGD",
+ "CAN7_TRAY27_PWRGD", "CAN7_TRAY28_PWRGD",
+ "CAN7_TRAY29_PWRGD", "CAN7_TRAY30_PWRGD",
+ "CAN7_TRAY31_PWRGD", "CAN7_TRAY32_PWRGD",
+ "", "",
+ "", "",
+ "", "",
+ "", "";
+ };
+
+ pwrgd_io_expander7: gpio@4f {
+ compatible = "nxp,pca9698";
+ reg = <0x4f>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-parent = <&sgpiom0>;
+ interrupts = <106 IRQ_TYPE_LEVEL_LOW>;
+
+ gpio-line-names =
+ "CAN8_TRAY1_PWRGD", "CAN8_TRAY2_PWRGD",
+ "CAN8_TRAY3_PWRGD", "CAN8_TRAY4_PWRGD",
+ "CAN8_TRAY5_PWRGD", "CAN8_TRAY6_PWRGD",
+ "CAN8_TRAY7_PWRGD", "CAN8_TRAY8_PWRGD",
+ "CAN8_TRAY9_PWRGD", "CAN8_TRAY10_PWRGD",
+ "CAN8_TRAY11_PWRGD", "CAN8_TRAY12_PWRGD",
+ "CAN8_TRAY13_PWRGD", "CAN8_TRAY14_PWRGD",
+ "CAN8_TRAY15_PWRGD", "CAN8_TRAY16_PWRGD",
+ "CAN8_TRAY17_PWRGD", "CAN8_TRAY18_PWRGD",
+ "CAN8_TRAY19_PWRGD", "CAN8_TRAY20_PWRGD",
+ "CAN8_TRAY21_PWRGD", "CAN8_TRAY22_PWRGD",
+ "CAN8_TRAY23_PWRGD", "CAN8_TRAY24_PWRGD",
+ "CAN8_TRAY25_PWRGD", "CAN8_TRAY26_PWRGD",
+ "CAN8_TRAY27_PWRGD", "CAN8_TRAY28_PWRGD",
+ "CAN8_TRAY29_PWRGD", "CAN8_TRAY30_PWRGD",
+ "CAN8_TRAY31_PWRGD", "CAN8_TRAY32_PWRGD",
+ "", "",
+ "", "",
+ "", "",
+ "", "";
+ };
+
+ large_leak_io_expander0: gpio@50 {
+ compatible = "nxp,pca9698";
+ reg = <0x50>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-parent = <&sgpiom0>;
+ interrupts = <54 IRQ_TYPE_LEVEL_LOW>;
+
+ gpio-line-names =
+ "CAN1_TRAY1_LARGE_LEAK", "CAN1_TRAY2_LARGE_LEAK",
+ "CAN1_TRAY3_LARGE_LEAK", "CAN1_TRAY4_LARGE_LEAK",
+ "CAN1_TRAY5_LARGE_LEAK", "CAN1_TRAY6_LARGE_LEAK",
+ "CAN1_TRAY7_LARGE_LEAK", "CAN1_TRAY8_LARGE_LEAK",
+ "CAN1_TRAY9_LARGE_LEAK", "CAN1_TRAY10_LARGE_LEAK",
+ "CAN1_TRAY11_LARGE_LEAK", "CAN1_TRAY12_LARGE_LEAK",
+ "CAN1_TRAY13_LARGE_LEAK", "CAN1_TRAY14_LARGE_LEAK",
+ "CAN1_TRAY15_LARGE_LEAK", "CAN1_TRAY16_LARGE_LEAK",
+ "CAN1_TRAY17_LARGE_LEAK", "CAN1_TRAY18_LARGE_LEAK",
+ "CAN1_TRAY19_LARGE_LEAK", "CAN1_TRAY20_LARGE_LEAK",
+ "CAN1_TRAY21_LARGE_LEAK", "CAN1_TRAY22_LARGE_LEAK",
+ "CAN1_TRAY23_LARGE_LEAK", "CAN1_TRAY24_LARGE_LEAK",
+ "CAN1_TRAY25_LARGE_LEAK", "CAN1_TRAY26_LARGE_LEAK",
+ "CAN1_TRAY27_LARGE_LEAK", "CAN1_TRAY28_LARGE_LEAK",
+ "CAN1_TRAY29_LARGE_LEAK", "CAN1_TRAY30_LARGE_LEAK",
+ "CAN1_TRAY31_LARGE_LEAK", "CAN1_TRAY32_LARGE_LEAK",
+ "", "",
+ "", "",
+ "", "",
+ "", "";
+ };
+
+ large_leak_io_expander1: gpio@51 {
+ compatible = "nxp,pca9698";
+ reg = <0x51>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-parent = <&sgpiom0>;
+ interrupts = <62 IRQ_TYPE_LEVEL_LOW>;
+
+ gpio-line-names =
+ "CAN2_TRAY1_LARGE_LEAK", "CAN2_TRAY2_LARGE_LEAK",
+ "CAN2_TRAY3_LARGE_LEAK", "CAN2_TRAY4_LARGE_LEAK",
+ "CAN2_TRAY5_LARGE_LEAK", "CAN2_TRAY6_LARGE_LEAK",
+ "CAN2_TRAY7_LARGE_LEAK", "CAN2_TRAY8_LARGE_LEAK",
+ "CAN2_TRAY9_LARGE_LEAK", "CAN2_TRAY10_LARGE_LEAK",
+ "CAN2_TRAY11_LARGE_LEAK", "CAN2_TRAY12_LARGE_LEAK",
+ "CAN2_TRAY13_LARGE_LEAK", "CAN2_TRAY14_LARGE_LEAK",
+ "CAN2_TRAY15_LARGE_LEAK", "CAN2_TRAY16_LARGE_LEAK",
+ "CAN2_TRAY17_LARGE_LEAK", "CAN2_TRAY18_LARGE_LEAK",
+ "CAN2_TRAY19_LARGE_LEAK", "CAN2_TRAY20_LARGE_LEAK",
+ "CAN2_TRAY21_LARGE_LEAK", "CAN2_TRAY22_LARGE_LEAK",
+ "CAN2_TRAY23_LARGE_LEAK", "CAN2_TRAY24_LARGE_LEAK",
+ "CAN2_TRAY25_LARGE_LEAK", "CAN2_TRAY26_LARGE_LEAK",
+ "CAN2_TRAY27_LARGE_LEAK", "CAN2_TRAY28_LARGE_LEAK",
+ "CAN2_TRAY29_LARGE_LEAK", "CAN2_TRAY30_LARGE_LEAK",
+ "CAN2_TRAY31_LARGE_LEAK", "CAN2_TRAY32_LARGE_LEAK",
+ "", "",
+ "", "",
+ "", "",
+ "", "";
+ };
+
+ large_leak_io_expander2: gpio@52 {
+ compatible = "nxp,pca9698";
+ reg = <0x52>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-parent = <&sgpiom0>;
+ interrupts = <70 IRQ_TYPE_LEVEL_LOW>;
+
+ gpio-line-names =
+ "CAN3_TRAY1_LARGE_LEAK", "CAN3_TRAY2_LARGE_LEAK",
+ "CAN3_TRAY3_LARGE_LEAK", "CAN3_TRAY4_LARGE_LEAK",
+ "CAN3_TRAY5_LARGE_LEAK", "CAN3_TRAY6_LARGE_LEAK",
+ "CAN3_TRAY7_LARGE_LEAK", "CAN3_TRAY8_LARGE_LEAK",
+ "CAN3_TRAY9_LARGE_LEAK", "CAN3_TRAY10_LARGE_LEAK",
+ "CAN3_TRAY11_LARGE_LEAK", "CAN3_TRAY12_LARGE_LEAK",
+ "CAN3_TRAY13_LARGE_LEAK", "CAN3_TRAY14_LARGE_LEAK",
+ "CAN3_TRAY15_LARGE_LEAK", "CAN3_TRAY16_LARGE_LEAK",
+ "CAN3_TRAY17_LARGE_LEAK", "CAN3_TRAY18_LARGE_LEAK",
+ "CAN3_TRAY19_LARGE_LEAK", "CAN3_TRAY20_LARGE_LEAK",
+ "CAN3_TRAY21_LARGE_LEAK", "CAN3_TRAY22_LARGE_LEAK",
+ "CAN3_TRAY23_LARGE_LEAK", "CAN3_TRAY24_LARGE_LEAK",
+ "CAN3_TRAY25_LARGE_LEAK", "CAN3_TRAY26_LARGE_LEAK",
+ "CAN3_TRAY27_LARGE_LEAK", "CAN3_TRAY28_LARGE_LEAK",
+ "CAN3_TRAY29_LARGE_LEAK", "CAN3_TRAY30_LARGE_LEAK",
+ "CAN3_TRAY31_LARGE_LEAK", "CAN3_TRAY32_LARGE_LEAK",
+ "", "",
+ "", "",
+ "", "",
+ "", "";
+ };
+
+ large_leak_io_expander3: gpio@53 {
+ compatible = "nxp,pca9698";
+ reg = <0x53>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-parent = <&sgpiom0>;
+ interrupts = <78 IRQ_TYPE_LEVEL_LOW>;
+
+ gpio-line-names =
+ "CAN4_TRAY1_LARGE_LEAK", "CAN4_TRAY2_LARGE_LEAK",
+ "CAN4_TRAY3_LARGE_LEAK", "CAN4_TRAY4_LARGE_LEAK",
+ "CAN4_TRAY5_LARGE_LEAK", "CAN4_TRAY6_LARGE_LEAK",
+ "CAN4_TRAY7_LARGE_LEAK", "CAN4_TRAY8_LARGE_LEAK",
+ "CAN4_TRAY9_LARGE_LEAK", "CAN4_TRAY10_LARGE_LEAK",
+ "CAN4_TRAY11_LARGE_LEAK", "CAN4_TRAY12_LARGE_LEAK",
+ "CAN4_TRAY13_LARGE_LEAK", "CAN4_TRAY14_LARGE_LEAK",
+ "CAN4_TRAY15_LARGE_LEAK", "CAN4_TRAY16_LARGE_LEAK",
+ "CAN4_TRAY17_LARGE_LEAK", "CAN4_TRAY18_LARGE_LEAK",
+ "CAN4_TRAY19_LARGE_LEAK", "CAN4_TRAY20_LARGE_LEAK",
+ "CAN4_TRAY21_LARGE_LEAK", "CAN4_TRAY22_LARGE_LEAK",
+ "CAN4_TRAY23_LARGE_LEAK", "CAN4_TRAY24_LARGE_LEAK",
+ "CAN4_TRAY25_LARGE_LEAK", "CAN4_TRAY26_LARGE_LEAK",
+ "CAN4_TRAY27_LARGE_LEAK", "CAN4_TRAY28_LARGE_LEAK",
+ "CAN4_TRAY29_LARGE_LEAK", "CAN4_TRAY30_LARGE_LEAK",
+ "CAN4_TRAY31_LARGE_LEAK", "CAN4_TRAY32_LARGE_LEAK",
+ "", "",
+ "", "",
+ "", "",
+ "", "";
+ };
+
+ large_leak_io_expander4: gpio@54 {
+ compatible = "nxp,pca9698";
+ reg = <0x54>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-parent = <&sgpiom0>;
+ interrupts = <86 IRQ_TYPE_LEVEL_LOW>;
+
+ gpio-line-names =
+ "CAN5_TRAY1_LARGE_LEAK", "CAN5_TRAY2_LARGE_LEAK",
+ "CAN5_TRAY3_LARGE_LEAK", "CAN5_TRAY4_LARGE_LEAK",
+ "CAN5_TRAY5_LARGE_LEAK", "CAN5_TRAY6_LARGE_LEAK",
+ "CAN5_TRAY7_LARGE_LEAK", "CAN5_TRAY8_LARGE_LEAK",
+ "CAN5_TRAY9_LARGE_LEAK", "CAN5_TRAY10_LARGE_LEAK",
+ "CAN5_TRAY11_LARGE_LEAK", "CAN5_TRAY12_LARGE_LEAK",
+ "CAN5_TRAY13_LARGE_LEAK", "CAN5_TRAY14_LARGE_LEAK",
+ "CAN5_TRAY15_LARGE_LEAK", "CAN5_TRAY16_LARGE_LEAK",
+ "CAN5_TRAY17_LARGE_LEAK", "CAN5_TRAY18_LARGE_LEAK",
+ "CAN5_TRAY19_LARGE_LEAK", "CAN5_TRAY20_LARGE_LEAK",
+ "CAN5_TRAY21_LARGE_LEAK", "CAN5_TRAY22_LARGE_LEAK",
+ "CAN5_TRAY23_LARGE_LEAK", "CAN5_TRAY24_LARGE_LEAK",
+ "CAN5_TRAY25_LARGE_LEAK", "CAN5_TRAY26_LARGE_LEAK",
+ "CAN5_TRAY27_LARGE_LEAK", "CAN5_TRAY28_LARGE_LEAK",
+ "CAN5_TRAY29_LARGE_LEAK", "CAN5_TRAY30_LARGE_LEAK",
+ "CAN5_TRAY31_LARGE_LEAK", "CAN5_TRAY32_LARGE_LEAK",
+ "", "",
+ "", "",
+ "", "",
+ "", "";
+ };
+
+ large_leak_io_expander5: gpio@55 {
+ compatible = "nxp,pca9698";
+ reg = <0x55>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-parent = <&sgpiom0>;
+ interrupts = <94 IRQ_TYPE_LEVEL_LOW>;
+
+ gpio-line-names =
+ "CAN6_TRAY1_LARGE_LEAK", "CAN6_TRAY2_LARGE_LEAK",
+ "CAN6_TRAY3_LARGE_LEAK", "CAN6_TRAY4_LARGE_LEAK",
+ "CAN6_TRAY5_LARGE_LEAK", "CAN6_TRAY6_LARGE_LEAK",
+ "CAN6_TRAY7_LARGE_LEAK", "CAN6_TRAY8_LARGE_LEAK",
+ "CAN6_TRAY9_LARGE_LEAK", "CAN6_TRAY10_LARGE_LEAK",
+ "CAN6_TRAY11_LARGE_LEAK", "CAN6_TRAY12_LARGE_LEAK",
+ "CAN6_TRAY13_LARGE_LEAK", "CAN6_TRAY14_LARGE_LEAK",
+ "CAN6_TRAY15_LARGE_LEAK", "CAN6_TRAY16_LARGE_LEAK",
+ "CAN6_TRAY17_LARGE_LEAK", "CAN6_TRAY18_LARGE_LEAK",
+ "CAN6_TRAY19_LARGE_LEAK", "CAN6_TRAY20_LARGE_LEAK",
+ "CAN6_TRAY21_LARGE_LEAK", "CAN6_TRAY22_LARGE_LEAK",
+ "CAN6_TRAY23_LARGE_LEAK", "CAN6_TRAY24_LARGE_LEAK",
+ "CAN6_TRAY25_LARGE_LEAK", "CAN6_TRAY26_LARGE_LEAK",
+ "CAN6_TRAY27_LARGE_LEAK", "CAN6_TRAY28_LARGE_LEAK",
+ "CAN6_TRAY29_LARGE_LEAK", "CAN6_TRAY30_LARGE_LEAK",
+ "CAN6_TRAY31_LARGE_LEAK", "CAN6_TRAY32_LARGE_LEAK",
+ "", "",
+ "", "",
+ "", "",
+ "", "";
+ };
+
+ large_leak_io_expander6: gpio@56 {
+ compatible = "nxp,pca9698";
+ reg = <0x56>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-parent = <&sgpiom0>;
+ interrupts = <102 IRQ_TYPE_LEVEL_LOW>;
+
+ gpio-line-names =
+ "CAN7_TRAY1_LARGE_LEAK", "CAN7_TRAY2_LARGE_LEAK",
+ "CAN7_TRAY3_LARGE_LEAK", "CAN7_TRAY4_LARGE_LEAK",
+ "CAN7_TRAY5_LARGE_LEAK", "CAN7_TRAY6_LARGE_LEAK",
+ "CAN7_TRAY7_LARGE_LEAK", "CAN7_TRAY8_LARGE_LEAK",
+ "CAN7_TRAY9_LARGE_LEAK", "CAN7_TRAY10_LARGE_LEAK",
+ "CAN7_TRAY11_LARGE_LEAK", "CAN7_TRAY12_LARGE_LEAK",
+ "CAN7_TRAY13_LARGE_LEAK", "CAN7_TRAY14_LARGE_LEAK",
+ "CAN7_TRAY15_LARGE_LEAK", "CAN7_TRAY16_LARGE_LEAK",
+ "CAN7_TRAY17_LARGE_LEAK", "CAN7_TRAY18_LARGE_LEAK",
+ "CAN7_TRAY19_LARGE_LEAK", "CAN7_TRAY20_LARGE_LEAK",
+ "CAN7_TRAY21_LARGE_LEAK", "CAN7_TRAY22_LARGE_LEAK",
+ "CAN7_TRAY23_LARGE_LEAK", "CAN7_TRAY24_LARGE_LEAK",
+ "CAN7_TRAY25_LARGE_LEAK", "CAN7_TRAY26_LARGE_LEAK",
+ "CAN7_TRAY27_LARGE_LEAK", "CAN7_TRAY28_LARGE_LEAK",
+ "CAN7_TRAY29_LARGE_LEAK", "CAN7_TRAY30_LARGE_LEAK",
+ "CAN7_TRAY31_LARGE_LEAK", "CAN7_TRAY32_LARGE_LEAK",
+ "", "",
+ "", "",
+ "", "",
+ "", "";
+ };
+
+ large_leak_io_expander7: gpio@57 {
+ compatible = "nxp,pca9698";
+ reg = <0x57>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-parent = <&sgpiom0>;
+ interrupts = <110 IRQ_TYPE_LEVEL_LOW>;
+
+ gpio-line-names =
+ "CAN8_TRAY1_LARGE_LEAK", "CAN8_TRAY2_LARGE_LEAK",
+ "CAN8_TRAY3_LARGE_LEAK", "CAN8_TRAY4_LARGE_LEAK",
+ "CAN8_TRAY5_LARGE_LEAK", "CAN8_TRAY6_LARGE_LEAK",
+ "CAN8_TRAY7_LARGE_LEAK", "CAN8_TRAY8_LARGE_LEAK",
+ "CAN8_TRAY9_LARGE_LEAK", "CAN8_TRAY10_LARGE_LEAK",
+ "CAN8_TRAY11_LARGE_LEAK", "CAN8_TRAY12_LARGE_LEAK",
+ "CAN8_TRAY13_LARGE_LEAK", "CAN8_TRAY14_LARGE_LEAK",
+ "CAN8_TRAY15_LARGE_LEAK", "CAN8_TRAY16_LARGE_LEAK",
+ "CAN8_TRAY17_LARGE_LEAK", "CAN8_TRAY18_LARGE_LEAK",
+ "CAN8_TRAY19_LARGE_LEAK", "CAN8_TRAY20_LARGE_LEAK",
+ "CAN8_TRAY21_LARGE_LEAK", "CAN8_TRAY22_LARGE_LEAK",
+ "CAN8_TRAY23_LARGE_LEAK", "CAN8_TRAY24_LARGE_LEAK",
+ "CAN8_TRAY25_LARGE_LEAK", "CAN8_TRAY26_LARGE_LEAK",
+ "CAN8_TRAY27_LARGE_LEAK", "CAN8_TRAY28_LARGE_LEAK",
+ "CAN8_TRAY29_LARGE_LEAK", "CAN8_TRAY30_LARGE_LEAK",
+ "CAN8_TRAY31_LARGE_LEAK", "CAN8_TRAY32_LARGE_LEAK",
+ "", "",
+ "", "",
+ "", "",
+ "", "";
+ };
+
+ small_leak_io_expander0: gpio@58 {
+ compatible = "nxp,pca9698";
+ reg = <0x58>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-parent = <&sgpiom0>;
+ interrupts = <52 IRQ_TYPE_LEVEL_LOW>;
+
+ gpio-line-names =
+ "CAN1_TRAY1_SMALL_LEAK", "CAN1_TRAY2_SMALL_LEAK",
+ "CAN1_TRAY3_SMALL_LEAK", "CAN1_TRAY4_SMALL_LEAK",
+ "CAN1_TRAY5_SMALL_LEAK", "CAN1_TRAY6_SMALL_LEAK",
+ "CAN1_TRAY7_SMALL_LEAK", "CAN1_TRAY8_SMALL_LEAK",
+ "CAN1_TRAY9_SMALL_LEAK", "CAN1_TRAY10_SMALL_LEAK",
+ "CAN1_TRAY11_SMALL_LEAK", "CAN1_TRAY12_SMALL_LEAK",
+ "CAN1_TRAY13_SMALL_LEAK", "CAN1_TRAY14_SMALL_LEAK",
+ "CAN1_TRAY15_SMALL_LEAK", "CAN1_TRAY16_SMALL_LEAK",
+ "CAN1_TRAY17_SMALL_LEAK", "CAN1_TRAY18_SMALL_LEAK",
+ "CAN1_TRAY19_SMALL_LEAK", "CAN1_TRAY20_SMALL_LEAK",
+ "CAN1_TRAY21_SMALL_LEAK", "CAN1_TRAY22_SMALL_LEAK",
+ "CAN1_TRAY23_SMALL_LEAK", "CAN1_TRAY24_SMALL_LEAK",
+ "CAN1_TRAY25_SMALL_LEAK", "CAN1_TRAY26_SMALL_LEAK",
+ "CAN1_TRAY27_SMALL_LEAK", "CAN1_TRAY28_SMALL_LEAK",
+ "CAN1_TRAY29_SMALL_LEAK", "CAN1_TRAY30_SMALL_LEAK",
+ "CAN1_TRAY31_SMALL_LEAK", "CAN1_TRAY32_SMALL_LEAK",
+ "", "",
+ "", "",
+ "", "",
+ "", "";
+ };
+
+ small_leak_io_expander1: gpio@59 {
+ compatible = "nxp,pca9698";
+ reg = <0x59>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-parent = <&sgpiom0>;
+ interrupts = <60 IRQ_TYPE_LEVEL_LOW>;
+
+ gpio-line-names =
+ "CAN2_TRAY1_SMALL_LEAK", "CAN2_TRAY2_SMALL_LEAK",
+ "CAN2_TRAY3_SMALL_LEAK", "CAN2_TRAY4_SMALL_LEAK",
+ "CAN2_TRAY5_SMALL_LEAK", "CAN2_TRAY6_SMALL_LEAK",
+ "CAN2_TRAY7_SMALL_LEAK", "CAN2_TRAY8_SMALL_LEAK",
+ "CAN2_TRAY9_SMALL_LEAK", "CAN2_TRAY10_SMALL_LEAK",
+ "CAN2_TRAY11_SMALL_LEAK", "CAN2_TRAY12_SMALL_LEAK",
+ "CAN2_TRAY13_SMALL_LEAK", "CAN2_TRAY14_SMALL_LEAK",
+ "CAN2_TRAY15_SMALL_LEAK", "CAN2_TRAY16_SMALL_LEAK",
+ "CAN2_TRAY17_SMALL_LEAK", "CAN2_TRAY18_SMALL_LEAK",
+ "CAN2_TRAY19_SMALL_LEAK", "CAN2_TRAY20_SMALL_LEAK",
+ "CAN2_TRAY21_SMALL_LEAK", "CAN2_TRAY22_SMALL_LEAK",
+ "CAN2_TRAY23_SMALL_LEAK", "CAN2_TRAY24_SMALL_LEAK",
+ "CAN2_TRAY25_SMALL_LEAK", "CAN2_TRAY26_SMALL_LEAK",
+ "CAN2_TRAY27_SMALL_LEAK", "CAN2_TRAY28_SMALL_LEAK",
+ "CAN2_TRAY29_SMALL_LEAK", "CAN2_TRAY30_SMALL_LEAK",
+ "CAN2_TRAY31_SMALL_LEAK", "CAN2_TRAY32_SMALL_LEAK",
+ "", "",
+ "", "",
+ "", "",
+ "", "";
+ };
+
+ small_leak_io_expander2: gpio@5a {
+ compatible = "nxp,pca9698";
+ reg = <0x5a>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-parent = <&sgpiom0>;
+ interrupts = <68 IRQ_TYPE_LEVEL_LOW>;
+
+ gpio-line-names =
+ "CAN3_TRAY1_SMALL_LEAK", "CAN3_TRAY2_SMALL_LEAK",
+ "CAN3_TRAY3_SMALL_LEAK", "CAN3_TRAY4_SMALL_LEAK",
+ "CAN3_TRAY5_SMALL_LEAK", "CAN3_TRAY6_SMALL_LEAK",
+ "CAN3_TRAY7_SMALL_LEAK", "CAN3_TRAY8_SMALL_LEAK",
+ "CAN3_TRAY9_SMALL_LEAK", "CAN3_TRAY10_SMALL_LEAK",
+ "CAN3_TRAY11_SMALL_LEAK", "CAN3_TRAY12_SMALL_LEAK",
+ "CAN3_TRAY13_SMALL_LEAK", "CAN3_TRAY14_SMALL_LEAK",
+ "CAN3_TRAY15_SMALL_LEAK", "CAN3_TRAY16_SMALL_LEAK",
+ "CAN3_TRAY17_SMALL_LEAK", "CAN3_TRAY18_SMALL_LEAK",
+ "CAN3_TRAY19_SMALL_LEAK", "CAN3_TRAY20_SMALL_LEAK",
+ "CAN3_TRAY21_SMALL_LEAK", "CAN3_TRAY22_SMALL_LEAK",
+ "CAN3_TRAY23_SMALL_LEAK", "CAN3_TRAY24_SMALL_LEAK",
+ "CAN3_TRAY25_SMALL_LEAK", "CAN3_TRAY26_SMALL_LEAK",
+ "CAN3_TRAY27_SMALL_LEAK", "CAN3_TRAY28_SMALL_LEAK",
+ "CAN3_TRAY29_SMALL_LEAK", "CAN3_TRAY30_SMALL_LEAK",
+ "CAN3_TRAY31_SMALL_LEAK", "CAN3_TRAY32_SMALL_LEAK",
+ "", "",
+ "", "",
+ "", "",
+ "", "";
+ };
+
+ small_leak_io_expander3: gpio@5b {
+ compatible = "nxp,pca9698";
+ reg = <0x5b>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-parent = <&sgpiom0>;
+ interrupts = <76 IRQ_TYPE_LEVEL_LOW>;
+
+ gpio-line-names =
+ "CAN4_TRAY1_SMALL_LEAK", "CAN4_TRAY2_SMALL_LEAK",
+ "CAN4_TRAY3_SMALL_LEAK", "CAN4_TRAY4_SMALL_LEAK",
+ "CAN4_TRAY5_SMALL_LEAK", "CAN4_TRAY6_SMALL_LEAK",
+ "CAN4_TRAY7_SMALL_LEAK", "CAN4_TRAY8_SMALL_LEAK",
+ "CAN4_TRAY9_SMALL_LEAK", "CAN4_TRAY10_SMALL_LEAK",
+ "CAN4_TRAY11_SMALL_LEAK", "CAN4_TRAY12_SMALL_LEAK",
+ "CAN4_TRAY13_SMALL_LEAK", "CAN4_TRAY14_SMALL_LEAK",
+ "CAN4_TRAY15_SMALL_LEAK", "CAN4_TRAY16_SMALL_LEAK",
+ "CAN4_TRAY17_SMALL_LEAK", "CAN4_TRAY18_SMALL_LEAK",
+ "CAN4_TRAY19_SMALL_LEAK", "CAN4_TRAY20_SMALL_LEAK",
+ "CAN4_TRAY21_SMALL_LEAK", "CAN4_TRAY22_SMALL_LEAK",
+ "CAN4_TRAY23_SMALL_LEAK", "CAN4_TRAY24_SMALL_LEAK",
+ "CAN4_TRAY25_SMALL_LEAK", "CAN4_TRAY26_SMALL_LEAK",
+ "CAN4_TRAY27_SMALL_LEAK", "CAN4_TRAY28_SMALL_LEAK",
+ "CAN4_TRAY29_SMALL_LEAK", "CAN4_TRAY30_SMALL_LEAK",
+ "CAN4_TRAY31_SMALL_LEAK", "CAN4_TRAY32_SMALL_LEAK",
+ "", "",
+ "", "",
+ "", "",
+ "", "";
+ };
+
+ small_leak_io_expander4: gpio@5c {
+ compatible = "nxp,pca9698";
+ reg = <0x5c>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-parent = <&sgpiom0>;
+ interrupts = <84 IRQ_TYPE_LEVEL_LOW>;
+
+ gpio-line-names =
+ "CAN5_TRAY1_SMALL_LEAK", "CAN5_TRAY2_SMALL_LEAK",
+ "CAN5_TRAY3_SMALL_LEAK", "CAN5_TRAY4_SMALL_LEAK",
+ "CAN5_TRAY5_SMALL_LEAK", "CAN5_TRAY6_SMALL_LEAK",
+ "CAN5_TRAY7_SMALL_LEAK", "CAN5_TRAY8_SMALL_LEAK",
+ "CAN5_TRAY9_SMALL_LEAK", "CAN5_TRAY10_SMALL_LEAK",
+ "CAN5_TRAY11_SMALL_LEAK", "CAN5_TRAY12_SMALL_LEAK",
+ "CAN5_TRAY13_SMALL_LEAK", "CAN5_TRAY14_SMALL_LEAK",
+ "CAN5_TRAY15_SMALL_LEAK", "CAN5_TRAY16_SMALL_LEAK",
+ "CAN5_TRAY17_SMALL_LEAK", "CAN5_TRAY18_SMALL_LEAK",
+ "CAN5_TRAY19_SMALL_LEAK", "CAN5_TRAY20_SMALL_LEAK",
+ "CAN5_TRAY21_SMALL_LEAK", "CAN5_TRAY22_SMALL_LEAK",
+ "CAN5_TRAY23_SMALL_LEAK", "CAN5_TRAY24_SMALL_LEAK",
+ "CAN5_TRAY25_SMALL_LEAK", "CAN5_TRAY26_SMALL_LEAK",
+ "CAN5_TRAY27_SMALL_LEAK", "CAN5_TRAY28_SMALL_LEAK",
+ "CAN5_TRAY29_SMALL_LEAK", "CAN5_TRAY30_SMALL_LEAK",
+ "CAN5_TRAY31_SMALL_LEAK", "CAN5_TRAY32_SMALL_LEAK",
+ "", "",
+ "", "",
+ "", "",
+ "", "";
+ };
+
+ small_leak_io_expander5: gpio@5d {
+ compatible = "nxp,pca9698";
+ reg = <0x5d>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-parent = <&sgpiom0>;
+ interrupts = <92 IRQ_TYPE_LEVEL_LOW>;
+
+ gpio-line-names =
+ "CAN6_TRAY1_SMALL_LEAK", "CAN6_TRAY2_SMALL_LEAK",
+ "CAN6_TRAY3_SMALL_LEAK", "CAN6_TRAY4_SMALL_LEAK",
+ "CAN6_TRAY5_SMALL_LEAK", "CAN6_TRAY6_SMALL_LEAK",
+ "CAN6_TRAY7_SMALL_LEAK", "CAN6_TRAY8_SMALL_LEAK",
+ "CAN6_TRAY9_SMALL_LEAK", "CAN6_TRAY10_SMALL_LEAK",
+ "CAN6_TRAY11_SMALL_LEAK", "CAN6_TRAY12_SMALL_LEAK",
+ "CAN6_TRAY13_SMALL_LEAK", "CAN6_TRAY14_SMALL_LEAK",
+ "CAN6_TRAY15_SMALL_LEAK", "CAN6_TRAY16_SMALL_LEAK",
+ "CAN6_TRAY17_SMALL_LEAK", "CAN6_TRAY18_SMALL_LEAK",
+ "CAN6_TRAY19_SMALL_LEAK", "CAN6_TRAY20_SMALL_LEAK",
+ "CAN6_TRAY21_SMALL_LEAK", "CAN6_TRAY22_SMALL_LEAK",
+ "CAN6_TRAY23_SMALL_LEAK", "CAN6_TRAY24_SMALL_LEAK",
+ "CAN6_TRAY25_SMALL_LEAK", "CAN6_TRAY26_SMALL_LEAK",
+ "CAN6_TRAY27_SMALL_LEAK", "CAN6_TRAY28_SMALL_LEAK",
+ "CAN6_TRAY29_SMALL_LEAK", "CAN6_TRAY30_SMALL_LEAK",
+ "CAN6_TRAY31_SMALL_LEAK", "CAN6_TRAY32_SMALL_LEAK",
+ "", "",
+ "", "",
+ "", "",
+ "", "";
+ };
+
+ small_leak_io_expander6: gpio@5e {
+ compatible = "nxp,pca9698";
+ reg = <0x5e>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-parent = <&sgpiom0>;
+ interrupts = <100 IRQ_TYPE_LEVEL_LOW>;
+
+ gpio-line-names =
+ "CAN7_TRAY1_SMALL_LEAK", "CAN7_TRAY2_SMALL_LEAK",
+ "CAN7_TRAY3_SMALL_LEAK", "CAN7_TRAY4_SMALL_LEAK",
+ "CAN7_TRAY5_SMALL_LEAK", "CAN7_TRAY6_SMALL_LEAK",
+ "CAN7_TRAY7_SMALL_LEAK", "CAN7_TRAY8_SMALL_LEAK",
+ "CAN7_TRAY9_SMALL_LEAK", "CAN7_TRAY10_SMALL_LEAK",
+ "CAN7_TRAY11_SMALL_LEAK", "CAN7_TRAY12_SMALL_LEAK",
+ "CAN7_TRAY13_SMALL_LEAK", "CAN7_TRAY14_SMALL_LEAK",
+ "CAN7_TRAY15_SMALL_LEAK", "CAN7_TRAY16_SMALL_LEAK",
+ "CAN7_TRAY17_SMALL_LEAK", "CAN7_TRAY18_SMALL_LEAK",
+ "CAN7_TRAY19_SMALL_LEAK", "CAN7_TRAY20_SMALL_LEAK",
+ "CAN7_TRAY21_SMALL_LEAK", "CAN7_TRAY22_SMALL_LEAK",
+ "CAN7_TRAY23_SMALL_LEAK", "CAN7_TRAY24_SMALL_LEAK",
+ "CAN7_TRAY25_SMALL_LEAK", "CAN7_TRAY26_SMALL_LEAK",
+ "CAN7_TRAY27_SMALL_LEAK", "CAN7_TRAY28_SMALL_LEAK",
+ "CAN7_TRAY29_SMALL_LEAK", "CAN7_TRAY30_SMALL_LEAK",
+ "CAN7_TRAY31_SMALL_LEAK", "CAN7_TRAY32_SMALL_LEAK",
+ "", "",
+ "", "",
+ "", "",
+ "", "";
+ };
+
+ small_leak_io_expander7: gpio@5f {
+ compatible = "nxp,pca9698";
+ reg = <0x5f>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-parent = <&sgpiom0>;
+ interrupts = <108 IRQ_TYPE_LEVEL_LOW>;
+
+ gpio-line-names =
+ "CAN8_TRAY1_SMALL_LEAK", "CAN8_TRAY2_SMALL_LEAK",
+ "CAN8_TRAY3_SMALL_LEAK", "CAN8_TRAY4_SMALL_LEAK",
+ "CAN8_TRAY5_SMALL_LEAK", "CAN8_TRAY6_SMALL_LEAK",
+ "CAN8_TRAY7_SMALL_LEAK", "CAN8_TRAY8_SMALL_LEAK",
+ "CAN8_TRAY9_SMALL_LEAK", "CAN8_TRAY10_SMALL_LEAK",
+ "CAN8_TRAY11_SMALL_LEAK", "CAN8_TRAY12_SMALL_LEAK",
+ "CAN8_TRAY13_SMALL_LEAK", "CAN8_TRAY14_SMALL_LEAK",
+ "CAN8_TRAY15_SMALL_LEAK", "CAN8_TRAY16_SMALL_LEAK",
+ "CAN8_TRAY17_SMALL_LEAK", "CAN8_TRAY18_SMALL_LEAK",
+ "CAN8_TRAY19_SMALL_LEAK", "CAN8_TRAY20_SMALL_LEAK",
+ "CAN8_TRAY21_SMALL_LEAK", "CAN8_TRAY22_SMALL_LEAK",
+ "CAN8_TRAY23_SMALL_LEAK", "CAN8_TRAY24_SMALL_LEAK",
+ "CAN8_TRAY25_SMALL_LEAK", "CAN8_TRAY26_SMALL_LEAK",
+ "CAN8_TRAY27_SMALL_LEAK", "CAN8_TRAY28_SMALL_LEAK",
+ "CAN8_TRAY29_SMALL_LEAK", "CAN8_TRAY30_SMALL_LEAK",
+ "CAN8_TRAY31_SMALL_LEAK", "CAN8_TRAY32_SMALL_LEAK",
+ "", "",
+ "", "",
+ "", "",
+ "", "";
+ };
+};
+
+&i2c4 {
+ status = "okay";
+ multi-master;
+ mctp-controller;
+ mctp0: mctp@10 {
+ compatible = "mctp-i2c-controller";
+ reg = <(0x10 | I2C_OWN_SLAVE_ADDRESS)>;
+ };
+
+ i2c-mux@77 {
+ compatible = "nxp,pca9548";
+ reg = <0x77>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ i2c4mux0ch0: i2c@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>;
+
+ io_expander3: gpio@23 {
+ compatible = "nxp,pca9555";
+ reg = <0x23>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-parent = <&io_expander7>;
+ interrupts = <3 IRQ_TYPE_LEVEL_LOW>;
+
+ gpio-line-names =
+ "", "",
+ "", "RST_I2CRST_MUX1_N",
+ "RST_I2CRST_MUX2_N", "RST_I2CRST_MUX3_N",
+ "RST_I2CRST_MUX4_N", "RST_I2CRST_MUX5_N",
+ "RST_I2CRST_MUX6_N", "RST_I2CRST_MUX7_N",
+ "RST_I2CRST_MUX8_N", "",
+ "TRAY30_PWRGD_BUF_R", "TRAY31_PWRGD_BUF_R",
+ "TRAY32_PWRGD_BUF_R", "TRAY37_PWRGD_BUF_R";
+ };
+ };
+
+ i2c4mux0ch1: i2c@1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <1>;
+
+ temp-sensor@48 {
+ compatible = "ti,tmp75";
+ reg = <0x48>;
+ };
+
+ temp-sensor@4a {
+ compatible = "ti,tmp75";
+ reg = <0x4a>;
+ };
+
+ eeprom@56 {
+ compatible = "atmel,24c128";
+ reg = <0x56>;
+ };
+ };
+
+ i2c4mux0ch2: i2c@2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <2>;
+
+ power-monitor@11 {
+ compatible = "infineon,tda38640";
+ reg = <0x11>;
+ };
+
+ power-monitor@22 {
+ compatible = "infineon,tda38640";
+ reg = <0x22>;
+ };
+
+ power-monitor@45 {
+ compatible = "infineon,tda38640";
+ reg = <0x45>;
+ };
+
+ power-monitor@66 {
+ compatible = "infineon,tda38640";
+ reg = <0x66>;
+ };
+ };
+
+ i2c4mux0ch3: i2c@3 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <3>;
+ status = "okay";
+ };
+
+ i2c4mux0ch4: i2c@4 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <4>;
+ status = "okay";
+ };
+
+ i2c4mux0ch5: i2c@5 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <5>;
+ status = "okay";
+ };
+
+ i2c4mux0ch6: i2c@6 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <6>;
+ mctp-controller;
+ };
+
+ i2c4mux0ch7: i2c@7 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <7>;
+ status = "okay";
+ };
+ };
+};
+
+&i2c5 {
+ status = "okay";
+
+ io_expander4: gpio@22 {
+ compatible = "nxp,pca9555";
+ reg = <0x22>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-parent = <&io_expander7>;
+ interrupts = <4 IRQ_TYPE_LEVEL_LOW>;
+
+ gpio-line-names =
+ "R_COME_THERMTRIP_L", "R_PWRGD_PCH_PWROK",
+ "", "",
+ "", "",
+ "", "",
+ "", "",
+ "", "",
+ "", "TRAY38_PWRGD_BUF_R",
+ "TRAY39_PWRGD_BUF_R", "TRAY40_PWRGD_BUF_R";
+ };
+
+ io_expander5: gpio@23 {
+ compatible = "nxp,pca9555";
+ reg = <0x23>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-parent = <&io_expander7>;
+ interrupts = <5 IRQ_TYPE_LEVEL_LOW>;
+
+ gpio-line-names =
+ "PWRGD_P5V_AUX_R2", "",
+ "PWRGD_P1V5_AUX_R", "PWRGD_P1V05_AUX_R",
+ "PWRGD_P52V_HSC_PWROK_R", "PWRGD_P24V_AUX_2_R",
+ "PWRGD_P24V_AUX_R", "PWRGD_P12V_AUX_R2",
+ "PWRGD_P12V_SCM_R", "P24V_AUX_INA230_ALERT_N_R",
+ "", "PRSNT_CAN1_MCIO_N",
+ "PRSNT_CAN2_MCIO_N", "PRSNT_AALC_MCIO_N",
+ "PRSNT_RACKMON_MCIO_N", "PRSNT_RIO_RACKMON_N";
+ };
+
+ temp-sensor@4f {
+ compatible = "ti,tmp75";
+ reg = <0x4f>;
+ };
+
+ eeprom@54 {
+ compatible = "atmel,24c128";
+ reg = <0x54>;
+ };
+
+ i2c-mux@77 {
+ compatible = "nxp,pca9548";
+ reg = <0x77>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ i2c-mux-idle-disconnect;
+
+ i2c5mux0ch0: i2c@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>;
+ };
+
+ i2c5mux0ch1: i2c@1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <1>;
+ };
+
+ i2c5mux0ch2: i2c@2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <2>;
+
+ eeprom@56 {
+ compatible = "atmel,24c128";
+ reg = <0x56>;
+ };
+ };
+
+ i2c5mux0ch3: i2c@3 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <3>;
+
+ eeprom@56 {
+ compatible = "atmel,24c128";
+ reg = <0x56>;
+ };
+ };
+
+ i2c5mux0ch4: i2c@4 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <4>;
+
+ eeprom@56 {
+ compatible = "atmel,24c128";
+ reg = <0x56>;
+ };
+ };
+
+ i2c5mux0ch5: i2c@5 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <5>;
+
+ eeprom@56 {
+ compatible = "atmel,24c128";
+ reg = <0x56>;
+ };
+ };
+
+ i2c5mux0ch6: i2c@6 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <6>;
+
+ eeprom@56 {
+ compatible = "atmel,24c128";
+ reg = <0x56>;
+ };
+ };
+
+ i2c5mux0ch7: i2c@7 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <7>;
+
+ eeprom@56 {
+ compatible = "atmel,24c128";
+ reg = <0x56>;
+ };
+ };
+ };
+};
+
+&i2c6 {
+ status = "okay";
+
+ dac@0c {
+ reg = <0x0c>;
+ compatible = "adi,ad5612";
+ vcc-supply = <&p5v_dac_aux>;
+ };
+
+ dac@0e {
+ reg = <0x0e>;
+ compatible = "adi,ad5612";
+ vcc-supply = <&p5v_dac_aux>;
+ };
+
+ dac@0f {
+ reg = <0x0f>;
+ compatible = "adi,ad5612";
+ vcc-supply = <&p5v_dac_aux>;
+ };
+
+ io_expander0: gpio@20 {
+ compatible = "nxp,pca9555";
+ reg = <0x20>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-parent = <&io_expander7>;
+ interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+
+ gpio-line-names =
+ "", "",
+ "", "",
+ "", "PRSNT_FANBP_0_PWR_N",
+ "PRSNT_FANBP_0_SIG_N", "PRSNT_POE_PWR_N",
+ "PRSNT_POE_SIG_N", "",
+ "PWRGD_P3V3_ISO_POE_BMC_R", "",
+ "", "",
+ "DEV_DIS_N", "PCI_DIS_N";
+ };
+
+ io_expander1: gpio@21 {
+ compatible = "nxp,pca9555";
+ reg = <0x21>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-parent = <&io_expander7>;
+ interrupts = <1 IRQ_TYPE_LEVEL_LOW>;
+
+ gpio-line-names =
+ "PWRGD_CPU_LVC3_BMC", "R_FM_BIOS_POST_CMPLT_BMC",
+ "", "",
+ "", "",
+ "", "",
+ "", "",
+ "", "PCIE_SSD1_PRSNT_N",
+ "", "TRAY23_PWRGD_BUF_R",
+ "TRAY24_PWRGD_BUF_R", "TRAY29_PWRGD_BUF_R";
+ };
+
+ io_expander2: gpio@22 {
+ compatible = "nxp,pca9555";
+ reg = <0x22>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-parent = <&io_expander7>;
+ interrupts = <2 IRQ_TYPE_LEVEL_LOW>;
+
+ gpio-line-names =
+ "BOARD_ID_0", "BOARD_ID_1",
+ "BOARD_ID_2", "BOARD_ID_3",
+ "SKU_ID_3", "SKU_ID_2",
+ "SKU_ID_1", "SKU_ID_0",
+ "", "",
+ "", "",
+ "", "",
+ "", "";
+ };
+
+ io_expander7: gpio@23 {
+ compatible = "nxp,pca9555";
+ reg = <0x23>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ interrupt-parent = <&sgpiom0>;
+ interrupts = <32 IRQ_TYPE_LEVEL_LOW>;
+
+ gpio-line-names =
+ "IOEXP1_INT_N", "IOEXP2_INT_N",
+ "IOEXP3_INT_N", "IOEXP4_INT_N",
+ "IOEXP5_INT_N", "IOEXP6_INT_N",
+ "IOEXP7_INT_N", "",
+ "", "",
+ "", "",
+ "", "",
+ "", "";
+ };
+
+ io_expander8: gpio@24 {
+ compatible = "nxp,pca9555";
+ reg = <0x24>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-parent = <&io_expander7>;
+ interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+
+ gpio-line-names =
+ "PRSNT_MGMT_J54_N", "PRSNT_RACKMON_J47_N",
+ "PRSNT_MGMT_DEBUG_J53_N", "PRSNT_MINISAS_TOP_J49_N",
+ "PRSNT_MINISAS_TOP_J50_N", "PRSNT_MINISAS_BOT_J51_N",
+ "PRSNT_MINISAS_BOT_J52_N", "JTAG_PLD_JTAGEN",
+ "PU_PLD_CONFIG_N", "",
+ "", "",
+ "", "",
+ "", "";
+};
+
+ // Marvell 88E6393X EEPROM
+ eeprom@50 {
+ compatible = "atmel,24c64";
+ reg = <0x50>;
+ };
+
+ rtc@51 {
+ compatible = "nxp,pcf8563";
+ reg = <0x51>;
+ };
+};
+
+&i2c7 {
+ status = "okay";
+ bus-frequency = <100000>;
+ multi-master;
+ aspeed,hw-timeout-ms = <1000>;
+
+ ipmb@10 {
+ compatible = "ipmb-dev";
+ reg = <(0x10 | I2C_OWN_SLAVE_ADDRESS)>;
+ i2c-protocol;
+ };
+};
+
+&i2c8 {
+ status = "okay";
+
+ i2c-mux@77 {
+ compatible = "nxp,pca9548";
+ reg = <0x77>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ i2c-mux-idle-disconnect;
+
+ i2c8mux0ch0: i2c@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>;
+ status = "okay";
+ };
+
+ i2c8mux0ch1: i2c@1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <1>;
+ status = "okay";
+ };
+
+ i2c8mux0ch2: i2c@2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <2>;
+ status = "okay";
+ };
+
+ i2c8mux0ch3: i2c@3 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <3>;
+ status = "okay";
+ };
+
+ i2c8mux0ch4: i2c@4 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <4>;
+ status = "okay";
+ };
+
+ i2c8mux0ch5: i2c@5 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <5>;
+ status = "okay";
+ };
+
+ i2c8mux0ch6: i2c@6 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <6>;
+ status = "okay";
+ };
+
+ i2c8mux0ch7: i2c@7 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <7>;
+ status = "okay";
+ };
+ };
+};
+
+&i2c9 {
+ status = "okay";
+
+ temperature-sensor@4b {
+ compatible = "ti,tmp75";
+ reg = <0x4b>;
+ };
+
+ eeprom@50 {
+ compatible = "atmel,24c128";
+ reg = <0x50>;
+ };
+
+ eeprom@51 {
+ compatible = "atmel,24c128";
+ reg = <0x51>;
+ };
+
+ eeprom@56 {
+ compatible = "atmel,24c64";
+ reg = <0x56>;
+ };
+};
+
+&i2c10 {
+ status = "okay";
+
+ legacy_prsnt_io_expander0: gpio@11 {
+ compatible = "nxp,pca9555";
+ reg = <0x11>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-parent = <&sgpiom0>;
+ interrupts = <40 IRQ_TYPE_LEVEL_LOW>;
+
+ gpio-line-names =
+ "TRAY_PRSNT1_N_BUF_R", "TRAY_PRSNT2_N_BUF_R",
+ "TRAY_PRSNT3_N_BUF_R", "TRAY_PRSNT4_N_BUF_R",
+ "TRAY_PRSNT5_N_BUF_R", "TRAY_PRSNT6_N_BUF_R",
+ "TRAY_PRSNT7_N_BUF_R", "TRAY_PRSNT8_N_BUF_R",
+ "TRAY_PRSNT9_N_BUF_R", "TRAY_PRSNT10_N_BUF_R",
+ "TRAY_PRSNT11_N_BUF_R", "TRAY_PRSNT12_N_BUF_R",
+ "TRAY_PRSNT13_N_BUF_R", "TRAY_PRSNT14_N_BUF_R",
+ "TRAY_PRSNT15_N_BUF_R", "TRAY_PRSNT16_N_BUF_R";
+ };
+
+ legacy_prsnt_io_expander1: gpio@12 {
+ compatible = "nxp,pca9555";
+ reg = <0x12>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-parent = <&sgpiom0>;
+ interrupts = <40 IRQ_TYPE_LEVEL_LOW>;
+
+ gpio-line-names =
+ "TRAY_PRSNT17_N_BUF_R", "TRAY_PRSNT18_N_BUF_R",
+ "TRAY_PRSNT19_N_BUF_R", "TRAY_PRSNT20_N_BUF_R",
+ "TRAY_PRSNT21_N_BUF_R", "TRAY_PRSNT22_N_BUF_R",
+ "TRAY_PRSNT23_N_BUF_R", "TRAY_PRSNT24_N_BUF_R",
+ "TRAY_PRSNT25_N_BUF_R", "TRAY_PRSNT26_N_BUF_R",
+ "TRAY_PRSNT27_N_BUF_R", "TRAY_PRSNT28_N_BUF_R",
+ "TRAY_PRSNT29_N_BUF_R", "TRAY_PRSNT30_N_BUF_R",
+ "TRAY_PRSNT31_N_BUF_R", "TRAY_PRSNT32_N_BUF_R";
+ };
+
+ legacy_prsnt_io_expander2: gpio@13 {
+ compatible = "nxp,pca9555";
+ reg = <0x13>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-parent = <&sgpiom0>;
+ interrupts = <40 IRQ_TYPE_LEVEL_LOW>;
+
+ gpio-line-names =
+ "TRAY_PRSNT33_N_BUF_R", "TRAY_PRSNT34_N_BUF_R",
+ "TRAY_PRSNT35_N_BUF_R", "TRAY_PRSNT36_N_BUF_R",
+ "TRAY_PRSNT37_N_BUF_R", "TRAY_PRSNT38_N_BUF_R",
+ "TRAY_PRSNT39_N_BUF_R", "TRAY_PRSNT40_N_BUF_R",
+ "", "",
+ "", "",
+ "", "",
+ "", "";
+ };
+
+ power-monitor@14 {
+ compatible = "infineon,xdp710";
+ reg = <0x14>;
+ };
+
+ legacy_pwrgd_io_expander1: gpio@15 {
+ compatible = "nxp,pca9555";
+ reg = <0x15>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-parent = <&sgpiom0>;
+ interrupts = <42 IRQ_TYPE_LEVEL_LOW>;
+
+ gpio-line-names =
+ "TRAY_PWRGD17_N_BUF_R", "TRAY_PWRGD18_N_BUF_R",
+ "TRAY_PWRGD19_N_BUF_R", "TRAY_PWRGD20_N_BUF_R",
+ "TRAY_PWRGD21_N_BUF_R", "TRAY_PWRGD22_N_BUF_R",
+ "TRAY_PWRGD23_N_BUF_R", "TRAY_PWRGD24_N_BUF_R",
+ "TRAY_PWRGD25_N_BUF_R", "TRAY_PWRGD26_N_BUF_R",
+ "TRAY_PWRGD27_N_BUF_R", "TRAY_PWRGD28_N_BUF_R",
+ "TRAY_PWRGD29_N_BUF_R", "TRAY_PWRGD30_N_BUF_R",
+ "TRAY_PWRGD31_N_BUF_R", "TRAY_PWRGD32_N_BUF_R";
+ };
+
+ legacy_pwrgd_io_expander2: gpio@16 {
+ compatible = "nxp,pca9555";
+ reg = <0x16>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-parent = <&sgpiom0>;
+ interrupts = <42 IRQ_TYPE_LEVEL_LOW>;
+
+ gpio-line-names =
+ "TRAY_PWRGD33_N_BUF_R", "TRAY_PWRGD34_N_BUF_R",
+ "TRAY_PWRGD35_N_BUF_R", "TRAY_PWRGD36_N_BUF_R",
+ "TRAY_PWRGD37_N_BUF_R", "TRAY_PWRGD38_N_BUF_R",
+ "TRAY_PWRGD39_N_BUF_R", "TRAY_PWRGD40_N_BUF_R",
+ "", "",
+ "", "",
+ "", "",
+ "", "";
+ };
+
+ legacy_leak_io_expander0: gpio@17 {
+ compatible = "nxp,pca9555";
+ reg = <0x17>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-parent = <&sgpiom0>;
+ interrupts = <46 IRQ_TYPE_LEVEL_LOW>;
+
+ gpio-line-names =
+ "TRAY_LEAK_DETECT1_N_BUF_R", "TRAY_LEAK_DETECT2_N_BUF_R",
+ "TRAY_LEAK_DETECT3_N_BUF_R", "TRAY_LEAK_DETECT4_N_BUF_R",
+ "TRAY_LEAK_DETECT5_N_BUF_R", "TRAY_LEAK_DETECT6_N_BUF_R",
+ "TRAY_LEAK_DETECT7_N_BUF_R", "TRAY_LEAK_DETECT8_N_BUF_R",
+ "TRAY_LEAK_DETECT9_N_BUF_R", "TRAY_LEAK_DETECT10_N_BUF_R",
+ "TRAY_LEAK_DETECT11_N_BUF_R", "TRAY_LEAK_DETECT12_N_BUF_R",
+ "TRAY_LEAK_DETECT13_N_BUF_R", "TRAY_LEAK_DETECT14_N_BUF_R",
+ "TRAY_LEAK_DETECT15_N_BUF_R", "TRAY_LEAK_DETECT16_N_BUF_R";
+ };
+
+ legacy_leak_io_expander1: gpio@18 {
+ compatible = "nxp,pca9555";
+ reg = <0x18>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-parent = <&sgpiom0>;
+ interrupts = <46 IRQ_TYPE_LEVEL_LOW>;
+
+ gpio-line-names =
+ "TRAY_LEAK_DETECT17_N_BUF_R", "TRAY_LEAK_DETECT18_N_BUF_R",
+ "TRAY_LEAK_DETECT19_N_BUF_R", "TRAY_LEAK_DETECT20_N_BUF_R",
+ "TRAY_LEAK_DETECT21_N_BUF_R", "TRAY_LEAK_DETECT22_N_BUF_R",
+ "TRAY_LEAK_DETECT23_N_BUF_R", "TRAY_LEAK_DETECT24_N_BUF_R",
+ "TRAY_LEAK_DETECT25_N_BUF_R", "TRAY_LEAK_DETECT26_N_BUF_R",
+ "TRAY_LEAK_DETECT27_N_BUF_R", "TRAY_LEAK_DETECT28_N_BUF_R",
+ "TRAY_LEAK_DETECT29_N_BUF_R", "TRAY_LEAK_DETECT30_N_BUF_R",
+ "TRAY_LEAK_DETECT31_N_BUF_R", "TRAY_LEAK_DETECT32_N_BUF_R";
+ };
+
+ legacy_leak_io_expander2: gpio@19 {
+ compatible = "nxp,pca9555";
+ reg = <0x19>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-parent = <&sgpiom0>;
+ interrupts = <46 IRQ_TYPE_LEVEL_LOW>;
+
+ gpio-line-names =
+ "TRAY_LEAK_DETECT33_N_BUF_R", "TRAY_LEAK_DETECT34_N_BUF_R",
+ "TRAY_LEAK_DETECT35_N_BUF_R", "TRAY_LEAK_DETECT36_N_BUF_R",
+ "TRAY_LEAK_DETECT37_N_BUF_R", "TRAY_LEAK_DETECT38_N_BUF_R",
+ "TRAY_LEAK_DETECT39_N_BUF_R", "TRAY_LEAK_DETECT40_N_BUF_R",
+ "", "",
+ "", "",
+ "", "",
+ "", "";
+ };
+
+ legacy_small_leak_io_expander0: gpio@1a {
+ compatible = "nxp,pca9555";
+ reg = <0x1a>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-parent = <&sgpiom0>;
+ interrupts = <44 IRQ_TYPE_LEVEL_LOW>;
+
+ gpio-line-names =
+ "TRAY_SMALL_LEAK1_N_BUF_R", "TRAY_SMALL_LEAK2_N_BUF_R",
+ "TRAY_SMALL_LEAK3_N_BUF_R", "TRAY_SMALL_LEAK4_N_BUF_R",
+ "TRAY_SMALL_LEAK5_N_BUF_R", "TRAY_SMALL_LEAK6_N_BUF_R",
+ "TRAY_SMALL_LEAK7_N_BUF_R", "TRAY_SMALL_LEAK8_N_BUF_R",
+ "TRAY_SMALL_LEAK9_N_BUF_R", "TRAY_SMALL_LEAK10_N_BUF_R",
+ "TRAY_SMALL_LEAK11_N_BUF_R", "TRAY_SMALL_LEAK12_N_BUF_R",
+ "TRAY_SMALL_LEAK13_N_BUF_R", "TRAY_SMALL_LEAK14_N_BUF_R",
+ "TRAY_SMALL_LEAK15_N_BUF_R", "TRAY_SMALL_LEAK16_N_BUF_R";
+ };
+
+ legacy_small_leak_io_expander1: gpio@1b {
+ compatible = "nxp,pca9555";
+ reg = <0x1b>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-parent = <&sgpiom0>;
+ interrupts = <44 IRQ_TYPE_LEVEL_LOW>;
+
+ gpio-line-names =
+ "TRAY_SMALL_LEAK17_N_BUF_R", "TRAY_SMALL_LEAK18_N_BUF_R",
+ "TRAY_SMALL_LEAK19_N_BUF_R", "TRAY_SMALL_LEAK20_N_BUF_R",
+ "TRAY_SMALL_LEAK21_N_BUF_R", "TRAY_SMALL_LEAK22_N_BUF_R",
+ "TRAY_SMALL_LEAK23_N_BUF_R", "TRAY_SMALL_LEAK24_N_BUF_R",
+ "TRAY_SMALL_LEAK25_N_BUF_R", "TRAY_SMALL_LEAK26_N_BUF_R",
+ "TRAY_SMALL_LEAK27_N_BUF_R", "TRAY_SMALL_LEAK28_N_BUF_R",
+ "TRAY_SMALL_LEAK29_N_BUF_R", "TRAY_SMALL_LEAK30_N_BUF_R",
+ "TRAY_SMALL_LEAK31_N_BUF_R", "TRAY_SMALL_LEAK32_N_BUF_R";
+ };
+
+ legacy_small_leak_io_expander2: gpio@1c {
+ compatible = "nxp,pca9555";
+ reg = <0x1c>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-parent = <&sgpiom0>;
+ interrupts = <44 IRQ_TYPE_LEVEL_LOW>;
+
+ gpio-line-names =
+ "TRAY_SMALL_LEAK33_N_BUF_R", "TRAY_SMALL_LEAK34_N_BUF_R",
+ "TRAY_SMALL_LEAK35_N_BUF_R", "TRAY_SMALL_LEAK36_N_BUF_R",
+ "TRAY_SMALL_LEAK37_N_BUF_R", "TRAY_SMALL_LEAK38_N_BUF_R",
+ "TRAY_SMALL_LEAK39_N_BUF_R", "TRAY_SMALL_LEAK40_N_BUF_R",
+ "", "",
+ "", "",
+ "", "",
+ "", "";
+ };
+
+ legacy_pwrgd_io_expander0: gpio@28 {
+ compatible = "nxp,pca9555";
+ reg = <0x28>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-parent = <&sgpiom0>;
+ interrupts = <42 IRQ_TYPE_LEVEL_LOW>;
+
+ gpio-line-names =
+ "TRAY_PWRGD1_N_BUF_R", "TRAY_PWRGD2_N_BUF_R",
+ "TRAY_PWRGD3_N_BUF_R", "TRAY_PWRGD4_N_BUF_R",
+ "TRAY_PWRGD5_N_BUF_R", "TRAY_PWRGD6_N_BUF_R",
+ "TRAY_PWRGD7_N_BUF_R", "TRAY_PWRGD8_N_BUF_R",
+ "TRAY_PWRGD9_N_BUF_R", "TRAY_PWRGD10_N_BUF_R",
+ "TRAY_PWRGD11_N_BUF_R", "TRAY_PWRGD12_N_BUF_R",
+ "TRAY_PWRGD13_N_BUF_R", "TRAY_PWRGD14_N_BUF_R",
+ "TRAY_PWRGD15_N_BUF_R", "TRAY_PWRGD16_N_BUF_R";
+ };
+
+ adc@35 {
+ compatible = "maxim,max11617";
+ reg = <0x35>;
+ };
+
+ power-monitor@40 {
+ compatible = "ti,ina230";
+ reg = <0x40>;
+ shunt-resistor = <1000>;
+ };
+
+ power-sensor@41 {
+ compatible = "ti,ina238";
+ reg = <0x41>;
+ shunt-resistor = <20000>;
+ };
+
+ power-sensor@43 {
+ compatible = "ti,ina238";
+ reg = <0x43>;
+ shunt-resistor = <20000>;
+ };
+
+ power-monitor@44 {
+ compatible = "lltc,ltc4287";
+ reg = <0x44>;
+ shunt-resistor-micro-ohms = <500>;
+ };
+
+ power-monitor@45 {
+ compatible = "ti,ina230";
+ reg = <0x45>;
+ shunt-resistor = <1000>;
+ };
+
+ adc@48 {
+ compatible = "ti,ads1015";
+ reg = <0x48>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ temp-sensor@4c {
+ compatible = "ti,tmp75";
+ reg = <0x4c>;
+ };
+
+ temp-sensor@4d {
+ compatible = "ti,tmp75";
+ reg = <0x4d>;
+ };
+
+ temp-sensor@4e {
+ compatible = "ti,tmp75";
+ reg = <0x4e>;
+ };
+
+ power-monitor@4f {
+ compatible = "ti,ina230";
+ reg = <0x4f>;
+ shunt-resistor = <1000>;
+ };
+
+ power-monitor@69 {
+ compatible = "pmbus";
+ reg = <0x69>;
+ };
+
+ fpga_io_expander64: gpio@64 {
+ compatible = "nxp,pca9555";
+ reg = <0x64>;
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ gpio-line-names =
+ "", "",
+ "", "",
+ "", "",
+ "LEAK_CONFIG0", "LEAK_CONFIG1",
+ "FPGA_PWRGD_P24V_AUX_R", "FPGA_PWRGD_P24V_AUX_2_R",
+ "FPGA_PWRGD_P12V_SCM_R", "FPGA_PWRGD_P12V_AUX_R2",
+ "FPGA_PRSNT_FANBP_0_SIG_R_PLD_N", "FPGA_PRSNT_FANBP_0_PWR_R_PLD_N",
+ "FPGA_P24V_AUX_INA230_ALERT_N_R", "FPGA_SMB_TMC75_TEMP_ALERT_N_R";
+ };
+
+ fpga_io_expander65: gpio@65 {
+ compatible = "nxp,pca9555";
+ reg = <0x65>;
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ gpio-line-names =
+ "FPGA_PCI_DIS_N", "FPGA_DEV_DIS_N",
+ "FPGA_PWRGD_P3V3_AUX_R", "FPGA_PWRGD_P5V_AUX_R2",
+ "FPGA_PWRGD_P1V05_AUX_R", "FPGA_P48V_HSC_ALERT_N",
+ "FPGA_PWRGD_P1V5_AUX_R", "FPGA_PWRGD_P52V_HSC_PWROK_R",
+ "FPGA_R_COME_THERMTRIP_L", "FPGA_PRSNT_POE_SIG_PLD_N",
+ "FPGA_PRSNT_POE_PWR_PLD_N", "FPGA_PRSNT_RIO_RACKMON_N",
+ "FPGA_PRSNT_CAN2_MCIO_N", "FPGA_PRSNT_CAN1_MCIO_N",
+ "FPGA_PRSNT_RACKMON_MCIO_N", "FPGA_PRSNT_AALC_MCIO_N";
+ };
+
+ fpga_io_expander66: gpio@66 {
+ compatible = "nxp,pca9555";
+ reg = <0x66>;
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ gpio-line-names =
+ "FPGA_R_FM_CPU_ERR0_LVT3_L", "FPGA_FPGA_R_FM_PCHHOT_L",
+ "FPGA_R_FM_BIOS_POST_CMPLT_L", "FPGA_R_FM_SOC_BMC_RST_L",
+ "FPGA_R_CPU_MSMI_CATERR_N", "FPGA_R_H_MEMHOT_OUT_FET_L",
+ "FPGA_R_PWRGD_P3V3_STBY", "FPGA_R_PWRGD_PCH_PWROK",
+ "FPGA_TRAY23_PWRGD_BUF_R", "FPGA_TRAY24_PWRGD_BUF_R",
+ "FPGA_P24V_AUX_2_INA230_ALERT_N_R", "FPGA_R_IRQ_BMC_PCH_SMI_N",
+ "FPGA_R_FM_CPU_DIMM_EVENT_COD_BUF", "FPGA_R_BIOS_MSG_DIS_L",
+ "FPGA_R_ISO_FM_USB_OC0_L", "FPGA_SPI_LVC_EN";
+ };
+
+ fpga_io_expander67: gpio@67 {
+ compatible = "nxp,pca9555";
+ reg = <0x67>;
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ gpio-line-names =
+ "FPGA_TRAY29_PWRGD_BUF_R", "FPGA_TRAY30_PWRGD_BUF_R",
+ "FPGA_TRAY31_PWRGD_BUF_R", "FPGA_TRAY32_PWRGD_BUF_R",
+ "FPGA_TRAY37_PWRGD_BUF_R", "FPGA_TRAY38_PWRGD_BUF_R",
+ "FPGA_TRAY39_PWRGD_BUF_R", "FPGA_TRAY40_PWRGD_BUF_R",
+ "FPGA_ISO_CARRIER_BOARD_PWR_OK", "FPGA_UART_MUX_SEL",
+ "", "",
+ "", "",
+ "", "";
+ };
+};
+
+&i2c11 {
+ status = "okay";
+
+ i2c-mux@77 {
+ compatible = "nxp,pca9548";
+ reg = <0x77>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ i2c-mux-idle-disconnect;
+
+ i2c11mux0ch0: i2c@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>;
+ status = "okay";
+ };
+
+ i2c11mux0ch1: i2c@1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <1>;
+ status = "okay";
+ };
+
+ i2c11mux0ch2: i2c@2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <2>;
+ status = "okay";
+ };
+
+ i2c11mux0ch3: i2c@3 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <3>;
+ status = "okay";
+ };
+
+ i2c11mux0ch4: i2c@4 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <4>;
+ status = "okay";
+ };
+
+ i2c11mux0ch5: i2c@5 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <5>;
+ status = "okay";
+ };
+
+ i2c11mux0ch6: i2c@6 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <6>;
+ status = "okay";
+ };
+
+ i2c11mux0ch7: i2c@7 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <7>;
+ status = "okay";
+ };
+ };
+};
+
+&i2c12 {
+ status = "okay";
+ bus-frequency = <400000>;
+};
+
+&i2c13 {
+ status = "okay";
+
+ i2c-mux@77 {
+ compatible = "nxp,pca9548";
+ reg = <0x77>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ i2c-mux-idle-disconnect;
+
+ i2c13mux0ch0: i2c@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>;
+ status = "okay";
+ };
+
+ i2c13mux0ch1: i2c@1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <1>;
+ status = "okay";
+ };
+
+ i2c13mux0ch2: i2c@2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <2>;
+ status = "okay";
+ };
+
+ i2c13mux0ch3: i2c@3 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <3>;
+ status = "okay";
+ };
+
+ i2c13mux0ch4: i2c@4 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <4>;
+ status = "okay";
+ };
+
+ i2c13mux0ch5: i2c@5 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <5>;
+ status = "okay";
+ };
+
+ i2c13mux0ch6: i2c@6 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <6>;
+ status = "okay";
+ };
+
+ i2c13mux0ch7: i2c@7 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <7>;
+ status = "okay";
+ };
+ };
+};
+
+&i2c14 {
+ status = "okay";
+};
+
+&i2c15 {
+ status = "okay";
+
+ i2c-mux@77 {
+ compatible = "nxp,pca9548";
+ reg = <0x77>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ i2c-mux-idle-disconnect;
+
+ i2c15mux0ch0: i2c@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>;
+ status = "okay";
+ };
+
+ i2c15mux0ch1: i2c@1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <1>;
+ status = "okay";
+ };
+
+ i2c15mux0ch2: i2c@2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <2>;
+ status = "okay";
+ };
+
+ i2c15mux0ch3: i2c@3 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <3>;
+ status = "okay";
+ };
+
+ i2c15mux0ch4: i2c@4 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <4>;
+ status = "okay";
+ };
+
+ i2c15mux0ch5: i2c@5 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <5>;
+ status = "okay";
+ };
+
+ i2c15mux0ch6: i2c@6 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <6>;
+ status = "okay";
+ };
+
+ i2c15mux0ch7: i2c@7 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <7>;
+ status = "okay";
+ };
+ };
+};
+
+&lpc_ctrl {
+ status = "okay";
+};
+
+&kcs3 {
+ aspeed,lpc-io-reg = <0xca2>;
+ status = "okay";
+};
+
+&mac2 {
+ status = "okay";
+ phy-mode = "rmii";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_rmii3_default>;
+
+ /*
+ * The Marvell 88E6393X is initialized at boot via EEPROM
+ * configuration and hardware straps.
+ * The BMC connects via an RMII fixed-link; link parameters are fixed
+ * by board design.
+ */
+ fixed-link {
+ speed = <100>;
+ full-duplex;
+ };
+};
+
+&mac3 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_rmii4_default>;
+ use-ncsi;
+};
+
+&mdio0 {
+ status = "okay";
+};
+
+&peci0 {
+ status = "okay";
+};
+
+&sgpiom0 {
+ status = "okay";
+ ngpios = <128>;
+ bus-frequency = <200000>;
+ gpio-line-names =
+ /*"input pin","output pin"*/
+ /*A0 - A7*/
+ "power-chassis-good","FM_PLD_HEARTBEAT_LVC3_R",
+ "host0-ready","R_BMC_PTH_RST_BTN_L",
+ "CONTROL_VT2_SUPPLY1_CLOSE","FM_MDIO_SW_SEL_PLD",
+ "CONTROL_VT2_SUPPLY2_CLOSE","FM_88E6393X_BIN_UPDATE_EN_N",
+ "CONTROL_VT2_SUPPLY3_CLOSE","Sequence_TransFR_Alert",
+ "RETURN_CNTL1_FB","WATER_VALVE1_OPEN",
+ "RETURN_CNTL2_FB","WATER_VALVE2_OPEN",
+ "RETURN_CNTL3_FB","WATER_VALVE3_OPEN",
+ /*B0 - B7*/
+ "IT_STOP_PUMP_R_CPLD","WATER_VALVE1_CLOSE",
+ "IT_STOP_PUMP_SPARE_R_CPLD","WATER_VALVE2_CLOSE",
+ "IT_STOP_PUMP_2_R_CPLD","WATER_VALVE3_CLOSE",
+ "IT_STOP_PUMP_SPARE_2_R_CPLD","REPORT_VT2_SUPPLY1_CLOSE",
+ "RPU_2_READY_SPARE_PLD_R","REPORT_VT2_SUPPLY2_CLOSE",
+ "RPU_2_READY_PLD_R","REPORT_VT2_SUPPLY3_CLOSE",
+ "RPU_READY_SPARE_PLD_R","PCIE_SSD1_PRSNT_N",
+ "RPU_READY_PLD_R","",
+ /*C0 - C7*/
+ "IOEXP8_INT_N","",
+ "SUPPLY_CNTL1_FB","",
+ "SUPPLY_CNTL2_FB","",
+ "SUPPLY_CNTL3_FB","",
+ "PRSNT_TRAY1_TO_40_R_BUF_N","",
+ "PWRGD_TRAY1_TO_40_R_BUF","",
+ "SMALL_LEAK_TRAY1_TO_40_R_BUF_N","",
+ "LEAK_DETECT_TRAY1_TO_40_R_BUF_N","",
+ /*D0 - D7*/
+ "PRSNT_CANBUSP1_TRAY1_TO_32_N","",
+ "PWRGD_CANBUSP1_TRAY1_TO_32_PWROK","",
+ "SMALL_LEAK_CANBUSP1_TRAY1_TO_32_N","",
+ "LEAK_DETECT_CANBUSP1_TRAY1_TO_32_N","",
+ "PRSNT_CANBUSP2_TRAY1_TO_32_N","",
+ "PWRGD_CANBUSP2_TRAY1_TO_32_PWROK","",
+ "SMALL_LEAK_CANBUSP2_TRAY1_TO_32_N","",
+ "LEAK_DETECT_CANBUSP2_TRAY1_TO_32_N","",
+ /*E0 - E7*/
+ "PRSNT_CANBUSP3_TRAY1_TO_32_N","",
+ "PWRGD_CANBUSP3_TRAY1_TO_32_PWROK","",
+ "SMALL_LEAK_CANBUSP3_TRAY1_TO_32_N","",
+ "LEAK_DETECT_CANBUSP3_TRAY1_TO_32_N","",
+ "PRSNT_CANBUSP4_TRAY1_TO_32_N","",
+ "PWRGD_CANBUSP4_TRAY1_TO_32_PWROK","",
+ "SMALL_LEAK_CANBUSP4_TRAY1_TO_32_N","",
+ "LEAK_DETECT_CANBUSP4_TRAY1_TO_32_N","",
+ /*F0 - F7*/
+ "PRSNT_CANBUSP5_TRAY1_TO_32_N","",
+ "PWRGD_CANBUSP5_TRAY1_TO_32_PWROK","",
+ "SMALL_LEAK_CANBUSP5_TRAY1_TO_32_N","",
+ "LEAK_DETECT_CANBUSP5_TRAY1_TO_32_N","",
+ "PRSNT_CANBUSP6_TRAY1_TO_32_N","",
+ "PWRGD_CANBUSP6_TRAY1_TO_32_PWROK","",
+ "SMALL_LEAK_CANBUSP6_TRAY1_TO_32_N","",
+ "LEAK_DETECT_CANBUSP6_TRAY1_TO_32_N","",
+ /*G0 - G7*/
+ "PRSNT_CANBUSP7_TRAY1_TO_32_N","",
+ "PWRGD_CANBUSP7_TRAY1_TO_32_PWROK","",
+ "SMALL_LEAK_CANBUSP7_TRAY1_TO_32_N","",
+ "LEAK_DETECT_CANBUSP7_TRAY1_TO_32_N","",
+ "PRSNT_CANBUSP8_TRAY1_TO_32_N","",
+ "PWRGD_CANBUSP8_TRAY1_TO_32_PWROK","",
+ "SMALL_LEAK_CANBUSP8_TRAY1_TO_32_N","",
+ "LEAK_DETECT_CANBUSP8_TRAY1_TO_32_N","",
+ /*H0 - H7*/
+ "CHASSIS0_LEAK_Q_N_R","",
+ "CHASSIS1_LEAK_Q_N_R","",
+ "CHASSIS2_LEAK_Q_N_R","",
+ "CHASSIS3_LEAK_Q_N_R","",
+ "CHASSIS4_LEAK_Q_N_R","",
+ "CHASSIS5_LEAK_Q_N_R","",
+ "CHASSIS6_LEAK_Q_N_R","",
+ "CHASSIS7_LEAK_Q_N_R","",
+ /*I0 - I7*/
+ "CHASSIS8_LEAK_Q_N_R","",
+ "CHASSIS9_LEAK_Q_N_R","",
+ "CHASSIS10_LEAK_Q_N_R","",
+ "CHASSIS11_LEAK_Q_N_R","",
+ "AALC_RPU_READY","",
+ "","",
+ "","",
+ "","",
+ /*J0 - J7*/
+ "","",
+ "","",
+ "","",
+ "","",
+ "","",
+ "","",
+ "","",
+ "","",
+ /*K0 - K7*/
+ "","",
+ "","",
+ "","",
+ "","",
+ "","",
+ "","",
+ "","",
+ "","",
+ /*L0 - L7*/
+ "IT_GEAR_RPU_2_LINK_PRSNT_SPARE_N_R","",
+ "IT_GEAR_RPU_2_LINK_PRSNT_N_R","",
+ "IT_GEAR_RPU_LINK_PRSNT_SPARE_N_R","",
+ "IT_GEAR_RPU_LINK_PRSNT_N_R","",
+ "","",
+ "","",
+ "","",
+ "","",
+ /*M0 - M7*/
+ "","",
+ "","",
+ "PRSNT_SENSOR_N","",
+ "PRSNT3_VT2_PLD_N","",
+ "PRSNT2_VT2_PLD_N","",
+ "PRSNT1_VT2_PLD_N","",
+ "PRSNT3_RETURN_PLD_N","",
+ "PRSNT2_RETURN_PLD_N","",
+ /*N0 - N7*/
+ "PRSNT1_RETURN_PLD_N","",
+ "PRSNT3_SUPPLY_PLD_N","",
+ "PRSNT2_SUPPLY_PLD_N","",
+ "PRSNT1_SUPPLY_PLD_N","",
+ "PRSNT_LEAK11_SENSOR_R_PLD_N","",
+ "PRSNT_LEAK10_SENSOR_R_PLD_N","",
+ "PRSNT_LEAK9_SENSOR_R_PLD_N","",
+ "PRSNT_LEAK8_SENSOR_R_PLD_N","",
+ /*O0 - O7*/
+ "PRSNT_LEAK7_SENSOR_R_PLD_N","",
+ "PRSNT_LEAK6_SENSOR_R_PLD_N","",
+ "PRSNT_LEAK5_SENSOR_R_PLD_N","",
+ "PRSNT_LEAK4_SENSOR_R_PLD_N","",
+ "PRSNT_LEAK3_SENSOR_R_PLD_N","",
+ "PRSNT_LEAK2_SENSOR_R_PLD_N","",
+ "PRSNT_LEAK1_SENSOR_R_PLD_N","",
+ "PRSNT_LEAK0_SENSOR_R_PLD_N","",
+ /*P0 - P7*/
+ "","",
+ "","",
+ "","",
+ "","",
+ "","SGPIO_REG_VALID_0",
+ "","SGPIO_REG_VALID_1",
+ "","SGPIO_REG_VALID_2",
+ "","SGPIO_REG_VALID_3";
+};
+
+&spi2 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_spi2_default>;
+
+ flash@0 {
+ status = "okay";
+ m25p,fast-read;
+ label = "pnor";
+ spi-max-frequency = <12000000>;
+ spi-tx-bus-width = <2>;
+ spi-rx-bus-width = <2>;
+ };
+};
+
+&uart3 {
+ status = "okay";
+};
+
+&wdt1 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_wdtrst1_default>;
+ aspeed,reset-type = "soc";
+ aspeed,external-signal;
+ aspeed,ext-push-pull;
+ aspeed,ext-active-high;
+ aspeed,ext-pulse-duration = <256>;
+};
+
--
2.34.1
^ permalink raw reply related
* Re: [REGRESSION] rseq: refactoring in v6.19 broke everyone on arm64 and tcmalloc everywhere
From: Dmitry Vyukov @ 2026-04-24 9:30 UTC (permalink / raw)
To: Mathias Stearn
Cc: Thomas Gleixner, Jinjie Ruan, linux-man, Mark Rutland,
Mathieu Desnoyers, Catalin Marinas, Will Deacon, Boqun Feng,
Paul E. McKenney, Chris Kennelly, regressions, linux-kernel,
linux-arm-kernel, Peter Zijlstra, Ingo Molnar, Blake Oler
In-Reply-To: <CAHnCjA1LqbaUGkPe79EeP6Mpaki8QWeR-JBSbrG0z6pTm9CmUg@mail.gmail.com>
On Fri, 24 Apr 2026 at 10:32, Mathias Stearn <mathias@mongodb.com> wrote:
>
> On Fri, Apr 24, 2026 at 9:57 AM Dmitry Vyukov <dvyukov@google.com> wrote:
> > > So if the code only requires to know when it got rescheduled to another
> > > CPU then it still should work, no?
> >
> > This was my first thought too:
> > https://lore.kernel.org/lkml/CACT4Y+a9GnOh3wHKSRwzoKF6_OSksQ8qehnHfpCgkQSt_OOmYg@mail.gmail.com/
> > The only problem is with membarrier (it used to force write to
> > __rseq_abi.cpu_id_start for all threads, but now it does not).
> > Otherwise the caching scheme works.
>
> I almost wrote a message last night saying that we didn't need
> cpu_id_start invalidation on preemption. However, I remembered that
> the Grow() function[1] does a load outside of a critical section then
> stores a derived value inside the critical section, guarded only by
> the cpu_id_start invalidation check in StoreCurrentCpu[2]. It really
> should be doing a compare against the original value inside the
> critical section (or just do the whole thing inside), but it doesn't.
> I haven't reasoned end-to-end through this fully to prove corruption
> is possible, but I suspect that it is if another thread same-cpu
> preempts between the loads and the store and updates the header before
> the original thread resumes and writes its original intended header
> value. Ditto for signals, which sometimes allocate even though they
> shouldn't.
>
> I was really hoping that we would only need to do the "redundant"
> cpu_id_start writes would only be needed on membarrier_rseq IPIs where
> it really is a pay-for-what-you-use functionality, I think existing
> binaries depend on invalidation on preemption. Luckily that should be
> cheap enough to be ~free.
I've prototyped this idea too:
https://github.com/dvyukov/linux/commit/1284e3723047cb5afd247f75c53de43efc18db82
> [1] https://github.com/google/tcmalloc/blob/8e98046ec5639bffbe70a53770a2699dd355b26d/tcmalloc/internal/percpu_tcmalloc.h#L964-L980
> [2] https://github.com/google/tcmalloc/blob/8e98046ec5639bffbe70a53770a2699dd355b26d/tcmalloc/internal/percpu_tcmalloc.h#L551-L605
^ permalink raw reply
* [PATCH v5 1/2] dt-bindings: arm: amlogic: add support for Amediatech X98Q
From: christian.koever-draxl @ 2026-04-24 9:36 UTC (permalink / raw)
To: robh, krzk+dt, conor+dt, neil.armstrong, khilman
Cc: jbrunet, martin.blumenstingl, devicetree, linux-amlogic,
linux-arm-kernel, linux-kernel,
Christian Stefan Kövér-Draxl, Conor Dooley
In-Reply-To: <20260424093633.10734-1-christian.koever-draxl@student.uibk.ac.at>
From: Christian Stefan Kövér-Draxl <christian.koever-draxl@student.uibk.ac.at>
Add the board binding for the Amediatech X98Q TV box.
Signed-off-by: Christian Stefan Kövér-Draxl <christian.koever-draxl@student.uibk.ac.at>
Acked-by: Conor Dooley <conor.dooley@microchip.com>
---
Documentation/devicetree/bindings/arm/amlogic.yaml | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/Documentation/devicetree/bindings/arm/amlogic.yaml b/Documentation/devicetree/bindings/arm/amlogic.yaml
index a885278bc4e2..c0167fbc310a 100644
--- a/Documentation/devicetree/bindings/arm/amlogic.yaml
+++ b/Documentation/devicetree/bindings/arm/amlogic.yaml
@@ -248,6 +248,13 @@ properties:
- const: amlogic,s805x2
- const: amlogic,s4
+ - description: Boards with the Amlogic Meson S4 S905W2 SoC
+ items:
+ - enum:
+ - amediatech,x98q
+ - const: amlogic,s905w2
+ - const: amlogic,s4
+
- description: Boards with the Amlogic Meson S4 S905Y4 SoC
items:
- enum:
--
2.54.0
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox