* Re: [PATCH 0/8] iio: timestamp declaration cleanup
From: Andy Shevchenko @ 2026-05-18 7:14 UTC (permalink / raw)
To: David Lechner
Cc: Jyoti Bhayana, Jonathan Cameron, Nuno Sá, Andy Shevchenko,
Nicolas Ferre, Alexandre Belloni, Claudiu Beznea, Maxime Coquelin,
Alexandre Torgue, Benson Leung, Guenter Roeck, linux-iio,
linux-kernel, linux-arm-kernel, linux-stm32, chrome-platform
In-Reply-To: <agq7PPw0qupI_8Dh@ashevche-desk.local>
On Mon, May 18, 2026 at 10:09:48AM +0300, Andy Shevchenko wrote:
> On Sun, May 17, 2026 at 01:17:17PM -0500, David Lechner wrote:
> > While looking around the code, I noticed that there are a lot of places
> > were we are manually filling all of the fields of an IIO timestamp.
> >
> > This is error-prone (as seen in the first patch) and more verbose than
> > it needs to be.
> >
> > I went with the approach of using the existing IIO_CHAN_SOFT_TIMESTAMP()
> > macro for doing a struct assignment. This does require a cast, which
>
> No, it's *not* a cast. It's a compound literal. And instead of doing this in
> every driver, add it to the macro (in a separate patch). Oh, let me just cook
> it for you (I added that to several cases in the past).
20260518071349.469748-1-andriy.shevchenko@linux.intel.com
> > makes it a bit more verbose, but we were already doing that in to
> > drivers, so I went with it anyway.
>
> > If we want to consider alternatives, we could make a iio helper function
> > or macro like the first and second patches did.
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply
* Re: [PATCH 2/3] memory: mtk-smi: Add a flag skip_rpm
From: Xueqi Zhang (张雪琦) @ 2026-05-18 7:13 UTC (permalink / raw)
To: robh@kernel.org, matthias.bgg@gmail.com,
Yong Wu (吴勇), AngeloGioacchino Del Regno,
krzk@kernel.org, conor+dt@kernel.org
Cc: Wendy-ST Lin (林詩庭),
linux-kernel@vger.kernel.org, linux-mediatek@lists.infradead.org,
linux-arm-kernel@lists.infradead.org, iommu@lists.linux.dev,
Project_Global_Chrome_Upstream_Group, devicetree@vger.kernel.org
In-Reply-To: <46e0e1f1-e094-40f9-99f9-22678bb40d39@collabora.com>
Hi Angelo,
First of all, please accept my apologies for the delayed response. I
have been deeply occupied with MT8196 Aluminium pKVM SMMU and SMI
related tasks recently.
Regarding your question, my previous description in the patch was not
accurate enough and may have caused some confusion. In fact, not
all SMI commons have their backup/restore handled by the RTFF
hardware. The SMI commons are distributed across various subsystems
(e.g., mminfra, venc, display, cam, etc.). Currently, only the SMI
common under the mminfra subsystem is backed up and restored by
the RTFF hardware.
Therefore, I believe adding a specific 'skip_rpm' flag is more
appropriate here. If we were to differentiate this based on a new
MTK_SMI_GEN3 type, it would imply that all SMI common modules of
that generation would skip the RPM operations, which is not the
intended behavior.
To make this clearer, I plan to update the commit message in the
next version as follows:
Subject: memory: mtk-smi: Add skip_rpm flag for certain MT8196 SMI
commons
Body:
On MT8196, certain SMI commons are backed up and restored by the RTFF
hardware rather than by software.
For these specific SMI commons, software-controlled register backup
and restore in the runtime callback is no longer necessary. Therefore,
introduce a 'skip_rpm' flag to bypass these redundant RPMoperations
for these SMI commons.
What do you think about this approach?
For reference, here is the link to the patch series on Patchwork:
https://patchwork.kernel.org/project/linux-mediatek/list/?series=945811&archive=both
Thanks,
Xueqi
On Thu, 2025-03-20 at 13:11 +0100, AngeloGioacchino Del Regno wrote:
> External email : Please do not click links or open attachments until
> you have verified the sender or the content.
>
>
> Il 20/03/25 08:36, Xueqi Zhang ha scritto:
> > MT8196 SMI commons is backed up/restored by RTFF HW.
> > It doesn't need SW control the register backup/store
> > in the runtime callback.Therefore, add a flag skip_rpm
> > to help skip RPM operations for SMI commons.
> >
> > Signed-off-by: Xueqi Zhang <xueqi.zhang@mediatek.com>
>
> So the MT8196 SMI common doesn't require any clocks?
>
> That's fine for me, but this looks bloody similar to MT6989's SMI
> common, which
> is SMI GEN3 and not GEN2....
>
> ....so, are you sure that you need a `skip_rpm` flag and not new
> MTK_SMI_GEN3 and
> MTK_SMI_GEN3_SUB_COMM types? :-)
>
> Regards,
> Angelo
>
> > ---
> > drivers/memory/mtk-smi.c | 11 ++++++++---
> > 1 file changed, 8 insertions(+), 3 deletions(-)
> >
> > diff --git a/drivers/memory/mtk-smi.c b/drivers/memory/mtk-smi.c
> > index a8f5467d6b31..b9affa3c3185 100644
> > --- a/drivers/memory/mtk-smi.c
> > +++ b/drivers/memory/mtk-smi.c
> > @@ -123,6 +123,7 @@ static const char * const mtk_smi_common_clks[]
> > = {"apb", "smi", "gals0", "gals1
> > struct mtk_smi_common_plat {
> > enum mtk_smi_type type;
> > bool has_gals;
> > + bool skip_rpm;
> > u32 bus_sel; /* Balance some larbs to
> > enter mmu0 or mmu1 */
> >
> > const struct mtk_smi_reg_pair *init;
> > @@ -547,6 +548,9 @@ static int mtk_smi_dts_clk_init(struct device
> > *dev, struct mtk_smi *smi,
> > {
> > int i, ret;
> >
> > + if (smi->plat->skip_rpm)
> > + return 0;
> > +
> > for (i = 0; i < clk_nr_required; i++)
> > smi->clks[i].id = clks[i];
> > ret = devm_clk_bulk_get(dev, clk_nr_required, smi->clks);
> > @@ -783,7 +787,7 @@ static int mtk_smi_common_probe(struct
> > platform_device *pdev)
> > common->dev = dev;
> > common->plat = of_device_get_match_data(dev);
> >
> > - if (common->plat->has_gals) {
> > + if (!common->plat->skip_rpm && common->plat->has_gals) {
> > if (common->plat->type == MTK_SMI_GEN2)
> > clk_required = MTK_SMI_COM_GALS_REQ_CLK_NR;
> > else if (common->plat->type == MTK_SMI_GEN2_SUB_COMM)
> > @@ -814,13 +818,14 @@ static int mtk_smi_common_probe(struct
> > platform_device *pdev)
> > }
> >
> > /* link its smi-common if this is smi-sub-common */
> > - if (common->plat->type == MTK_SMI_GEN2_SUB_COMM) {
> > + if (common->plat->type == MTK_SMI_GEN2_SUB_COMM && !common-
> > >plat->skip_rpm) {
> > ret = mtk_smi_device_link_common(dev, &common-
> > >smi_common_dev);
> > if (ret < 0)
> > return ret;
> > }
> >
> > - pm_runtime_enable(dev);
> > + if (!common->plat->skip_rpm)
> > + pm_runtime_enable(dev);
> > platform_set_drvdata(pdev, common);
> > return 0;
> > }
>
>
^ permalink raw reply
* Re: [PATCH 0/8] iio: timestamp declaration cleanup
From: Andy Shevchenko @ 2026-05-18 7:09 UTC (permalink / raw)
To: David Lechner
Cc: Jyoti Bhayana, Jonathan Cameron, Nuno Sá, Andy Shevchenko,
Nicolas Ferre, Alexandre Belloni, Claudiu Beznea, Maxime Coquelin,
Alexandre Torgue, Benson Leung, Guenter Roeck, linux-iio,
linux-kernel, linux-arm-kernel, linux-stm32, chrome-platform
In-Reply-To: <20260517-iio-timestamp-cleanup-v1-0-61fb908c11c7@baylibre.com>
On Sun, May 17, 2026 at 01:17:17PM -0500, David Lechner wrote:
> While looking around the code, I noticed that there are a lot of places
> were we are manually filling all of the fields of an IIO timestamp.
>
> This is error-prone (as seen in the first patch) and more verbose than
> it needs to be.
>
> I went with the approach of using the existing IIO_CHAN_SOFT_TIMESTAMP()
> macro for doing a struct assignment. This does require a cast, which
No, it's *not* a cast. It's a compound literal. And instead of doing this in
every driver, add it to the macro (in a separate patch). Oh, let me just cook
it for you (I added that to several cases in the past).
> makes it a bit more verbose, but we were already doing that in to
> drivers, so I went with it anyway.
> If we want to consider alternatives, we could make a iio helper function
> or macro like the first and second patches did.
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply
* Re: [PATCH v14 04/44] arm64: RMI: Add SMC definitions for calling the RMM
From: Gavin Shan @ 2026-05-18 7:08 UTC (permalink / raw)
To: Steven Price, kvm, kvmarm
Cc: Catalin Marinas, Marc Zyngier, Will Deacon, James Morse,
Oliver Upton, Suzuki K Poulose, Zenghui Yu, linux-arm-kernel,
linux-kernel, Joey Gouly, Alexandru Elisei, Christoffer Dall,
Fuad Tabba, linux-coco, Ganapatrao Kulkarni, Shanker Donthineni,
Alper Gun, Aneesh Kumar K . V, Emi Kisanuki, Vishal Annapurve,
WeiLin.Chang, Lorenzo.Pieralisi2
In-Reply-To: <20260513131757.116630-5-steven.price@arm.com>
Hi Steven,
On 5/13/26 11:17 PM, Steven Price wrote:
> The RMM (Realm Management Monitor) provides functionality that can be
> accessed by SMC calls from the host.
>
> The SMC definitions are based on DEN0137[1] version 2.0-bet1
>
> [1] https://developer.arm.com/documentation/den0137/2-0bet1/
>
> Signed-off-by: Steven Price <steven.price@arm.com>
> ---
> Changes since v13:
> * Updated to RMM spec v2.0-bet1
> Changes since v12:
> * Updated to RMM spec v2.0-bet0
> Changes since v9:
> * Corrected size of 'ripas_value' in struct rec_exit. The spec states
> this is an 8-bit type with padding afterwards (rather than a u64).
> Changes since v8:
> * Added RMI_PERMITTED_GICV3_HCR_BITS to define which bits the RMM
> permits to be modified.
> Changes since v6:
> * Renamed REC_ENTER_xxx defines to include 'FLAG' to make it obvious
> these are flag values.
> Changes since v5:
> * Sorted the SMC #defines by value.
> * Renamed SMI_RxI_CALL to SMI_RMI_CALL since the macro is only used for
> RMI calls.
> * Renamed REC_GIC_NUM_LRS to REC_MAX_GIC_NUM_LRS since the actual
> number of available list registers could be lower.
> * Provided a define for the reserved fields of FeatureRegister0.
> * Fix inconsistent names for padding fields.
> Changes since v4:
> * Update to point to final released RMM spec.
> * Minor rearrangements.
> Changes since v3:
> * Update to match RMM spec v1.0-rel0-rc1.
> Changes since v2:
> * Fix specification link.
> * Rename rec_entry->rec_enter to match spec.
> * Fix size of pmu_ovf_status to match spec.
> ---
> arch/arm64/include/asm/rmi_smc.h | 448 +++++++++++++++++++++++++++++++
> 1 file changed, 448 insertions(+)
> create mode 100644 arch/arm64/include/asm/rmi_smc.h
>
> diff --git a/arch/arm64/include/asm/rmi_smc.h b/arch/arm64/include/asm/rmi_smc.h
> new file mode 100644
> index 000000000000..a09b7a631fef
> --- /dev/null
> +++ b/arch/arm64/include/asm/rmi_smc.h
> @@ -0,0 +1,448 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Copyright (C) 2023-2026 ARM Ltd.
> + *
> + * The values and structures in this file are from the Realm Management Monitor
> + * specification (DEN0137) version 2.0-bet1:
> + * https://developer.arm.com/documentation/den0137/2-0bet1/
> + */
> +
> +#ifndef __ASM_RMI_SMC_H
> +#define __ASM_RMI_SMC_H
> +
> +#include <linux/arm-smccc.h>
> +
> +#define SMC_RMI_CALL(func) \
> + ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
> + ARM_SMCCC_SMC_64, \
> + ARM_SMCCC_OWNER_STANDARD, \
> + (func))
> +
> +#define SMC_RMI_VERSION SMC_RMI_CALL(0x0150)
> +
> +#define SMC_RMI_RTT_DATA_MAP_INIT SMC_RMI_CALL(0x0153)
> +
> +#define SMC_RMI_REALM_ACTIVATE SMC_RMI_CALL(0x0157)
> +#define SMC_RMI_REALM_CREATE SMC_RMI_CALL(0x0158)
> +#define SMC_RMI_REALM_DESTROY SMC_RMI_CALL(0x0159)
> +#define SMC_RMI_REC_CREATE SMC_RMI_CALL(0x015a)
> +#define SMC_RMI_REC_DESTROY SMC_RMI_CALL(0x015b)
> +#define SMC_RMI_REC_ENTER SMC_RMI_CALL(0x015c)
> +#define SMC_RMI_RTT_CREATE SMC_RMI_CALL(0x015d)
> +#define SMC_RMI_RTT_DESTROY SMC_RMI_CALL(0x015e)
> +
> +#define SMC_RMI_RTT_READ_ENTRY SMC_RMI_CALL(0x0161)
> +
> +#define SMC_RMI_RTT_DEV_VALIDATE SMC_RMI_CALL(0x0163)
> +#define SMC_RMI_PSCI_COMPLETE SMC_RMI_CALL(0x0164)
> +#define SMC_RMI_FEATURES SMC_RMI_CALL(0x0165)
> +#define SMC_RMI_RTT_FOLD SMC_RMI_CALL(0x0166)
> +
> +#define SMC_RMI_RTT_INIT_RIPAS SMC_RMI_CALL(0x0168)
> +#define SMC_RMI_RTT_SET_RIPAS SMC_RMI_CALL(0x0169)
> +#define SMC_RMI_VSMMU_CREATE SMC_RMI_CALL(0x016a)
> +#define SMC_RMI_VSMMU_DESTROY SMC_RMI_CALL(0x016b)
> +#define SMC_RMI_RMM_CONFIG_SET SMC_RMI_CALL(0x016e)
> +#define SMC_RMI_PSMMU_IRQ_NOTIFY SMC_RMI_CALL(0x016f)
> +
> +#define SMC_RMI_PDEV_ABORT SMC_RMI_CALL(0x0174)
> +#define SMC_RMI_PDEV_COMMUNICATE SMC_RMI_CALL(0x0175)
> +#define SMC_RMI_PDEV_CREATE SMC_RMI_CALL(0x0176)
> +#define SMC_RMI_PDEV_DESTROY SMC_RMI_CALL(0x0177)
> +#define SMC_RMI_PDEV_GET_STATE SMC_RMI_CALL(0x0178)
> +
> +#define SMC_RMI_PDEV_STREAM_KEY_REFRESH SMC_RMI_CALL(0x017a)
> +#define SMC_RMI_PDEV_SET_PUBKEY SMC_RMI_CALL(0x017b)
> +#define SMC_RMI_PDEV_STOP SMC_RMI_CALL(0x017c)
> +#define SMC_RMI_RTT_AUX_CREATE SMC_RMI_CALL(0x017d)
> +#define SMC_RMI_RTT_AUX_DESTROY SMC_RMI_CALL(0x017e)
> +#define SMC_RMI_RTT_AUX_FOLD SMC_RMI_CALL(0x017f)
> +
> +#define SMC_RMI_VDEV_ABORT SMC_RMI_CALL(0x0185)
> +#define SMC_RMI_VDEV_COMMUNICATE SMC_RMI_CALL(0x0186)
> +#define SMC_RMI_VDEV_CREATE SMC_RMI_CALL(0x0187)
> +#define SMC_RMI_VDEV_DESTROY SMC_RMI_CALL(0x0188)
> +#define SMC_RMI_VDEV_GET_STATE SMC_RMI_CALL(0x0189)
> +#define SMC_RMI_VDEV_UNLOCK SMC_RMI_CALL(0x018a)
> +#define SMC_RMI_RTT_SET_S2AP SMC_RMI_CALL(0x018b)
> +#define SMC_RMI_VDEV_COMPLETE SMC_RMI_CALL(0x018e)
> +
> +#define SMC_RMI_VDEV_GET_INTERFACE_REPORT SMC_RMI_CALL(0x01d0)
> +#define SMC_RMI_VDEV_GET_MEASUREMENTS SMC_RMI_CALL(0x01d1)
> +#define SMC_RMI_VDEV_LOCK SMC_RMI_CALL(0x01d2)
> +#define SMC_RMI_VDEV_START SMC_RMI_CALL(0x01d3)
> +
> +#define SMC_RMI_VSMMU_EVENT_NOTIFY SMC_RMI_CALL(0x01d6)
> +#define SMC_RMI_PSMMU_ACTIVATE SMC_RMI_CALL(0x01d7)
> +#define SMC_RMI_PSMMU_DEACTIVATE SMC_RMI_CALL(0x01d8)
> +
> +#define SMC_RMI_PSMMU_ST_L2_CREATE SMC_RMI_CALL(0x01db)
> +#define SMC_RMI_PSMMU_ST_L2_DESTROY SMC_RMI_CALL(0x01dc)
> +#define SMC_RMI_DPT_L0_CREATE SMC_RMI_CALL(0x01dd)
> +#define SMC_RMI_DPT_L0_DESTROY SMC_RMI_CALL(0x01de)
> +#define SMC_RMI_DPT_L1_CREATE SMC_RMI_CALL(0x01df)
> +#define SMC_RMI_DPT_L1_DESTROY SMC_RMI_CALL(0x01e0)
> +#define SMC_RMI_GRANULE_TRACKING_GET SMC_RMI_CALL(0x01e1)
> +
> +#define SMC_RMI_GRANULE_TRACKING_SET SMC_RMI_CALL(0x01e3)
> +
> +#define SMC_RMI_RMM_CONFIG_GET SMC_RMI_CALL(0x01ec)
> +
> +#define SMC_RMI_RMM_STATE_GET SMC_RMI_CALL(0x01ee)
> +
> +#define SMC_RMI_PSMMU_EVENT_CONSUME SMC_RMI_CALL(0x01f0)
> +#define SMC_RMI_GRANULE_RANGE_DELEGATE SMC_RMI_CALL(0x01f1)
> +#define SMC_RMI_GRANULE_RANGE_UNDELEGATE SMC_RMI_CALL(0x01f2)
> +#define SMC_RMI_GPT_L1_CREATE SMC_RMI_CALL(0x01f3)
> +#define SMC_RMI_GPT_L1_DESTROY SMC_RMI_CALL(0x01f4)
> +#define SMC_RMI_RTT_DATA_MAP SMC_RMI_CALL(0x01f5)
> +#define SMC_RMI_RTT_DATA_UNMAP SMC_RMI_CALL(0x01f6)
> +#define SMC_RMI_RTT_DEV_MAP SMC_RMI_CALL(0x01f7)
> +#define SMC_RMI_RTT_DEV_UNMAP SMC_RMI_CALL(0x01f8)
> +#define SMC_RMI_RTT_ARCH_DEV_MAP SMC_RMI_CALL(0x01f9)
> +#define SMC_RMI_RTT_ARCH_DEV_UNMAP SMC_RMI_CALL(0x01fa)
> +#define SMC_RMI_RTT_UNPROT_MAP SMC_RMI_CALL(0x01fb)
> +#define SMC_RMI_RTT_UNPROT_UNMAP SMC_RMI_CALL(0x01fc)
> +#define SMC_RMI_RTT_AUX_PROT_MAP SMC_RMI_CALL(0x01fd)
> +#define SMC_RMI_RTT_AUX_PROT_UNMAP SMC_RMI_CALL(0x01fe)
> +#define SMC_RMI_RTT_AUX_UNPROT_MAP SMC_RMI_CALL(0x01ff)
> +#define SMC_RMI_RTT_AUX_UNPROT_UNMAP SMC_RMI_CALL(0x0200)
> +#define SMC_RMI_REALM_TERMINATE SMC_RMI_CALL(0x0201)
> +#define SMC_RMI_RMM_ACTIVATE SMC_RMI_CALL(0x0202)
> +#define SMC_RMI_OP_CONTINUE SMC_RMI_CALL(0x0203)
> +#define SMC_RMI_PDEV_STREAM_CONNECT SMC_RMI_CALL(0x0204)
> +#define SMC_RMI_PDEV_STREAM_DISCONNECT SMC_RMI_CALL(0x0205)
> +#define SMC_RMI_PDEV_STREAM_COMPLETE SMC_RMI_CALL(0x0206)
> +#define SMC_RMI_PDEV_STREAM_KEY_PURGE SMC_RMI_CALL(0x0207)
> +#define SMC_RMI_OP_MEM_DONATE SMC_RMI_CALL(0x0208)
> +#define SMC_RMI_OP_MEM_RECLAIM SMC_RMI_CALL(0x0209)
> +#define SMC_RMI_OP_CANCEL SMC_RMI_CALL(0x020a)
> +#define SMC_RMI_VSMMU_FEATURES SMC_RMI_CALL(0x020b)
> +#define SMC_RMI_VSMMU_CMD_GET SMC_RMI_CALL(0x020c)
> +#define SMC_RMI_VSMMU_CMD_COMPLETE SMC_RMI_CALL(0x020d)
> +#define SMC_RMI_PSMMU_INFO SMC_RMI_CALL(0x020e)
> +
> +#define RMI_ABI_MAJOR_VERSION 2
> +#define RMI_ABI_MINOR_VERSION 0
> +
> +#define RMI_ABI_VERSION_GET_MAJOR(version) ((version) >> 16)
> +#define RMI_ABI_VERSION_GET_MINOR(version) ((version) & 0xFFFF)
> +#define RMI_ABI_VERSION(major, minor) (((major) << 16) | (minor))
> +
> +#define RMI_UNASSIGNED 0
> +#define RMI_ASSIGNED 1
> +#define RMI_TABLE 2
> +
Those definations are inconsistent to those defined in tf-rmm/lib/smc/include/smc-rmi.h
where their size are 64-bits. Also, other two definations are missed here and perhaps
worthy to be added here.
#define RMI_ASSIGNED_DEV UL(3)
#define RMI_AUX_DESTROYED UL(5)
> +#define RMI_RETURN_STATUS(ret) ((ret) & 0xFF)
> +#define RMI_RETURN_INDEX(ret) (((ret) >> 8) & 0xFF)
> +#define RMI_RETURN_MEMREQ(ret) (((ret) >> 8) & 0x3)
> +#define RMI_RETURN_CAN_CANCEL(ret) (((ret) >> 10) & 0x1)
> +
> +#define RMI_SUCCESS 0
> +#define RMI_ERROR_INPUT 1
> +#define RMI_ERROR_REALM 2
> +#define RMI_ERROR_REC 3
> +#define RMI_ERROR_RTT 4
> +#define RMI_ERROR_NOT_SUPPORTED 5
> +#define RMI_ERROR_DEVICE 6
> +#define RMI_ERROR_RTT_AUX 7
> +#define RMI_ERROR_PSMMU_ST 8
> +#define RMI_ERROR_DPT 9
> +#define RMI_BUSY 10
> +#define RMI_ERROR_GLOBAL 11
> +#define RMI_ERROR_TRACKING 12
> +#define RMI_INCOMPLETE 13
> +#define RMI_BLOCKED 14
> +#define RMI_ERROR_GPT 15
> +#define RMI_ERROR_GRANULE 16
> +
> +#define RMI_OP_MEM_REQ_NONE 0
> +#define RMI_OP_MEM_REQ_DONATE 1
> +#define RMI_OP_MEM_REQ_RECLAIM 2
> +
The size of those definations are 32-bits, different to that of them defined
in tf-rmm/lib/smc/include/smc-rmi.h
#define RMI_OP_MEM_REQ_NONE (0UL)
#define RMI_OP_MEM_REQ_DONATE (1UL)
#define RMI_OP_MEM_REQ_RECLAIM (2UL)
> +#define RMI_DONATE_SIZE(req) ((req) & 0x3)
> +#define RMI_DONATE_COUNT_MASK GENMASK(15, 2)
> +#define RMI_DONATE_COUNT(req) (((req) & RMI_DONATE_COUNT_MASK) >> 2)
> +#define RMI_DONATE_CONTIG(req) (!!((req) & BIT(16)))
> +#define RMI_DONATE_STATE(req) (!!((req) & BIT(17)))
> +
> +#define RMI_OP_MEM_DELEGATED 0
> +#define RMI_OP_MEM_UNDELEGATED 1
> +
As above, inconsistent size to those definations in tf-rmm/lib/smc/include/smc-rmi.h
> +#define RMI_ADDR_TYPE_NONE 0
> +#define RMI_ADDR_TYPE_SINGLE 1
> +#define RMI_ADDR_TYPE_LIST 2
> +
As above, inconsistent size to those definations in tf-rmm/lib/smc/include/smc-rmi.h
> +#define RMI_ADDR_RANGE_SIZE_MASK GENMASK(1, 0)
> +#define RMI_ADDR_RANGE_COUNT_MASK GENMASK(PAGE_SHIFT - 1, 2)
> +#define RMI_ADDR_RANGE_ADDR_MASK (PAGE_MASK & GENMASK(51, 0))
> +#define RMI_ADDR_RANGE_STATE_MASK BIT(63)
> +
> +#define RMI_ADDR_RANGE_SIZE(ar) (FIELD_GET(RMI_ADDR_RANGE_SIZE_MASK, \
> + (ar)))
> +#define RMI_ADDR_RANGE_COUNT(ar) (FIELD_GET(RMI_ADDR_RANGE_COUNT_MASK, \
> + (ar)))
> +#define RMI_ADDR_RANGE_ADDR(ar) ((ar) & RMI_ADDR_RANGE_ADDR_MASK)
> +#define RMI_ADDR_RANGE_STATE(ar) (FIELD_GET(RMI_ADDR_RANGE_STATE_MASK, \
> + (ar)))
> +
> +enum rmi_ripas {
> + RMI_EMPTY = 0,
> + RMI_RAM = 1,
> + RMI_DESTROYED = 2,
> + RMI_DEV = 3,
> +};
> +
> +#define RMI_NO_MEASURE_CONTENT 0
> +#define RMI_MEASURE_CONTENT 1
> +
> +#define RMI_FEATURE_REGISTER_0_S2SZ GENMASK(7, 0)
> +#define RMI_FEATURE_REGISTER_0_LPA2 BIT(8)
> +#define RMI_FEATURE_REGISTER_0_SVE BIT(9)
> +#define RMI_FEATURE_REGISTER_0_SVE_VL GENMASK(13, 10)
> +#define RMI_FEATURE_REGISTER_0_NUM_BPS GENMASK(19, 14)
> +#define RMI_FEATURE_REGISTER_0_NUM_WPS GENMASK(25, 20)
> +#define RMI_FEATURE_REGISTER_0_PMU BIT(26)
> +#define RMI_FEATURE_REGISTER_0_PMU_NUM_CTRS GENMASK(31, 27)
> +
> +#define RMI_FEATURE_REGISTER_1_RMI_GRAN_SZ_4KB BIT(0)
> +#define RMI_FEATURE_REGISTER_1_RMI_GRAN_SZ_16KB BIT(1)
> +#define RMI_FEATURE_REGISTER_1_RMI_GRAN_SZ_64KB BIT(2)
> +#define RMI_FEATURE_REGISTER_1_HASH_SHA_256 BIT(3)
> +#define RMI_FEATURE_REGISTER_1_HASH_SHA_384 BIT(4)
> +#define RMI_FEATURE_REGISTER_1_HASH_SHA_512 BIT(5)
> +#define RMI_FEATURE_REGISTER_1_MAX_RECS_ORDER GENMASK(9, 6)
> +#define RMI_FEATURE_REGISTER_1_L0GPTSZ GENMASK(13, 10)
> +#define RMI_FEATURE_REGISTER_1_PPS GENMASK(16, 14)
> +
> +#define RMI_FEATURE_REGISTER_2_DA BIT(0)
> +#define RMI_FEATURE_REGISTER_2_DA_COH BIT(1)
> +#define RMI_FEATURE_REGISTER_2_VSMMU BIT(2)
> +#define RMI_FEATURE_REGISTER_2_ATS BIT(3)
> +#define RMI_FEATURE_REGISTER_2_MAX_VDEVS_ORDER GENMASK(7, 4)
> +#define RMI_FEATURE_REGISTER_2_VDEV_KROU BIT(8)
> +#define RMI_FEATURE_REGISTER_2_NON_TEE_STREAM BIT(9)
> +
> +#define RMI_FEATURE_REGISTER_3_MAX_NUM_AUX_PLANES GENMASK(3, 0)
> +#define RMI_FEATURE_REGISTER_3_RTT_PLAN GENMASK(5, 4)
> +#define RMI_FEATURE_REGISTER_3_RTT_S2AP_INDIRECT BIT(6)
> +
> +#define RMI_FEATURE_REGISTER_4_MEC_COUNT GENMASK(63, 0)
> +
> +#define RMI_MEM_CATEGORY_CONVENTIONAL 0
> +#define RMI_MEM_CATEGORY_DEV_NCOH 1
> +#define RMI_MEM_CATEGORY_DEV_COH 2
> +
> +#define RMI_TRACKING_RESERVED 0
> +#define RMI_TRACKING_NONE 1
> +#define RMI_TRACKING_FINE 2
> +#define RMI_TRACKING_COARSE 3
> +
> +#define RMI_GRANULE_SIZE_4KB 0
> +#define RMI_GRANULE_SIZE_16KB 1
> +#define RMI_GRANULE_SIZE_64KB 2
> +
> +/*
> + * Note many of these fields are smaller than u64 but all fields have u64
> + * alignment, so use u64 to ensure correct alignment.
> + */
> +struct rmm_config {
> + union { /* 0x0 */
> + struct {
> + u64 tracking_region_size;
> + u64 rmi_granule_size;
> + };
> + u8 sizer[0x1000];
> + };
> +};
> +
> +#define RMI_REALM_PARAM_FLAG_LPA2 BIT(0)
> +#define RMI_REALM_PARAM_FLAG_SVE BIT(1)
> +#define RMI_REALM_PARAM_FLAG_PMU BIT(2)
> +
> +struct realm_params {
> + union { /* 0x0 */
> + struct {
> + u64 flags;
> + u64 s2sz;
> + u64 sve_vl;
> + u64 num_bps;
> + u64 num_wps;
> + u64 pmu_num_ctrs;
> + u64 hash_algo;
> + u64 num_aux_planes;
> + };
> + u8 padding0[0x400];
> + };
> + union { /* 0x400 */
> + struct {
> + u8 rpv[64];
> + u64 ats_plane;
> + };
> + u8 padding1[0x400];
> + };
> + union { /* 0x800 */
> + struct {
> + u64 padding;
> + u64 rtt_base;
> + s64 rtt_level_start;
> + u64 rtt_num_start;
> + u64 flags1;
> + u64 aux_rtt_base[3];
> + };
> + u8 padding2[0x800];
> + };
> +};
> +
> +/*
> + * The number of GPRs (starting from X0) that are
> + * configured by the host when a REC is created.
> + */
> +#define REC_CREATE_NR_GPRS 8
> +
> +#define REC_PARAMS_FLAG_RUNNABLE BIT_ULL(0)
> +
> +struct rec_params {
> + union { /* 0x0 */
> + u64 flags;
> + u8 padding0[0x100];
> + };
> + union { /* 0x100 */
> + u64 mpidr;
> + u8 padding1[0x100];
> + };
> + union { /* 0x200 */
> + u64 pc;
> + u8 padding2[0x100];
> + };
> + union { /* 0x300 */
> + u64 gprs[REC_CREATE_NR_GPRS];
> + u8 padding3[0xd00];
> + };
> +};
> +
> +#define REC_ENTER_FLAG_EMULATED_MMIO BIT(0)
> +#define REC_ENTER_FLAG_INJECT_SEA BIT(1)
> +#define REC_ENTER_FLAG_TRAP_WFI BIT(2)
> +#define REC_ENTER_FLAG_TRAP_WFE BIT(3)
> +#define REC_ENTER_FLAG_RIPAS_RESPONSE BIT(4)
> +#define REC_ENTER_FLAG_S2AP_RESPONSE BIT(5)
> +#define REC_ENTER_FLAG_DEV_MEM_RESPONSE BIT(6)
> +#define REC_ENTER_FLAG_FORCE_P0 BIT(7)
> +
> +#define REC_RUN_GPRS 31
> +#define REC_MAX_GIC_NUM_LRS 16
> +
> +#define RMI_PERMITTED_GICV3_HCR_BITS (ICH_HCR_EL2_UIE | \
> + ICH_HCR_EL2_LRENPIE | \
> + ICH_HCR_EL2_NPIE | \
> + ICH_HCR_EL2_VGrp0EIE | \
> + ICH_HCR_EL2_VGrp0DIE | \
> + ICH_HCR_EL2_VGrp1EIE | \
> + ICH_HCR_EL2_VGrp1DIE | \
> + ICH_HCR_EL2_TDIR)
> +
> +struct rec_enter {
> + union { /* 0x000 */
> + u64 flags;
> + u8 padding0[0x200];
> + };
> + union { /* 0x200 */
> + u64 gprs[REC_RUN_GPRS];
> + u8 padding1[0x100];
> + };
> + u8 padding3[0x500];
> +};
> +
> +#define RMI_EXIT_SYNC 0x00
> +#define RMI_EXIT_IRQ 0x01
> +#define RMI_EXIT_FIQ 0x02
> +#define RMI_EXIT_PSCI 0x03
> +#define RMI_EXIT_RIPAS_CHANGE 0x04
> +#define RMI_EXIT_HOST_CALL 0x05
> +#define RMI_EXIT_SERROR 0x06
> +#define RMI_EXIT_S2AP_CHANGE 0x07
> +#define RMI_EXIT_VDEV_REQUEST 0x08
> +#define RMI_EXIT_VDEV_VALIDATE_MAPPING 0x09
> +#define RMI_EXIT_VSMMU_COMMAND 0x0a
> +
> +struct rec_exit {
> + union { /* 0x000 */
> + u8 exit_reason;
> + u8 padding0[0x100];
> + };
> + union { /* 0x100 */
> + struct {
> + u64 esr;
> + u64 far;
> + u64 hpfar;
> + u64 rtt_tree;
> + };
> + u8 padding1[0x100];
> + };
> + union { /* 0x200 */
> + u64 gprs[REC_RUN_GPRS];
> + u8 padding2[0x100];
> + };
> + union { /* 0x300 */
> + u8 padding3[0x100];
> + };
> + union { /* 0x400 */
> + struct {
> + u64 cntp_ctl;
> + u64 cntp_cval;
> + u64 cntv_ctl;
> + u64 cntv_cval;
> + };
> + u8 padding4[0x100];
> + };
> + union { /* 0x500 */
> + struct {
> + u64 ripas_base;
> + u64 ripas_top;
> + u8 ripas_value;
> + u8 padding8[15];
> + u64 s2ap_base;
> + u64 s2ap_top;
> + u64 vdev_id_1;
> + u64 vdev_id_2;
> + u64 dev_mem_base;
> + u64 dev_mem_top;
> + u64 dev_mem_pa;
> + };
> + u8 padding5[0x100];
> + };
> + union { /* 0x600 */
> + struct {
> + u16 imm;
> + u16 padding9;
> + u64 plane;
> + };
> + u8 padding6[0x100];
> + };
> + union { /* 0x700 */
> + struct {
> + u8 pmu_ovf_status;
> + u8 padding10[15];
> + u64 vsmmu;
> + };
> + u8 padding7[0x100];
> + };
> +};
> +
> +struct rec_run {
> + struct rec_enter enter;
> + struct rec_exit exit;
> +};
> +
> +/* RMI_RTT_UNPROT_MAP_FLAGS definitions */
> +#define RMI_RTT_UNPROT_MAP_FLAGS_OADDR_TYPE GENMASK(1, 0)
> +#define RMI_RTT_UNPROT_MAP_FLAGS_LIST_COUNT GENMASK(15, 2)
> +#define RMI_RTT_UNPROT_MAP_FLAGS_MEMATTR GENMASK(18, 16)
> +#define RMI_RTT_UNPROT_MAP_FLAGS_S2AP GENMASK(22, 19)
> +
> +/* S2AP Direct Encodings, used in RMI_RTT_UNPROT_MAP_FLAGS_S2AP */
> +#define RMI_S2AP_DIRECT_WRITE BIT(0)
> +#define RMI_S2AP_DIRECT_READ BIT(1)
> +
> +#endif /* __ASM_RMI_SMC_H */
Thanks,
Gavin
^ permalink raw reply
* Re: [PATCH 2/5] dt-bindings: connector: Add fsl,io-connector binding
From: Krzysztof Kozlowski @ 2026-05-18 7:07 UTC (permalink / raw)
To: Chancel Liu
Cc: robh@kernel.org, krzk+dt@kernel.org, conor+dt@kernel.org,
Frank Li, s.hauer@pengutronix.de, festevam@gmail.com,
mturquette@baylibre.com, sboyd@kernel.org, kernel@pengutronix.de,
devicetree@vger.kernel.org, linux-kernel@vger.kernel.org,
imx@lists.linux.dev, linux-arm-kernel@lists.infradead.org,
linux-clk@vger.kernel.org
In-Reply-To: <AM9PR04MB8353FE81D06852D45514E460E3032@AM9PR04MB8353.eurprd04.prod.outlook.com>
On 18/05/2026 06:18, Chancel Liu wrote:
>>> +description:
>>> + The NXP I/O connector represents a physically present I/O connector
>>> +on the
>>> + base board. It acts as a nexus that exposes a constrained set of
>>> +I/O
>>> + resources, such as GPIOs, clocks, PWMs and interrupts, through
>>> +fixed
>>> + electrical wiring. All actual hardware providers reside on the base board.
>>> + The connector node only defines index-based mappings to those
>> providers.
>>> +
>>> +properties:
>>> + compatible:
>>> + const: fsl,io-connector
>>
>> Everything is IO. Everything is connector, so your compatible does not match
>> requirements from writing bindings.
>>
>
> Yes, this compatible is too generic. I will rename the compatible to
> fsl,aud-io-connector.
aud is not much better. Which boards have it? What's the pinout? What's
standard? Is it described anywhere? If so, provide reference to spec/docs.
>
>>> +
>>> + gpio-controller: true
>>> +
>>> + '#gpio-cells':
>>> + const: 2
>>> +
>>> + gpio-map:
>>> + $ref: /schemas/types.yaml#/definitions/uint32-matrix
>>
>> You do not need to redefine the types. You need constraints, though.
>>
>
> OK. I will add proper constraints.
>
>>> +
>>> + gpio-map-mask:
>>> + $ref: /schemas/types.yaml#/definitions/uint32-array
>>> +
>>> + gpio-map-pass-thru:
>>> + $ref: /schemas/types.yaml#/definitions/uint32-array
>>> +
>>> + '#clock-cells':
>>> + const: 1
>>> +
>>> + clock-map:
>>> + $ref: /schemas/types.yaml#/definitions/uint32-matrix
>>> +
>>> + clock-map-mask:
>>> + $ref: /schemas/types.yaml#/definitions/uint32-array
>>> +
>>> + clock-map-pass-thru:
>>> + $ref: /schemas/types.yaml#/definitions/uint32-array
>>
>> I do not see these defined anywhere. I also checked cover letter for
>> references for pulls to dtschema.
>>
>
> Nexus nodes are already in the device-tree specification:
> https://github.com/devicetree-org/devicetree-specification/blob/v0.4/source/chapter2-devicetree-basics.rst#nexus-nodes-and-specifier-mapping
> For reference, current kernel has supported it:
> * Nexus OF support:
> commit bd6f2fd5a1d5 ("of: Support parsing phandle argument lists through a nexus node")
> * GPIO adoption:
> commit c11e6f0f04db ("gpio: Support gpio nexus dt bindings")
> * PWM adoption:
> commit e71e46a6f19c ("pwm: Add support for pwm nexus dt bindings")
> Clock adoption is ongoing:
> https://lore.kernel.org/all/20260327-schneider-v7-0-rc1-crypto-v1-10-5e6ff7853994@bootlin.com/
DT spec only mentions nexuses, but it is only a spec. Each property from
the spec must be defined in dtschema or kernel bindings.
I do not see any dependency mentioned in the cover letter, so how do you
think we can figure out where is this definition of clock nexus?
Best regards,
Krzysztof
^ permalink raw reply
* Re: [PATCH 3/4] dt-bindings: usb: add CIX Sky1 Cadence USB3 controller
From: Krzysztof Kozlowski @ 2026-05-18 7:04 UTC (permalink / raw)
To: Peter Chen
Cc: robh, krzk+dt, conor+dt, gregkh, pawell, rogerq, devicetree,
linux-kernel, linux-usb, cix-kernel-upstream, linux-arm-kernel,
arnd
In-Reply-To: <agq5eZSAZYRAuCH6@nchen-desktop>
On 18/05/2026 09:02, Peter Chen wrote:
> On 26-05-15 13:18:53, Krzysztof Kozlowski wrote:
>> EXTERNAL EMAIL
>>
>> On 15/05/2026 12:25, Peter Chen wrote:
>>> On 26-05-15 09:54:10, Krzysztof Kozlowski wrote:
>>>> EXTERNAL EMAIL
>>>>
>>>> On Mon, May 11, 2026 at 10:42:43AM +0800, Peter Chen wrote:
>>>>> Add a binding for the CIX Sky1 integration of the Cadence USBSSP DRD
>>>>> controller. The schema documents the glue register window, clocks,
>>>>> resets, interrupts and S5 system controller phandle.
>>>>>
>>>>> Signed-off-by: Peter Chen <peter.chen@cixtech.com>
>>>>> ---
>>>>> .../bindings/usb/cix,sky1-cdns3.yaml | 151 ++++++++++++++++++
>>>>
>>>> Why are you mixing USB patches with DTS in one patchset? Don't.
>>>
>>> In this series, the 1st patch is the IP core driver changes (export APIs for glue layer
>>> use), and the second glue layer patch is the user for new adding APIs.
>>
>>
>> Not really answer to my question. Why is DTS here? It has nothing to do
>> with 1st patch, second patch or this one.
>>
>
> Per submitting-patches.rst I.7, the DTS was placed at the end of the
> series so either maintainer can apply their portion. That said, if
> you prefer I can split it into a separate series, I have no strong
> option.
Don't mix DTS with USB patchset.
Best regards,
Krzysztof
^ permalink raw reply
* Re: [PATCH 3/4] dt-bindings: usb: add CIX Sky1 Cadence USB3 controller
From: Peter Chen @ 2026-05-18 7:02 UTC (permalink / raw)
To: Krzysztof Kozlowski
Cc: robh, krzk+dt, conor+dt, gregkh, pawell, rogerq, devicetree,
linux-kernel, linux-usb, cix-kernel-upstream, linux-arm-kernel,
arnd
In-Reply-To: <ccc8ab6c-d301-4585-8be3-1977485c5e87@kernel.org>
On 26-05-15 13:18:53, Krzysztof Kozlowski wrote:
> EXTERNAL EMAIL
>
> On 15/05/2026 12:25, Peter Chen wrote:
> > On 26-05-15 09:54:10, Krzysztof Kozlowski wrote:
> >> EXTERNAL EMAIL
> >>
> >> On Mon, May 11, 2026 at 10:42:43AM +0800, Peter Chen wrote:
> >>> Add a binding for the CIX Sky1 integration of the Cadence USBSSP DRD
> >>> controller. The schema documents the glue register window, clocks,
> >>> resets, interrupts and S5 system controller phandle.
> >>>
> >>> Signed-off-by: Peter Chen <peter.chen@cixtech.com>
> >>> ---
> >>> .../bindings/usb/cix,sky1-cdns3.yaml | 151 ++++++++++++++++++
> >>
> >> Why are you mixing USB patches with DTS in one patchset? Don't.
> >
> > In this series, the 1st patch is the IP core driver changes (export APIs for glue layer
> > use), and the second glue layer patch is the user for new adding APIs.
>
>
> Not really answer to my question. Why is DTS here? It has nothing to do
> with 1st patch, second patch or this one.
>
Per submitting-patches.rst I.7, the DTS was placed at the end of the
series so either maintainer can apply their portion. That said, if
you prefer I can split it into a separate series, I have no strong
option.
--
Best regards,
Peter
^ permalink raw reply
* Re: [PATCH] clk: clk-imx8mm: Initialize clocks in arch_initcall
From: Abel Vesa @ 2026-05-18 7:02 UTC (permalink / raw)
To: Paul Geurts
Cc: Ahmad Fatoum, Martijn de Gouw, Saravana Kannan,
abelvesa@kernel.org, peng.fan@nxp.com, mturquette@baylibre.com,
sboyd@kernel.org, Frank.Li@nxp.com, s.hauer@pengutronix.de,
kernel@pengutronix.de, festevam@gmail.com, shawnguo@kernel.org,
linux-clk@vger.kernel.org, imx@lists.linux.dev,
linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org
In-Reply-To: <GVXPR02MB109689E26A9BAE94C2BAA34FDBD2C2@GVXPR02MB10968.eurprd02.prod.outlook.com>
On 26-04-21 12:00:43, Paul Geurts wrote:
> > Hello Paul,
> >
> > Cc += Saravana
> >
> > On 4/9/26 11:16 AM, Paul Geurts wrote:
> >>> Hello Paul,
> >>>
> >>> On 4/8/26 12:13 PM, Paul Geurts wrote:
> >>>> The i.MX8MM clock driver is implemented as module_platform_driver();,
> >>>> which makes it initialize in device_initcall(). This means that all
> >>>> drivers referencing the clock driver nodes in the device tree are
> >>>> deferred by fw_devlink, which are most of the i.MX8M platform drivers.
> >>>>
> >>>> Explicitly initialize the clock driver in arch_initcall(), to make sure
> >>>> the clock driver is ready when the rest of the drivers are probed.
> >>>>
> >>>> Fixes: af7e7ee0e428 ("clk: imx8mm: Switch to platform driver")
> >>>
> >>> Your commit message doesn't explain why this was a problem for you.
> >>> Does it delay your boot? What makes this patch a fix?
> >>
> >> Yes I could update that in the commit description. The problem is that because
> >> of this, _all_ hardware is initialized in late_initcall, as that is where
> >> deferred probes are handled.
> >
> > There's no one initcall order that will make drivers across all systems
> > equally happy. That's why there are probe deferrals in the first place.
>
> I understand. But this order makes all i.MX systems equally unhappy :-P.
>
> >
> >> For embedded devices, some sign of life is
> >> expected by most people during boot. Especially when an initrd needs to be
> >> unpacked, this sign of life is going to take a very long time.
> >
> > Ok, so the problem is that the probes happen too late. Does the total
> > boot time take considerably longer or are you just unhappy with the
> > ordering?
>
> Both. It takes longer, and interfaces I would expect to be live "early" are very late.
>
> >
> >> Some display
> >> controllers don't even get enough time to show the boot logo because of this.
> >> I don't think the idea behind the initcall levels is that _everything_ is
> >> initialized in late.
> >
> > I suspect we could improve the situation with "post-init-providers"
> > hints, but I haven't used it myself so far.
> > Maybe Saravana could give some advice once the problem is better understood?
>
> I could look into this, thanks!
>
> >
> >>> What happens if you build the driver as module with your changes applied?
> >>
> >> On module insertion, there is no initcall level, and initialization is
> >> performed on insertion (AFAIK). Fact is that the system would probably
> >> not boot when this is built as a module, as there are no peripheral clocks
> >> without it.
> >
> > Ok, then this is patch is not acceptable. What's buildable as module
> > should work as module. I don't personally build it as module either, but
> > removing the possibility will break users relying on it for Android GKI,
> > I presume.
>
> This patch doesn't change anything about whether the driver is usable as
> a module. I think the original driver is already not useable as a module,
> independent of this patch.
What? Why is it not usable as a module?
^ permalink raw reply
* Re: [PATCH] clk: clk-imx8mm: Initialize clocks in arch_initcall
From: Abel Vesa @ 2026-05-18 6:58 UTC (permalink / raw)
To: Paul Geurts
Cc: abelvesa@kernel.org, peng.fan@nxp.com, mturquette@baylibre.com,
sboyd@kernel.org, Frank.Li@nxp.com, s.hauer@pengutronix.de,
kernel@pengutronix.de, festevam@gmail.com, shawnguo@kernel.org,
linux-clk@vger.kernel.org, imx@lists.linux.dev,
linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org, Martijn de Gouw
In-Reply-To: <GVXPR02MB109688D7C86DC2A63D8BA146FBD2C2@GVXPR02MB10968.eurprd02.prod.outlook.com>
On 26-04-21 11:14:27, Paul Geurts wrote:
> > On 26-04-08 12:13:13, Paul Geurts wrote:
> >> The i.MX8MM clock driver is implemented as module_platform_driver();,
> >> which makes it initialize in device_initcall(). This means that all
> >> drivers referencing the clock driver nodes in the device tree are
> >> deferred by fw_devlink, which are most of the i.MX8M platform drivers.
> >>
> >> Explicitly initialize the clock driver in arch_initcall(), to make sure
> >> the clock driver is ready when the rest of the drivers are probed.
> >>
> >> Fixes: af7e7ee0e428 ("clk: imx8mm: Switch to platform driver")
> >> Signed-off-by: Paul Geurts <paul.geurts@prodrive-technologies.com>
> >
> > Nack.
> >
> > Nothing wrong with probe deferring. It is there to ensure the order
> > the drivers probe in is correct.
> >
> > Plus, moving it to arch_initcall won't solve anything.
> I disagree, as it solves a _lot_ on my setup. But I think the next section
> explains it better.
Nope. If your setup has issues with the clock controller not probing
early enough, then your setup isn't following the upstream model.
Please describe exactly what are the issues with your setup. Maybe we
can find a proper solution.
>
> >
> > fw_devlink will not stop the driver from probing if there is no provider
> > that this driver is waiting for. And if there is a provider that is
> > needed by this clock controller, moving it to arch_initcall won't
> > magically skip waiting for the provider anyway.
> I think you have the issue backwards. There is no provider that is needed
> by the clock controller. The clock controller is needed by everything else.
> So the clock controller is not deferred. All other things are deferred because
> of the clock controller.
>
> I understand that probe deferring is not there for nothing. But I would also
> argue that the initcall levels are also not there for nothing. IMO a chip
> clock controller is an architecture driver, and belongs in arch_. Whether this
> is the correct way to do it, or whether this driver should be able to be
> compiled as a module is a separate discussion.
By the looks of it, you are obviously confusing terms here. A clock
controller is never an "architecture driver" and it definitely doesn't
"belong in arch_". A clock controller is most of the time a platform
driver. There is a big difference.
^ permalink raw reply
* [PATCH 10/18] raid6: rework registration of optimized algorithms
From: Christoph Hellwig @ 2026-05-18 5:17 UTC (permalink / raw)
To: Andrew Morton
Cc: Catalin Marinas, Will Deacon, Ard Biesheuvel, Huacai Chen,
WANG Xuerui, Madhavan Srinivasan, Michael Ellerman,
Nicholas Piggin, Christophe Leroy (CS GROUP), Paul Walmsley,
Palmer Dabbelt, Albert Ou, Alexandre Ghiti, Heiko Carstens,
Vasily Gorbik, Alexander Gordeev, Christian Borntraeger,
Sven Schnelle, Thomas Gleixner, Ingo Molnar, Borislav Petkov,
Dave Hansen, x86, H. Peter Anvin, Herbert Xu, Dan Williams,
Chris Mason, David Sterba, Arnd Bergmann, Song Liu, Yu Kuai,
Li Nan, linux-kernel, linux-arm-kernel, loongarch, linuxppc-dev,
linux-riscv, linux-s390, linux-crypto, linux-btrfs, linux-arch,
linux-raid
In-Reply-To: <20260518051804.462141-1-hch@lst.de>
Replace the static array of algorithms with a call to an architecture
helper to register algorithms. This serves two purposes: it avoid
having to register all algorithms in a single central place, and it
removes the need for the priority field by just registering the
algorithms that the architecture considers suitable for the currently
running CPUs.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Acked-by: Ard Biesheuvel <ardb@kernel.org>
Tested-by: Ard Biesheuvel <ardb@kernel.org> # kunit only on arm64
---
lib/raid/Kconfig | 11 +
lib/raid/raid6/Makefile | 4 +
lib/raid/raid6/algos.c | 303 ++++++++----------
lib/raid/raid6/algos.h | 67 +---
lib/raid/raid6/arm/neon.c | 6 -
lib/raid/raid6/arm/pq_arch.h | 21 ++
lib/raid/raid6/arm/recov_neon.c | 7 -
lib/raid/raid6/arm64/pq_arch.h | 1 +
lib/raid/raid6/loongarch/loongarch_simd.c | 12 -
lib/raid/raid6/loongarch/pq_arch.h | 23 ++
.../raid6/loongarch/recov_loongarch_simd.c | 14 -
lib/raid/raid6/powerpc/altivec.uc | 10 -
lib/raid/raid6/powerpc/pq_arch.h | 32 ++
lib/raid/raid6/powerpc/vpermxor.uc | 11 -
lib/raid/raid6/recov.c | 2 -
lib/raid/raid6/riscv/pq_arch.h | 21 ++
lib/raid/raid6/riscv/recov_rvv.c | 2 -
lib/raid/raid6/riscv/rvv.h | 6 -
lib/raid/raid6/s390/pq_arch.h | 15 +
lib/raid/raid6/s390/recov_s390xc.c | 2 -
lib/raid/raid6/s390/s390vx.uc | 7 -
lib/raid/raid6/tests/raid6_kunit.c | 23 +-
lib/raid/raid6/x86/avx2.c | 14 -
lib/raid/raid6/x86/avx512.c | 19 --
lib/raid/raid6/x86/mmx.c | 8 -
lib/raid/raid6/x86/pq_arch.h | 96 ++++++
lib/raid/raid6/x86/recov_avx2.c | 8 -
lib/raid/raid6/x86/recov_avx512.c | 12 -
lib/raid/raid6/x86/recov_ssse3.c | 9 -
lib/raid/raid6/x86/sse1.c | 12 -
lib/raid/raid6/x86/sse2.c | 15 -
31 files changed, 384 insertions(+), 409 deletions(-)
create mode 100644 lib/raid/raid6/arm/pq_arch.h
create mode 100644 lib/raid/raid6/arm64/pq_arch.h
create mode 100644 lib/raid/raid6/loongarch/pq_arch.h
create mode 100644 lib/raid/raid6/powerpc/pq_arch.h
create mode 100644 lib/raid/raid6/riscv/pq_arch.h
create mode 100644 lib/raid/raid6/s390/pq_arch.h
create mode 100644 lib/raid/raid6/x86/pq_arch.h
diff --git a/lib/raid/Kconfig b/lib/raid/Kconfig
index e39f6d667792..978cd6ba08ac 100644
--- a/lib/raid/Kconfig
+++ b/lib/raid/Kconfig
@@ -32,6 +32,17 @@ config XOR_KUNIT_TEST
config RAID6_PQ
tristate
+# selected by architectures that provide an optimized PQ implementation
+config RAID6_PQ_ARCH
+ depends on RAID6_PQ
+ default y if KERNEL_MODE_NEON # arm32/arm64
+ default y if LOONGARCH
+ default y if ALTIVEC # powerpc
+ default y if RISCV_ISA_V
+ default y if S390
+ default y if X86
+ bool
+
config RAID6_PQ_KUNIT_TEST
tristate "KUnit tests for RAID6 PQ functions" if !KUNIT_ALL_TESTS
depends on KUNIT
diff --git a/lib/raid/raid6/Makefile b/lib/raid/raid6/Makefile
index 90de3dce152e..1d79b76b320e 100644
--- a/lib/raid/raid6/Makefile
+++ b/lib/raid/raid6/Makefile
@@ -4,6 +4,10 @@ ccflags-y += -I $(src)
ccflags-y += -I $(src)
+ifeq ($(CONFIG_RAID6_PQ_ARCH),y)
+CFLAGS_algos.o += -I$(src)/$(SRCARCH)
+endif
+
obj-$(CONFIG_RAID6_PQ) += raid6_pq.o tests/
raid6_pq-y += algos.o tables.o
diff --git a/lib/raid/raid6/algos.c b/lib/raid/raid6/algos.c
index d83ca4dac864..30d7cb34874f 100644
--- a/lib/raid/raid6/algos.c
+++ b/lib/raid/raid6/algos.c
@@ -17,6 +17,9 @@
#include <kunit/visibility.h>
#include "algos.h"
+#define RAID6_MAX_ALGOS 16
+static const struct raid6_calls *raid6_algos[RAID6_MAX_ALGOS];
+static unsigned int raid6_nr_algos;
static const struct raid6_recov_calls *raid6_recov_algo;
/* Selected algorithm */
@@ -97,71 +100,6 @@ bool raid6_can_xor_syndrome(void)
}
EXPORT_SYMBOL_GPL(raid6_can_xor_syndrome);
-const struct raid6_calls * const raid6_algos[] = {
-#if defined(__i386__) && !defined(__arch_um__)
- &raid6_avx512x2,
- &raid6_avx512x1,
- &raid6_avx2x2,
- &raid6_avx2x1,
- &raid6_sse2x2,
- &raid6_sse2x1,
- &raid6_sse1x2,
- &raid6_sse1x1,
- &raid6_mmxx2,
- &raid6_mmxx1,
-#endif
-#if defined(__x86_64__) && !defined(__arch_um__)
- &raid6_avx512x4,
- &raid6_avx512x2,
- &raid6_avx512x1,
- &raid6_avx2x4,
- &raid6_avx2x2,
- &raid6_avx2x1,
- &raid6_sse2x4,
- &raid6_sse2x2,
- &raid6_sse2x1,
-#endif
-#ifdef CONFIG_ALTIVEC
- &raid6_vpermxor8,
- &raid6_vpermxor4,
- &raid6_vpermxor2,
- &raid6_vpermxor1,
- &raid6_altivec8,
- &raid6_altivec4,
- &raid6_altivec2,
- &raid6_altivec1,
-#endif
-#if defined(CONFIG_S390)
- &raid6_s390vx8,
-#endif
-#ifdef CONFIG_KERNEL_MODE_NEON
- &raid6_neonx8,
- &raid6_neonx4,
- &raid6_neonx2,
- &raid6_neonx1,
-#endif
-#ifdef CONFIG_LOONGARCH
-#ifdef CONFIG_CPU_HAS_LASX
- &raid6_lasx,
-#endif
-#ifdef CONFIG_CPU_HAS_LSX
- &raid6_lsx,
-#endif
-#endif
-#ifdef CONFIG_RISCV_ISA_V
- &raid6_rvvx1,
- &raid6_rvvx2,
- &raid6_rvvx4,
- &raid6_rvvx8,
-#endif
- &raid6_intx8,
- &raid6_intx4,
- &raid6_intx2,
- &raid6_intx1,
- NULL
-};
-EXPORT_SYMBOL_IF_KUNIT(raid6_algos);
-
/**
* raid6_recov_2data - recover two missing data disks
* @disks: number of "disks" to operate on including parity
@@ -215,119 +153,57 @@ void raid6_recov_datap(int disks, size_t bytes, int faila, void **ptrs)
}
EXPORT_SYMBOL_GPL(raid6_recov_datap);
-const struct raid6_recov_calls *const raid6_recov_algos[] = {
-#ifdef CONFIG_X86
- &raid6_recov_avx512,
- &raid6_recov_avx2,
- &raid6_recov_ssse3,
-#endif
-#ifdef CONFIG_S390
- &raid6_recov_s390xc,
-#endif
-#if defined(CONFIG_KERNEL_MODE_NEON)
- &raid6_recov_neon,
-#endif
-#ifdef CONFIG_LOONGARCH
-#ifdef CONFIG_CPU_HAS_LASX
- &raid6_recov_lasx,
-#endif
-#ifdef CONFIG_CPU_HAS_LSX
- &raid6_recov_lsx,
-#endif
-#endif
-#ifdef CONFIG_RISCV_ISA_V
- &raid6_recov_rvv,
-#endif
- &raid6_recov_intx1,
- NULL
-};
-EXPORT_SYMBOL_IF_KUNIT(raid6_recov_algos);
-
#define RAID6_TIME_JIFFIES_LG2 4
#define RAID6_TEST_DISKS 8
#define RAID6_TEST_DISKS_ORDER 3
-static inline const struct raid6_recov_calls *raid6_choose_recov(void)
+static int raid6_choose_gen(void *(*const dptrs)[RAID6_TEST_DISKS],
+ const int disks)
{
- const struct raid6_recov_calls *const *algo;
- const struct raid6_recov_calls *best;
-
- for (best = NULL, algo = raid6_recov_algos; *algo; algo++)
- if (!best || (*algo)->priority > best->priority)
- if (!(*algo)->valid || (*algo)->valid())
- best = *algo;
+ /* work on the second half of the disks */
+ int start = (disks >> 1) - 1, stop = disks - 3;
+ const struct raid6_calls *best = NULL;
+ unsigned long bestgenperf = 0;
+ unsigned int i;
- if (best) {
- raid6_recov_algo = best;
+ for (i = 0; i < raid6_nr_algos; i++) {
+ const struct raid6_calls *algo = raid6_algos[i];
+ unsigned long perf = 0, j0, j1;
- pr_info("raid6: using %s recovery algorithm\n", best->name);
- } else
- pr_err("raid6: Yikes! No recovery algorithm found!\n");
-
- return best;
-}
+ preempt_disable();
+ j0 = jiffies;
+ while ((j1 = jiffies) == j0)
+ cpu_relax();
+ while (time_before(jiffies,
+ j1 + (1<<RAID6_TIME_JIFFIES_LG2))) {
+ algo->gen_syndrome(disks, PAGE_SIZE, *dptrs);
+ perf++;
+ }
+ preempt_enable();
-static inline const struct raid6_calls *raid6_choose_gen(
- void *(*const dptrs)[RAID6_TEST_DISKS], const int disks)
-{
- unsigned long perf, bestgenperf, j0, j1;
- int start = (disks>>1)-1, stop = disks-3; /* work on the second half of the disks */
- const struct raid6_calls *const *algo;
- const struct raid6_calls *best;
-
- for (bestgenperf = 0, best = NULL, algo = raid6_algos; *algo; algo++) {
- if (!best || (*algo)->priority >= best->priority) {
- if ((*algo)->valid && !(*algo)->valid())
- continue;
-
- if (!IS_ENABLED(CONFIG_RAID6_PQ_BENCHMARK)) {
- best = *algo;
- break;
- }
-
- perf = 0;
-
- preempt_disable();
- j0 = jiffies;
- while ((j1 = jiffies) == j0)
- cpu_relax();
- while (time_before(jiffies,
- j1 + (1<<RAID6_TIME_JIFFIES_LG2))) {
- (*algo)->gen_syndrome(disks, PAGE_SIZE, *dptrs);
- perf++;
- }
- preempt_enable();
-
- if (perf > bestgenperf) {
- bestgenperf = perf;
- best = *algo;
- }
- pr_info("raid6: %-8s gen() %5ld MB/s\n", (*algo)->name,
- (perf * HZ * (disks-2)) >>
- (20 - PAGE_SHIFT + RAID6_TIME_JIFFIES_LG2));
+ if (perf > bestgenperf) {
+ bestgenperf = perf;
+ best = algo;
}
+ pr_info("raid6: %-8s gen() %5ld MB/s\n", algo->name,
+ (perf * HZ * (disks-2)) >>
+ (20 - PAGE_SHIFT + RAID6_TIME_JIFFIES_LG2));
}
if (!best) {
pr_err("raid6: Yikes! No algorithm found!\n");
- goto out;
+ return -EINVAL;
}
raid6_call = *best;
- if (!IS_ENABLED(CONFIG_RAID6_PQ_BENCHMARK)) {
- pr_info("raid6: skipped pq benchmark and selected %s\n",
- best->name);
- goto out;
- }
-
pr_info("raid6: using algorithm %s gen() %ld MB/s\n",
best->name,
(bestgenperf * HZ * (disks - 2)) >>
(20 - PAGE_SHIFT + RAID6_TIME_JIFFIES_LG2));
if (best->xor_syndrome) {
- perf = 0;
+ unsigned long perf = 0, j0, j1;
preempt_disable();
j0 = jiffies;
@@ -346,8 +222,7 @@ static inline const struct raid6_calls *raid6_choose_gen(
(20 - PAGE_SHIFT + RAID6_TIME_JIFFIES_LG2 + 1));
}
-out:
- return best;
+ return 0;
}
@@ -357,12 +232,17 @@ static inline const struct raid6_calls *raid6_choose_gen(
static int __init raid6_select_algo(void)
{
const int disks = RAID6_TEST_DISKS;
-
- const struct raid6_calls *gen_best;
- const struct raid6_recov_calls *rec_best;
char *disk_ptr, *p;
void *dptrs[RAID6_TEST_DISKS];
int i, cycle;
+ int error;
+
+ if (!IS_ENABLED(CONFIG_RAID6_PQ_BENCHMARK) || raid6_nr_algos == 1) {
+ pr_info("raid6: skipped pq benchmark and selected %s\n",
+ raid6_algos[raid6_nr_algos - 1]->name);
+ raid6_call = *raid6_algos[raid6_nr_algos - 1];
+ return 0;
+ }
/* prepare the buffer and fill it circularly with gfmul table */
disk_ptr = (char *)__get_free_pages(GFP_KERNEL, RAID6_TEST_DISKS_ORDER);
@@ -385,22 +265,109 @@ static int __init raid6_select_algo(void)
memcpy(p, raid6_gfmul, (disks - 2) * PAGE_SIZE % 65536);
/* select raid gen_syndrome function */
- gen_best = raid6_choose_gen(&dptrs, disks);
-
- /* select raid recover functions */
- rec_best = raid6_choose_recov();
+ error = raid6_choose_gen(&dptrs, disks);
free_pages((unsigned long)disk_ptr, RAID6_TEST_DISKS_ORDER);
- return gen_best && rec_best ? 0 : -EINVAL;
+ return error;
}
-static void raid6_exit(void)
+/*
+ * Register a RAID6 P/Q generation algorithm. The most optimized/unrolled
+ * implementation should be registered last so it will be selected when the
+ * boot-time benchmark is disabled.
+ */
+void __init raid6_algo_add(const struct raid6_calls *algo)
{
- do { } while (0);
+ if (WARN_ON_ONCE(raid6_nr_algos == RAID6_MAX_ALGOS))
+ return;
+ raid6_algos[raid6_nr_algos++] = algo;
}
-subsys_initcall(raid6_select_algo);
+void __init raid6_algo_add_default(void)
+{
+ raid6_algo_add(&raid6_intx1);
+ raid6_algo_add(&raid6_intx2);
+ raid6_algo_add(&raid6_intx4);
+ raid6_algo_add(&raid6_intx8);
+}
+
+void __init raid6_recov_algo_add(const struct raid6_recov_calls *algo)
+{
+ if (WARN_ON_ONCE(raid6_recov_algo))
+ return;
+ raid6_recov_algo = algo;
+}
+
+#ifdef CONFIG_RAID6_PQ_ARCH
+#include "pq_arch.h"
+#else
+static inline void arch_raid6_init(void)
+{
+ raid6_algo_add_default();
+}
+#endif /* CONFIG_RAID6_PQ_ARCH */
+
+static int __init raid6_init(void)
+{
+ /*
+ * Architectures providing arch_raid6_init must add all PQ generation
+ * algorithms they want to consider in arch_raid6_init(), including
+ * the generic ones using raid6_algo_add_default() if wanted.
+ */
+ arch_raid6_init();
+
+ /*
+ * Architectures don't have to set a recovery algorithm, we'll just pick
+ * the generic integer one if none was set.
+ */
+ if (!raid6_recov_algo)
+ raid6_recov_algo = &raid6_recov_intx1;
+ pr_info("raid6: using %s recovery algorithm\n", raid6_recov_algo->name);
+
+ return raid6_select_algo();
+}
+
+static void __exit raid6_exit(void)
+{
+}
+
+subsys_initcall(raid6_init);
module_exit(raid6_exit);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("RAID6 Q-syndrome calculations");
+
+#if IS_ENABLED(CONFIG_RAID6_PQ_KUNIT_TEST)
+const struct raid6_calls *raid6_algo_find(unsigned int idx)
+{
+ if (idx >= raid6_nr_algos) {
+ /*
+ * Always include the simplest generic integer implementation in
+ * the unit tests as a baseline.
+ */
+ if (idx == raid6_nr_algos &&
+ raid6_algos[0] != &raid6_intx1)
+ return &raid6_intx1;
+ return NULL;
+ }
+ return raid6_algos[idx];
+}
+EXPORT_SYMBOL_IF_KUNIT(raid6_algo_find);
+
+const struct raid6_recov_calls *raid6_recov_algo_find(unsigned int idx)
+{
+ switch (idx) {
+ case 0:
+ /* always test the generic integer implementation */
+ return &raid6_recov_intx1;
+ case 1:
+ /* test the optimized implementation if there is one */
+ if (raid6_recov_algo != &raid6_recov_intx1)
+ return raid6_recov_algo;
+ return NULL;
+ default:
+ return NULL;
+ }
+}
+EXPORT_SYMBOL_IF_KUNIT(raid6_recov_algo_find);
+#endif /* CONFIG_RAID6_PQ_KUNIT_TEST */
diff --git a/lib/raid/raid6/algos.h b/lib/raid/raid6/algos.h
index e5f1098d2179..43f636be183f 100644
--- a/lib/raid/raid6/algos.h
+++ b/lib/raid/raid6/algos.h
@@ -5,6 +5,7 @@
#ifndef _PQ_IMPL_H
#define _PQ_IMPL_H
+#include <linux/init.h>
#include <linux/raid/pq_tables.h>
/* Routine choices */
@@ -13,70 +14,28 @@ struct raid6_calls {
void (*gen_syndrome)(int disks, size_t bytes, void **ptrs);
void (*xor_syndrome)(int disks, int start, int stop, size_t bytes,
void **ptrs);
- int (*valid)(void); /* Returns 1 if this routine set is usable */
- int priority; /* Relative priority ranking if non-zero */
};
-/* Various routine sets */
-extern const struct raid6_calls raid6_intx1;
-extern const struct raid6_calls raid6_intx2;
-extern const struct raid6_calls raid6_intx4;
-extern const struct raid6_calls raid6_intx8;
-extern const struct raid6_calls raid6_mmxx1;
-extern const struct raid6_calls raid6_mmxx2;
-extern const struct raid6_calls raid6_sse1x1;
-extern const struct raid6_calls raid6_sse1x2;
-extern const struct raid6_calls raid6_sse2x1;
-extern const struct raid6_calls raid6_sse2x2;
-extern const struct raid6_calls raid6_sse2x4;
-extern const struct raid6_calls raid6_altivec1;
-extern const struct raid6_calls raid6_altivec2;
-extern const struct raid6_calls raid6_altivec4;
-extern const struct raid6_calls raid6_altivec8;
-extern const struct raid6_calls raid6_avx2x1;
-extern const struct raid6_calls raid6_avx2x2;
-extern const struct raid6_calls raid6_avx2x4;
-extern const struct raid6_calls raid6_avx512x1;
-extern const struct raid6_calls raid6_avx512x2;
-extern const struct raid6_calls raid6_avx512x4;
-extern const struct raid6_calls raid6_s390vx8;
-extern const struct raid6_calls raid6_vpermxor1;
-extern const struct raid6_calls raid6_vpermxor2;
-extern const struct raid6_calls raid6_vpermxor4;
-extern const struct raid6_calls raid6_vpermxor8;
-extern const struct raid6_calls raid6_lsx;
-extern const struct raid6_calls raid6_lasx;
-extern const struct raid6_calls raid6_rvvx1;
-extern const struct raid6_calls raid6_rvvx2;
-extern const struct raid6_calls raid6_rvvx4;
-extern const struct raid6_calls raid6_rvvx8;
-
struct raid6_recov_calls {
const char *name;
void (*data2)(int disks, size_t bytes, int faila, int failb,
void **ptrs);
void (*datap)(int disks, size_t bytes, int faila, void **ptrs);
- int (*valid)(void);
- int priority;
};
-extern const struct raid6_recov_calls raid6_recov_intx1;
-extern const struct raid6_recov_calls raid6_recov_ssse3;
-extern const struct raid6_recov_calls raid6_recov_avx2;
-extern const struct raid6_recov_calls raid6_recov_avx512;
-extern const struct raid6_recov_calls raid6_recov_s390xc;
-extern const struct raid6_recov_calls raid6_recov_neon;
-extern const struct raid6_recov_calls raid6_recov_lsx;
-extern const struct raid6_recov_calls raid6_recov_lasx;
-extern const struct raid6_recov_calls raid6_recov_rvv;
+void __init raid6_algo_add(const struct raid6_calls *algo);
+void __init raid6_algo_add_default(void);
+void __init raid6_recov_algo_add(const struct raid6_recov_calls *algo);
-extern const struct raid6_calls raid6_neonx1;
-extern const struct raid6_calls raid6_neonx2;
-extern const struct raid6_calls raid6_neonx4;
-extern const struct raid6_calls raid6_neonx8;
+/* for the kunit test */
+const struct raid6_calls *raid6_algo_find(unsigned int idx);
+const struct raid6_recov_calls *raid6_recov_algo_find(unsigned int idx);
-/* Algorithm list */
-extern const struct raid6_calls * const raid6_algos[];
-extern const struct raid6_recov_calls *const raid6_recov_algos[];
+/* generic implementations */
+extern const struct raid6_calls raid6_intx1;
+extern const struct raid6_calls raid6_intx2;
+extern const struct raid6_calls raid6_intx4;
+extern const struct raid6_calls raid6_intx8;
+extern const struct raid6_recov_calls raid6_recov_intx1;
#endif /* _PQ_IMPL_H */
diff --git a/lib/raid/raid6/arm/neon.c b/lib/raid/raid6/arm/neon.c
index bd4ec4c86ee8..341c61af675e 100644
--- a/lib/raid/raid6/arm/neon.c
+++ b/lib/raid/raid6/arm/neon.c
@@ -42,15 +42,9 @@
struct raid6_calls const raid6_neonx ## _n = { \
.gen_syndrome = raid6_neon ## _n ## _gen_syndrome, \
.xor_syndrome = raid6_neon ## _n ## _xor_syndrome, \
- .valid = raid6_have_neon, \
.name = "neonx" #_n, \
}
-static int raid6_have_neon(void)
-{
- return cpu_has_neon();
-}
-
RAID6_NEON_WRAPPER(1);
RAID6_NEON_WRAPPER(2);
RAID6_NEON_WRAPPER(4);
diff --git a/lib/raid/raid6/arm/pq_arch.h b/lib/raid/raid6/arm/pq_arch.h
new file mode 100644
index 000000000000..3f876ea6749c
--- /dev/null
+++ b/lib/raid/raid6/arm/pq_arch.h
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include <asm/neon.h>
+
+extern const struct raid6_calls raid6_neonx1;
+extern const struct raid6_calls raid6_neonx2;
+extern const struct raid6_calls raid6_neonx4;
+extern const struct raid6_calls raid6_neonx8;
+extern const struct raid6_recov_calls raid6_recov_neon;
+
+static __always_inline void __init arch_raid6_init(void)
+{
+ raid6_algo_add_default();
+ if (cpu_has_neon()) {
+ raid6_algo_add(&raid6_neonx1);
+ raid6_algo_add(&raid6_neonx2);
+ raid6_algo_add(&raid6_neonx4);
+ raid6_algo_add(&raid6_neonx8);
+ raid6_recov_algo_add(&raid6_recov_neon);
+ }
+}
diff --git a/lib/raid/raid6/arm/recov_neon.c b/lib/raid/raid6/arm/recov_neon.c
index e1d1d19fc9a8..1524050d09b7 100644
--- a/lib/raid/raid6/arm/recov_neon.c
+++ b/lib/raid/raid6/arm/recov_neon.c
@@ -10,11 +10,6 @@
#include "algos.h"
#include "arm/neon.h"
-static int raid6_has_neon(void)
-{
- return cpu_has_neon();
-}
-
static void raid6_2data_recov_neon(int disks, size_t bytes, int faila,
int failb, void **ptrs)
{
@@ -87,7 +82,5 @@ static void raid6_datap_recov_neon(int disks, size_t bytes, int faila,
const struct raid6_recov_calls raid6_recov_neon = {
.data2 = raid6_2data_recov_neon,
.datap = raid6_datap_recov_neon,
- .valid = raid6_has_neon,
.name = "neon",
- .priority = 10,
};
diff --git a/lib/raid/raid6/arm64/pq_arch.h b/lib/raid/raid6/arm64/pq_arch.h
new file mode 100644
index 000000000000..27ff564d7594
--- /dev/null
+++ b/lib/raid/raid6/arm64/pq_arch.h
@@ -0,0 +1 @@
+#include "arm/pq_arch.h"
diff --git a/lib/raid/raid6/loongarch/loongarch_simd.c b/lib/raid/raid6/loongarch/loongarch_simd.c
index f77d11ce676e..c1eb53fafd27 100644
--- a/lib/raid/raid6/loongarch/loongarch_simd.c
+++ b/lib/raid/raid6/loongarch/loongarch_simd.c
@@ -26,11 +26,6 @@
#ifdef CONFIG_CPU_HAS_LSX
#define NSIZE 16
-static int raid6_has_lsx(void)
-{
- return cpu_has_lsx;
-}
-
static void raid6_lsx_gen_syndrome(int disks, size_t bytes, void **ptrs)
{
u8 **dptr = (u8 **)ptrs;
@@ -246,7 +241,6 @@ static void raid6_lsx_xor_syndrome(int disks, int start, int stop,
const struct raid6_calls raid6_lsx = {
.gen_syndrome = raid6_lsx_gen_syndrome,
.xor_syndrome = raid6_lsx_xor_syndrome,
- .valid = raid6_has_lsx,
.name = "lsx",
};
@@ -256,11 +250,6 @@ const struct raid6_calls raid6_lsx = {
#ifdef CONFIG_CPU_HAS_LASX
#define NSIZE 32
-static int raid6_has_lasx(void)
-{
- return cpu_has_lasx;
-}
-
static void raid6_lasx_gen_syndrome(int disks, size_t bytes, void **ptrs)
{
u8 **dptr = (u8 **)ptrs;
@@ -414,7 +403,6 @@ static void raid6_lasx_xor_syndrome(int disks, int start, int stop,
const struct raid6_calls raid6_lasx = {
.gen_syndrome = raid6_lasx_gen_syndrome,
.xor_syndrome = raid6_lasx_xor_syndrome,
- .valid = raid6_has_lasx,
.name = "lasx",
};
#undef NSIZE
diff --git a/lib/raid/raid6/loongarch/pq_arch.h b/lib/raid/raid6/loongarch/pq_arch.h
new file mode 100644
index 000000000000..ae443a4d7b69
--- /dev/null
+++ b/lib/raid/raid6/loongarch/pq_arch.h
@@ -0,0 +1,23 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include <asm/cpu-features.h>
+
+extern const struct raid6_calls raid6_lsx;
+extern const struct raid6_calls raid6_lasx;
+
+extern const struct raid6_recov_calls raid6_recov_lsx;
+extern const struct raid6_recov_calls raid6_recov_lasx;
+
+static __always_inline void __init arch_raid6_init(void)
+{
+ raid6_algo_add_default();
+ if (IS_ENABLED(CONFIG_CPU_HAS_LSX) && cpu_has_lsx)
+ raid6_algo_add(&raid6_lsx);
+ if (IS_ENABLED(CONFIG_CPU_HAS_LASX) && cpu_has_lasx)
+ raid6_algo_add(&raid6_lasx);
+
+ if (IS_ENABLED(CONFIG_CPU_HAS_LASX) && cpu_has_lasx)
+ raid6_recov_algo_add(&raid6_recov_lasx);
+ else if (IS_ENABLED(CONFIG_CPU_HAS_LSX) && cpu_has_lsx)
+ raid6_recov_algo_add(&raid6_recov_lsx);
+}
diff --git a/lib/raid/raid6/loongarch/recov_loongarch_simd.c b/lib/raid/raid6/loongarch/recov_loongarch_simd.c
index 0bbdc8b5c2e7..87a2313bbb4f 100644
--- a/lib/raid/raid6/loongarch/recov_loongarch_simd.c
+++ b/lib/raid/raid6/loongarch/recov_loongarch_simd.c
@@ -24,11 +24,6 @@
*/
#ifdef CONFIG_CPU_HAS_LSX
-static int raid6_has_lsx(void)
-{
- return cpu_has_lsx;
-}
-
static void raid6_2data_recov_lsx(int disks, size_t bytes, int faila,
int failb, void **ptrs)
{
@@ -291,18 +286,11 @@ static void raid6_datap_recov_lsx(int disks, size_t bytes, int faila,
const struct raid6_recov_calls raid6_recov_lsx = {
.data2 = raid6_2data_recov_lsx,
.datap = raid6_datap_recov_lsx,
- .valid = raid6_has_lsx,
.name = "lsx",
- .priority = 1,
};
#endif /* CONFIG_CPU_HAS_LSX */
#ifdef CONFIG_CPU_HAS_LASX
-static int raid6_has_lasx(void)
-{
- return cpu_has_lasx;
-}
-
static void raid6_2data_recov_lasx(int disks, size_t bytes, int faila,
int failb, void **ptrs)
{
@@ -509,8 +497,6 @@ static void raid6_datap_recov_lasx(int disks, size_t bytes, int faila,
const struct raid6_recov_calls raid6_recov_lasx = {
.data2 = raid6_2data_recov_lasx,
.datap = raid6_datap_recov_lasx,
- .valid = raid6_has_lasx,
.name = "lasx",
- .priority = 2,
};
#endif /* CONFIG_CPU_HAS_LASX */
diff --git a/lib/raid/raid6/powerpc/altivec.uc b/lib/raid/raid6/powerpc/altivec.uc
index eb4a448cc88e..c5429fb71dd6 100644
--- a/lib/raid/raid6/powerpc/altivec.uc
+++ b/lib/raid/raid6/powerpc/altivec.uc
@@ -104,17 +104,7 @@ static void raid6_altivec$#_gen_syndrome(int disks, size_t bytes, void **ptrs)
preempt_enable();
}
-int raid6_have_altivec(void);
-#if $# == 1
-int raid6_have_altivec(void)
-{
- /* This assumes either all CPUs have Altivec or none does */
- return cpu_has_feature(CPU_FTR_ALTIVEC);
-}
-#endif
-
const struct raid6_calls raid6_altivec$# = {
.gen_syndrome = raid6_altivec$#_gen_syndrome,
- .valid = raid6_have_altivec,
.name = "altivecx$#",
};
diff --git a/lib/raid/raid6/powerpc/pq_arch.h b/lib/raid/raid6/powerpc/pq_arch.h
new file mode 100644
index 000000000000..ea1878777ff2
--- /dev/null
+++ b/lib/raid/raid6/powerpc/pq_arch.h
@@ -0,0 +1,32 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include <asm/cputable.h>
+
+extern const struct raid6_calls raid6_altivec1;
+extern const struct raid6_calls raid6_altivec2;
+extern const struct raid6_calls raid6_altivec4;
+extern const struct raid6_calls raid6_altivec8;
+extern const struct raid6_calls raid6_vpermxor1;
+extern const struct raid6_calls raid6_vpermxor2;
+extern const struct raid6_calls raid6_vpermxor4;
+extern const struct raid6_calls raid6_vpermxor8;
+
+static __always_inline void __init arch_raid6_init(void)
+{
+ raid6_algo_add_default();
+
+ /* This assumes either all CPUs have Altivec or none does */
+ if (cpu_has_feature(CPU_FTR_ALTIVEC)) {
+ raid6_algo_add(&raid6_altivec1);
+ raid6_algo_add(&raid6_altivec2);
+ raid6_algo_add(&raid6_altivec4);
+ raid6_algo_add(&raid6_altivec8);
+ }
+ if (cpu_has_feature(CPU_FTR_ALTIVEC_COMP) &&
+ cpu_has_feature(CPU_FTR_ARCH_207S)) {
+ raid6_algo_add(&raid6_vpermxor1);
+ raid6_algo_add(&raid6_vpermxor2);
+ raid6_algo_add(&raid6_vpermxor4);
+ raid6_algo_add(&raid6_vpermxor8);
+ }
+}
diff --git a/lib/raid/raid6/powerpc/vpermxor.uc b/lib/raid/raid6/powerpc/vpermxor.uc
index ec61f30bec11..e8964361aaef 100644
--- a/lib/raid/raid6/powerpc/vpermxor.uc
+++ b/lib/raid/raid6/powerpc/vpermxor.uc
@@ -76,18 +76,7 @@ static void raid6_vpermxor$#_gen_syndrome(int disks, size_t bytes, void **ptrs)
preempt_enable();
}
-int raid6_have_altivec_vpermxor(void);
-#if $# == 1
-int raid6_have_altivec_vpermxor(void)
-{
- /* Check if arch has both altivec and the vpermxor instructions */
- return (cpu_has_feature(CPU_FTR_ALTIVEC_COMP) &&
- cpu_has_feature(CPU_FTR_ARCH_207S));
-}
-#endif
-
const struct raid6_calls raid6_vpermxor$# = {
.gen_syndrome = raid6_vpermxor$#_gen_syndrome,
- .valid = raid6_have_altivec_vpermxor,
.name = "vpermxor$#",
};
diff --git a/lib/raid/raid6/recov.c b/lib/raid/raid6/recov.c
index 735ab4013771..76eb2aef3667 100644
--- a/lib/raid/raid6/recov.c
+++ b/lib/raid/raid6/recov.c
@@ -97,7 +97,5 @@ static void raid6_datap_recov_intx1(int disks, size_t bytes, int faila,
const struct raid6_recov_calls raid6_recov_intx1 = {
.data2 = raid6_2data_recov_intx1,
.datap = raid6_datap_recov_intx1,
- .valid = NULL,
.name = "intx1",
- .priority = 0,
};
diff --git a/lib/raid/raid6/riscv/pq_arch.h b/lib/raid/raid6/riscv/pq_arch.h
new file mode 100644
index 000000000000..82f1a188f8c4
--- /dev/null
+++ b/lib/raid/raid6/riscv/pq_arch.h
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include <asm/vector.h>
+
+extern const struct raid6_calls raid6_rvvx1;
+extern const struct raid6_calls raid6_rvvx2;
+extern const struct raid6_calls raid6_rvvx4;
+extern const struct raid6_calls raid6_rvvx8;
+extern const struct raid6_recov_calls raid6_recov_rvv;
+
+static __always_inline void __init arch_raid6_init(void)
+{
+ raid6_algo_add_default();
+ if (has_vector()) {
+ raid6_algo_add(&raid6_rvvx1);
+ raid6_algo_add(&raid6_rvvx2);
+ raid6_algo_add(&raid6_rvvx4);
+ raid6_algo_add(&raid6_rvvx8);
+ raid6_recov_algo_add(&raid6_recov_rvv);
+ }
+}
diff --git a/lib/raid/raid6/riscv/recov_rvv.c b/lib/raid/raid6/riscv/recov_rvv.c
index 02120d245e22..2305940276dd 100644
--- a/lib/raid/raid6/riscv/recov_rvv.c
+++ b/lib/raid/raid6/riscv/recov_rvv.c
@@ -218,7 +218,5 @@ static void raid6_datap_recov_rvv(int disks, size_t bytes, int faila,
const struct raid6_recov_calls raid6_recov_rvv = {
.data2 = raid6_2data_recov_rvv,
.datap = raid6_datap_recov_rvv,
- .valid = rvv_has_vector,
.name = "rvv",
- .priority = 1,
};
diff --git a/lib/raid/raid6/riscv/rvv.h b/lib/raid/raid6/riscv/rvv.h
index c293130d798b..3a7c2468b1ea 100644
--- a/lib/raid/raid6/riscv/rvv.h
+++ b/lib/raid/raid6/riscv/rvv.h
@@ -10,11 +10,6 @@
#include <asm/vector.h>
#include "algos.h"
-static int rvv_has_vector(void)
-{
- return has_vector();
-}
-
#define RAID6_RVV_WRAPPER(_n) \
static void raid6_rvv ## _n ## _gen_syndrome(int disks, \
size_t bytes, void **ptrs) \
@@ -41,6 +36,5 @@ static int rvv_has_vector(void)
struct raid6_calls const raid6_rvvx ## _n = { \
.gen_syndrome = raid6_rvv ## _n ## _gen_syndrome, \
.xor_syndrome = raid6_rvv ## _n ## _xor_syndrome, \
- .valid = rvv_has_vector, \
.name = "rvvx" #_n, \
}
diff --git a/lib/raid/raid6/s390/pq_arch.h b/lib/raid/raid6/s390/pq_arch.h
new file mode 100644
index 000000000000..95d14c342306
--- /dev/null
+++ b/lib/raid/raid6/s390/pq_arch.h
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include <linux/cpufeature.h>
+
+extern const struct raid6_calls raid6_s390vx8;
+extern const struct raid6_recov_calls raid6_recov_s390xc;
+
+static __always_inline void __init arch_raid6_init(void)
+{
+ if (cpu_has_vx())
+ raid6_algo_add(&raid6_s390vx8);
+ else
+ raid6_algo_add_default();
+ raid6_recov_algo_add(&raid6_recov_s390xc);
+}
diff --git a/lib/raid/raid6/s390/recov_s390xc.c b/lib/raid/raid6/s390/recov_s390xc.c
index e7b3409f21e2..08d56896e5ea 100644
--- a/lib/raid/raid6/s390/recov_s390xc.c
+++ b/lib/raid/raid6/s390/recov_s390xc.c
@@ -112,7 +112,5 @@ static void raid6_datap_recov_s390xc(int disks, size_t bytes, int faila,
const struct raid6_recov_calls raid6_recov_s390xc = {
.data2 = raid6_2data_recov_s390xc,
.datap = raid6_datap_recov_s390xc,
- .valid = NULL,
.name = "s390xc",
- .priority = 1,
};
diff --git a/lib/raid/raid6/s390/s390vx.uc b/lib/raid/raid6/s390/s390vx.uc
index aba3515eacac..e5cf9054be2a 100644
--- a/lib/raid/raid6/s390/s390vx.uc
+++ b/lib/raid/raid6/s390/s390vx.uc
@@ -121,15 +121,8 @@ static void raid6_s390vx$#_xor_syndrome(int disks, int start, int stop,
kernel_fpu_end(&vxstate, KERNEL_VXR);
}
-static int raid6_s390vx$#_valid(void)
-{
- return cpu_has_vx();
-}
-
const struct raid6_calls raid6_s390vx$# = {
.gen_syndrome = raid6_s390vx$#_gen_syndrome,
.xor_syndrome = raid6_s390vx$#_xor_syndrome,
- .valid = raid6_s390vx$#_valid,
.name = "vx128x$#",
- .priority = 1,
};
diff --git a/lib/raid/raid6/tests/raid6_kunit.c b/lib/raid/raid6/tests/raid6_kunit.c
index de6a866953c5..4dea1c5acc96 100644
--- a/lib/raid/raid6/tests/raid6_kunit.c
+++ b/lib/raid/raid6/tests/raid6_kunit.c
@@ -88,19 +88,20 @@ static void test_disks(struct kunit *test, const struct raid6_calls *calls,
static void raid6_test(struct kunit *test)
{
- const struct raid6_calls *const *algo;
- const struct raid6_recov_calls *const *ra;
int i, j, p1, p2;
+ unsigned int r, g;
- for (ra = raid6_recov_algos; *ra; ra++) {
- if ((*ra)->valid && !(*ra)->valid())
- continue;
+ for (r = 0; ; r++) {
+ const struct raid6_recov_calls *ra = raid6_recov_algo_find(r);
- for (algo = raid6_algos; *algo; algo++) {
- const struct raid6_calls *calls = *algo;
+ if (!ra)
+ break;
- if (calls->valid && !calls->valid())
- continue;
+ for (g = 0; ; g++) {
+ const struct raid6_calls *calls = raid6_algo_find(g);
+
+ if (!calls)
+ break;
/* Nuke syndromes */
memset(data[NDISKS - 2], 0xee, PAGE_SIZE);
@@ -112,7 +113,7 @@ static void raid6_test(struct kunit *test)
for (i = 0; i < NDISKS-1; i++)
for (j = i+1; j < NDISKS; j++)
- test_disks(test, calls, *ra, i, j);
+ test_disks(test, calls, ra, i, j);
if (!calls->xor_syndrome)
continue;
@@ -130,7 +131,7 @@ static void raid6_test(struct kunit *test)
for (i = 0; i < NDISKS-1; i++)
for (j = i+1; j < NDISKS; j++)
test_disks(test, calls,
- *ra, i, j);
+ ra, i, j);
}
}
diff --git a/lib/raid/raid6/x86/avx2.c b/lib/raid/raid6/x86/avx2.c
index 0bf831799082..7efd94e6a87a 100644
--- a/lib/raid/raid6/x86/avx2.c
+++ b/lib/raid/raid6/x86/avx2.c
@@ -24,11 +24,6 @@ static const struct raid6_avx2_constants {
0x1d1d1d1d1d1d1d1dULL, 0x1d1d1d1d1d1d1d1dULL,},
};
-static int raid6_have_avx2(void)
-{
- return boot_cpu_has(X86_FEATURE_AVX2) && boot_cpu_has(X86_FEATURE_AVX);
-}
-
/*
* Plain AVX2 implementation
*/
@@ -131,10 +126,7 @@ static void raid6_avx21_xor_syndrome(int disks, int start, int stop,
const struct raid6_calls raid6_avx2x1 = {
.gen_syndrome = raid6_avx21_gen_syndrome,
.xor_syndrome = raid6_avx21_xor_syndrome,
- .valid = raid6_have_avx2,
.name = "avx2x1",
- /* Prefer AVX2 over priority 1 (SSE2 and others) */
- .priority = 2,
};
/*
@@ -262,10 +254,7 @@ static void raid6_avx22_xor_syndrome(int disks, int start, int stop,
const struct raid6_calls raid6_avx2x2 = {
.gen_syndrome = raid6_avx22_gen_syndrome,
.xor_syndrome = raid6_avx22_xor_syndrome,
- .valid = raid6_have_avx2,
.name = "avx2x2",
- /* Prefer AVX2 over priority 1 (SSE2 and others) */
- .priority = 2,
};
#ifdef CONFIG_X86_64
@@ -466,9 +455,6 @@ static void raid6_avx24_xor_syndrome(int disks, int start, int stop,
const struct raid6_calls raid6_avx2x4 = {
.gen_syndrome = raid6_avx24_gen_syndrome,
.xor_syndrome = raid6_avx24_xor_syndrome,
- .valid = raid6_have_avx2,
.name = "avx2x4",
- /* Prefer AVX2 over priority 1 (SSE2 and others) */
- .priority = 2,
};
#endif /* CONFIG_X86_64 */
diff --git a/lib/raid/raid6/x86/avx512.c b/lib/raid/raid6/x86/avx512.c
index 98ed42fb0a46..0772e798b742 100644
--- a/lib/raid/raid6/x86/avx512.c
+++ b/lib/raid/raid6/x86/avx512.c
@@ -30,16 +30,6 @@ static const struct raid6_avx512_constants {
0x1d1d1d1d1d1d1d1dULL, 0x1d1d1d1d1d1d1d1dULL,},
};
-static int raid6_have_avx512(void)
-{
- return boot_cpu_has(X86_FEATURE_AVX2) &&
- boot_cpu_has(X86_FEATURE_AVX) &&
- boot_cpu_has(X86_FEATURE_AVX512F) &&
- boot_cpu_has(X86_FEATURE_AVX512BW) &&
- boot_cpu_has(X86_FEATURE_AVX512VL) &&
- boot_cpu_has(X86_FEATURE_AVX512DQ);
-}
-
static void raid6_avx5121_gen_syndrome(int disks, size_t bytes, void **ptrs)
{
u8 **dptr = (u8 **)ptrs;
@@ -159,10 +149,7 @@ static void raid6_avx5121_xor_syndrome(int disks, int start, int stop,
const struct raid6_calls raid6_avx512x1 = {
.gen_syndrome = raid6_avx5121_gen_syndrome,
.xor_syndrome = raid6_avx5121_xor_syndrome,
- .valid = raid6_have_avx512,
.name = "avx512x1",
- /* Prefer AVX512 over priority 1 (SSE2 and others) */
- .priority = 2,
};
/*
@@ -317,10 +304,7 @@ static void raid6_avx5122_xor_syndrome(int disks, int start, int stop,
const struct raid6_calls raid6_avx512x2 = {
.gen_syndrome = raid6_avx5122_gen_syndrome,
.xor_syndrome = raid6_avx5122_xor_syndrome,
- .valid = raid6_have_avx512,
.name = "avx512x2",
- /* Prefer AVX512 over priority 1 (SSE2 and others) */
- .priority = 2,
};
#ifdef CONFIG_X86_64
@@ -556,9 +540,6 @@ static void raid6_avx5124_xor_syndrome(int disks, int start, int stop,
const struct raid6_calls raid6_avx512x4 = {
.gen_syndrome = raid6_avx5124_gen_syndrome,
.xor_syndrome = raid6_avx5124_xor_syndrome,
- .valid = raid6_have_avx512,
.name = "avx512x4",
- /* Prefer AVX512 over priority 1 (SSE2 and others) */
- .priority = 2,
};
#endif
diff --git a/lib/raid/raid6/x86/mmx.c b/lib/raid/raid6/x86/mmx.c
index 052d9f010bfe..3228c335965a 100644
--- a/lib/raid/raid6/x86/mmx.c
+++ b/lib/raid/raid6/x86/mmx.c
@@ -22,12 +22,6 @@ const struct raid6_mmx_constants {
0x1d1d1d1d1d1d1d1dULL,
};
-static int raid6_have_mmx(void)
-{
- /* Not really "boot_cpu" but "all_cpus" */
- return boot_cpu_has(X86_FEATURE_MMX);
-}
-
/*
* Plain MMX implementation
*/
@@ -70,7 +64,6 @@ static void raid6_mmx1_gen_syndrome(int disks, size_t bytes, void **ptrs)
const struct raid6_calls raid6_mmxx1 = {
.gen_syndrome = raid6_mmx1_gen_syndrome,
- .valid = raid6_have_mmx,
.name = "mmxx1",
};
@@ -127,6 +120,5 @@ static void raid6_mmx2_gen_syndrome(int disks, size_t bytes, void **ptrs)
const struct raid6_calls raid6_mmxx2 = {
.gen_syndrome = raid6_mmx2_gen_syndrome,
- .valid = raid6_have_mmx,
.name = "mmxx2",
};
diff --git a/lib/raid/raid6/x86/pq_arch.h b/lib/raid/raid6/x86/pq_arch.h
new file mode 100644
index 000000000000..28e395eb04d1
--- /dev/null
+++ b/lib/raid/raid6/x86/pq_arch.h
@@ -0,0 +1,96 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include <asm/cpufeature.h>
+
+extern const struct raid6_calls raid6_mmxx1;
+extern const struct raid6_calls raid6_mmxx2;
+extern const struct raid6_calls raid6_sse1x1;
+extern const struct raid6_calls raid6_sse1x2;
+extern const struct raid6_calls raid6_sse2x1;
+extern const struct raid6_calls raid6_sse2x2;
+extern const struct raid6_calls raid6_sse2x4;
+extern const struct raid6_calls raid6_avx2x1;
+extern const struct raid6_calls raid6_avx2x2;
+extern const struct raid6_calls raid6_avx2x4;
+extern const struct raid6_calls raid6_avx512x1;
+extern const struct raid6_calls raid6_avx512x2;
+extern const struct raid6_calls raid6_avx512x4;
+
+extern const struct raid6_recov_calls raid6_recov_ssse3;
+extern const struct raid6_recov_calls raid6_recov_avx2;
+extern const struct raid6_recov_calls raid6_recov_avx512;
+
+static inline int raid6_has_avx512(void)
+{
+ return boot_cpu_has(X86_FEATURE_AVX2) &&
+ boot_cpu_has(X86_FEATURE_AVX) &&
+ boot_cpu_has(X86_FEATURE_AVX512F) &&
+ boot_cpu_has(X86_FEATURE_AVX512BW) &&
+ boot_cpu_has(X86_FEATURE_AVX512VL) &&
+ boot_cpu_has(X86_FEATURE_AVX512DQ);
+}
+
+static inline bool raid6_has_avx2(void)
+{
+ return boot_cpu_has(X86_FEATURE_AVX2) && boot_cpu_has(X86_FEATURE_AVX);
+}
+
+static inline bool raid6_has_ssse3(void)
+{
+ return boot_cpu_has(X86_FEATURE_XMM) &&
+ boot_cpu_has(X86_FEATURE_XMM2) &&
+ boot_cpu_has(X86_FEATURE_SSSE3);
+}
+
+static inline bool raid6_has_sse2(void)
+{
+ return boot_cpu_has(X86_FEATURE_MMX) &&
+ boot_cpu_has(X86_FEATURE_FXSR) &&
+ boot_cpu_has(X86_FEATURE_XMM) &&
+ boot_cpu_has(X86_FEATURE_XMM2);
+}
+
+static inline bool raid6_has_sse1_or_mmxext(void)
+{
+ return boot_cpu_has(X86_FEATURE_MMX) &&
+ (boot_cpu_has(X86_FEATURE_XMM) ||
+ boot_cpu_has(X86_FEATURE_MMXEXT));
+}
+
+static __always_inline void __init arch_raid6_init(void)
+{
+ if (raid6_has_avx2()) {
+ if (raid6_has_avx512()) {
+ raid6_algo_add(&raid6_avx512x1);
+ raid6_algo_add(&raid6_avx512x2);
+ if (IS_ENABLED(CONFIG_X86_64))
+ raid6_algo_add(&raid6_avx512x4);
+ }
+ raid6_algo_add(&raid6_avx2x1);
+ raid6_algo_add(&raid6_avx2x2);
+ if (IS_ENABLED(CONFIG_X86_64))
+ raid6_algo_add(&raid6_avx2x4);
+ } else if (IS_ENABLED(CONFIG_X86_64) || raid6_has_sse2()) {
+ /* x86_64 can assume SSE2 as baseline */
+ raid6_algo_add(&raid6_sse2x1);
+ raid6_algo_add(&raid6_sse2x2);
+ if (IS_ENABLED(CONFIG_X86_64))
+ raid6_algo_add(&raid6_sse2x4);
+ } else {
+ raid6_algo_add_default();
+ if (raid6_has_sse1_or_mmxext()) {
+ raid6_algo_add(&raid6_sse1x1);
+ raid6_algo_add(&raid6_sse1x2);
+ } else if (boot_cpu_has(X86_FEATURE_MMX)) {
+ raid6_algo_add(&raid6_mmxx1);
+ raid6_algo_add(&raid6_mmxx2);
+ }
+ }
+
+ if (raid6_has_avx512())
+ raid6_recov_algo_add(&raid6_recov_avx512);
+ else if (raid6_has_avx2())
+ raid6_recov_algo_add(&raid6_recov_avx2);
+ else if (raid6_has_ssse3())
+ raid6_recov_algo_add(&raid6_recov_ssse3);
+}
diff --git a/lib/raid/raid6/x86/recov_avx2.c b/lib/raid/raid6/x86/recov_avx2.c
index 06c6e05763bc..a714a780a2d8 100644
--- a/lib/raid/raid6/x86/recov_avx2.c
+++ b/lib/raid/raid6/x86/recov_avx2.c
@@ -9,12 +9,6 @@
#include <asm/fpu/api.h>
#include "algos.h"
-static int raid6_has_avx2(void)
-{
- return boot_cpu_has(X86_FEATURE_AVX2) &&
- boot_cpu_has(X86_FEATURE_AVX);
-}
-
static void raid6_2data_recov_avx2(int disks, size_t bytes, int faila,
int failb, void **ptrs)
{
@@ -305,11 +299,9 @@ static void raid6_datap_recov_avx2(int disks, size_t bytes, int faila,
const struct raid6_recov_calls raid6_recov_avx2 = {
.data2 = raid6_2data_recov_avx2,
.datap = raid6_datap_recov_avx2,
- .valid = raid6_has_avx2,
#ifdef CONFIG_X86_64
.name = "avx2x2",
#else
.name = "avx2x1",
#endif
- .priority = 2,
};
diff --git a/lib/raid/raid6/x86/recov_avx512.c b/lib/raid/raid6/x86/recov_avx512.c
index 850bb962b514..ec72d5a30c01 100644
--- a/lib/raid/raid6/x86/recov_avx512.c
+++ b/lib/raid/raid6/x86/recov_avx512.c
@@ -11,16 +11,6 @@
#include <asm/fpu/api.h>
#include "algos.h"
-static int raid6_has_avx512(void)
-{
- return boot_cpu_has(X86_FEATURE_AVX2) &&
- boot_cpu_has(X86_FEATURE_AVX) &&
- boot_cpu_has(X86_FEATURE_AVX512F) &&
- boot_cpu_has(X86_FEATURE_AVX512BW) &&
- boot_cpu_has(X86_FEATURE_AVX512VL) &&
- boot_cpu_has(X86_FEATURE_AVX512DQ);
-}
-
static void raid6_2data_recov_avx512(int disks, size_t bytes, int faila,
int failb, void **ptrs)
{
@@ -369,11 +359,9 @@ static void raid6_datap_recov_avx512(int disks, size_t bytes, int faila,
const struct raid6_recov_calls raid6_recov_avx512 = {
.data2 = raid6_2data_recov_avx512,
.datap = raid6_datap_recov_avx512,
- .valid = raid6_has_avx512,
#ifdef CONFIG_X86_64
.name = "avx512x2",
#else
.name = "avx512x1",
#endif
- .priority = 3,
};
diff --git a/lib/raid/raid6/x86/recov_ssse3.c b/lib/raid/raid6/x86/recov_ssse3.c
index 95589c33003a..700bd2c865ec 100644
--- a/lib/raid/raid6/x86/recov_ssse3.c
+++ b/lib/raid/raid6/x86/recov_ssse3.c
@@ -8,13 +8,6 @@
#include <asm/fpu/api.h>
#include "algos.h"
-static int raid6_has_ssse3(void)
-{
- return boot_cpu_has(X86_FEATURE_XMM) &&
- boot_cpu_has(X86_FEATURE_XMM2) &&
- boot_cpu_has(X86_FEATURE_SSSE3);
-}
-
static void raid6_2data_recov_ssse3(int disks, size_t bytes, int faila,
int failb, void **ptrs)
{
@@ -320,11 +313,9 @@ static void raid6_datap_recov_ssse3(int disks, size_t bytes, int faila,
const struct raid6_recov_calls raid6_recov_ssse3 = {
.data2 = raid6_2data_recov_ssse3,
.datap = raid6_datap_recov_ssse3,
- .valid = raid6_has_ssse3,
#ifdef CONFIG_X86_64
.name = "ssse3x2",
#else
.name = "ssse3x1",
#endif
- .priority = 1,
};
diff --git a/lib/raid/raid6/x86/sse1.c b/lib/raid/raid6/x86/sse1.c
index 7004255a0bb1..6ebdcf824e00 100644
--- a/lib/raid/raid6/x86/sse1.c
+++ b/lib/raid/raid6/x86/sse1.c
@@ -25,14 +25,6 @@ extern const struct raid6_mmx_constants {
u64 x1d;
} raid6_mmx_constants;
-static int raid6_have_sse1_or_mmxext(void)
-{
- /* Not really boot_cpu but "all_cpus" */
- return boot_cpu_has(X86_FEATURE_MMX) &&
- (boot_cpu_has(X86_FEATURE_XMM) ||
- boot_cpu_has(X86_FEATURE_MMXEXT));
-}
-
/*
* Plain SSE1 implementation
*/
@@ -86,9 +78,7 @@ static void raid6_sse11_gen_syndrome(int disks, size_t bytes, void **ptrs)
const struct raid6_calls raid6_sse1x1 = {
.gen_syndrome = raid6_sse11_gen_syndrome,
- .valid = raid6_have_sse1_or_mmxext,
.name = "sse1x1",
- .priority = 1, /* Has cache hints */
};
/*
@@ -148,7 +138,5 @@ static void raid6_sse12_gen_syndrome(int disks, size_t bytes, void **ptrs)
const struct raid6_calls raid6_sse1x2 = {
.gen_syndrome = raid6_sse12_gen_syndrome,
- .valid = raid6_have_sse1_or_mmxext,
.name = "sse1x2",
- .priority = 1, /* Has cache hints */
};
diff --git a/lib/raid/raid6/x86/sse2.c b/lib/raid/raid6/x86/sse2.c
index f30be4ee14d0..7049c8512f35 100644
--- a/lib/raid/raid6/x86/sse2.c
+++ b/lib/raid/raid6/x86/sse2.c
@@ -22,15 +22,6 @@ static const struct raid6_sse_constants {
{ 0x1d1d1d1d1d1d1d1dULL, 0x1d1d1d1d1d1d1d1dULL },
};
-static int raid6_have_sse2(void)
-{
- /* Not really boot_cpu but "all_cpus" */
- return boot_cpu_has(X86_FEATURE_MMX) &&
- boot_cpu_has(X86_FEATURE_FXSR) &&
- boot_cpu_has(X86_FEATURE_XMM) &&
- boot_cpu_has(X86_FEATURE_XMM2);
-}
-
/*
* Plain SSE2 implementation
*/
@@ -136,9 +127,7 @@ static void raid6_sse21_xor_syndrome(int disks, int start, int stop,
const struct raid6_calls raid6_sse2x1 = {
.gen_syndrome = raid6_sse21_gen_syndrome,
.xor_syndrome = raid6_sse21_xor_syndrome,
- .valid = raid6_have_sse2,
.name = "sse2x1",
- .priority = 1, /* Has cache hints */
};
/*
@@ -266,9 +255,7 @@ static void raid6_sse22_xor_syndrome(int disks, int start, int stop,
const struct raid6_calls raid6_sse2x2 = {
.gen_syndrome = raid6_sse22_gen_syndrome,
.xor_syndrome = raid6_sse22_xor_syndrome,
- .valid = raid6_have_sse2,
.name = "sse2x2",
- .priority = 1, /* Has cache hints */
};
#ifdef CONFIG_X86_64
@@ -473,9 +460,7 @@ static void raid6_sse24_xor_syndrome(int disks, int start, int stop,
const struct raid6_calls raid6_sse2x4 = {
.gen_syndrome = raid6_sse24_gen_syndrome,
.xor_syndrome = raid6_sse24_xor_syndrome,
- .valid = raid6_have_sse2,
.name = "sse2x4",
- .priority = 1, /* Has cache hints */
};
#endif /* CONFIG_X86_64 */
--
2.53.0
^ permalink raw reply related
* Re: [PATCH 2/3] memory: mtk-smi: Add a flag skip_rpm
From: Xueqi Zhang (张雪琦) @ 2026-05-18 6:51 UTC (permalink / raw)
To: robh@kernel.org, matthias.bgg@gmail.com,
Yong Wu (吴勇), AngeloGioacchino Del Regno,
krzk@kernel.org, conor+dt@kernel.org
Cc: Wendy-ST Lin (林詩庭),
linux-kernel@vger.kernel.org, linux-mediatek@lists.infradead.org,
linux-arm-kernel@lists.infradead.org, iommu@lists.linux.dev,
Project_Global_Chrome_Upstream_Group, devicetree@vger.kernel.org
In-Reply-To: <46e0e1f1-e094-40f9-99f9-22678bb40d39@collabora.com>
Hi Angelo
First of all, please accept my apologies for the delayed response. I
have been deeply occupied with MT8196 Aluminium pKVM SMMU and SMI
related tasks recently.
Regarding your question, my previous description in the patch was not
accurate enough and may have caused some confusion. In fact, not all
SMI commons have their backup/restore handled by the RTFF hardware. The
SMI commons are distributed across various subsystems (e.g., mminfra,
venc, display, cam, etc.). Currently, only the SMI common under the
mminfra subsystem is backed up and restored by the RTFF hardware.
Therefore, I believe adding a specific skip_rpm flag is more
appropriate here. If we were to differentiate this based on a new
MTK_SMI_GEN3 type, it would imply that all SMI common modules of that
generation would skip the RPM operations, which is not the intended
behavior.
To make this clearer, I plan to update the commit message in the next
version as follows:
Subject: memory: mtk-smi: Add skip_rpm flag for certain MT8196 SMI
commons
Body:
On MT8196, certain SMI commons are backed up and restored by the RTFF
hardware rather than by software.
For these specific SMI commons, software-controlled register backup and
restore in the runtime callback is no longer necessary. Therefore,
introduce a skip_rpm flag to bypass these redundant RPM operations for
these SMI commons.
What do you think about this approach?
Thanks,
Xueqi
On Thu, 2025-03-20 at 13:11 +0100, AngeloGioacchino Del Regno wrote:
> External email : Please do not click links or open attachments until
> you have verified the sender or the content.
>
>
> Il 20/03/25 08:36, Xueqi Zhang ha scritto:
> > MT8196 SMI commons is backed up/restored by RTFF HW.
> > It doesn't need SW control the register backup/store
> > in the runtime callback.Therefore, add a flag skip_rpm
> > to help skip RPM operations for SMI commons.
> >
> > Signed-off-by: Xueqi Zhang <xueqi.zhang@mediatek.com>
>
> So the MT8196 SMI common doesn't require any clocks?
>
> That's fine for me, but this looks bloody similar to MT6989's SMI
> common, which
> is SMI GEN3 and not GEN2....
>
> ....so, are you sure that you need a `skip_rpm` flag and not new
> MTK_SMI_GEN3 and
> MTK_SMI_GEN3_SUB_COMM types? :-)
>
> Regards,
> Angelo
>
> > ---
> > drivers/memory/mtk-smi.c | 11 ++++++++---
> > 1 file changed, 8 insertions(+), 3 deletions(-)
> >
> > diff --git a/drivers/memory/mtk-smi.c b/drivers/memory/mtk-smi.c
> > index a8f5467d6b31..b9affa3c3185 100644
> > --- a/drivers/memory/mtk-smi.c
> > +++ b/drivers/memory/mtk-smi.c
> > @@ -123,6 +123,7 @@ static const char * const mtk_smi_common_clks[]
> > = {"apb", "smi", "gals0", "gals1
> > struct mtk_smi_common_plat {
> > enum mtk_smi_type type;
> > bool has_gals;
> > + bool skip_rpm;
> > u32 bus_sel; /* Balance some larbs to
> > enter mmu0 or mmu1 */
> >
> > const struct mtk_smi_reg_pair *init;
> > @@ -547,6 +548,9 @@ static int mtk_smi_dts_clk_init(struct device
> > *dev, struct mtk_smi *smi,
> > {
> > int i, ret;
> >
> > + if (smi->plat->skip_rpm)
> > + return 0;
> > +
> > for (i = 0; i < clk_nr_required; i++)
> > smi->clks[i].id = clks[i];
> > ret = devm_clk_bulk_get(dev, clk_nr_required, smi->clks);
> > @@ -783,7 +787,7 @@ static int mtk_smi_common_probe(struct
> > platform_device *pdev)
> > common->dev = dev;
> > common->plat = of_device_get_match_data(dev);
> >
> > - if (common->plat->has_gals) {
> > + if (!common->plat->skip_rpm && common->plat->has_gals) {
> > if (common->plat->type == MTK_SMI_GEN2)
> > clk_required = MTK_SMI_COM_GALS_REQ_CLK_NR;
> > else if (common->plat->type == MTK_SMI_GEN2_SUB_COMM)
> > @@ -814,13 +818,14 @@ static int mtk_smi_common_probe(struct
> > platform_device *pdev)
> > }
> >
> > /* link its smi-common if this is smi-sub-common */
> > - if (common->plat->type == MTK_SMI_GEN2_SUB_COMM) {
> > + if (common->plat->type == MTK_SMI_GEN2_SUB_COMM && !common-
> > >plat->skip_rpm) {
> > ret = mtk_smi_device_link_common(dev, &common-
> > >smi_common_dev);
> > if (ret < 0)
> > return ret;
> > }
> >
> > - pm_runtime_enable(dev);
> > + if (!common->plat->skip_rpm)
> > + pm_runtime_enable(dev);
> > platform_set_drvdata(pdev, common);
> > return 0;
> > }
>
>
^ permalink raw reply
* Re: [PATCH v18 0/7] coresight: ctcu: Enable byte-cntr function for TMC ETR
From: Jie Gan @ 2026-05-18 6:48 UTC (permalink / raw)
To: Suzuki K Poulose, Mike Leach, James Clark, Alexander Shishkin,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Tingwei Zhang,
Bjorn Andersson, Konrad Dybcio
Cc: coresight, linux-arm-kernel, linux-kernel, linux-arm-msm,
devicetree, Konrad Dybcio, Krzysztof Kozlowski
In-Reply-To: <20260507-enable-byte-cntr-for-ctcu-v18-0-2b2d590463a3@oss.qualcomm.com>
On 5/7/2026 10:11 PM, Jie Gan wrote:
> The byte-cntr function provided by the CTCU device is used to count the
> trace data entering the ETR. An interrupt is triggered if the data size
> exceeds the threshold set in the BYTECNTRVAL register. The interrupt
> handler counts the number of triggered interruptions.
>
Gentle reminder. Thank you for taking the time to review this patch series.
Thanks,
Jie
> Based on this concept, the irq_cnt can be used to determine whether
> the etr_buf is full. The ETR device will be disabled when the active
> etr_buf is nearly full or a timeout occurs. The nearly full buffer will
> be switched to background after synced. A new buffer will be picked from
> the etr_buf_list, then restart the ETR device.
>
> The byte-cntr reading functions can access data from the synced and
> deactivated buffer, transferring trace data from the etr_buf to userspace
> without stopping the ETR device.
>
> The byte-cntr read operation has integrated with the file node tmc_etr,
> for example:
> /dev/tmc_etr0
> /dev/tmc_etr1
>
> There are two scenarios for the tmc_etr file node with byte-cntr function:
> 1. BYTECNTRVAL register is configured and byte-cntr is enabled -> byte-cntr read
> 2. BYTECNTRVAL register is reset or byte-cntr is disabled -> original behavior
>
> Shell commands to enable byte-cntr reading for etr0:
> echo 1 > /sys/bus/coresight/devices/ctcu0/irq_enabled0
> echo 1 > /sys/bus/coresight/devices/tmc_etr0/enable_sink
> echo 1 > /sys/bus/coresight/devices/etm0/enable_source
> cat /dev/tmc_etr0
>
> Reset the BYTECNTR register for etr0:
> echo 0 > /sys/bus/coresight/devices/ctcu0/irq_enabled0
>
> Test Report:
> === Module setup ===
> CONFIG_CORESIGHT=y (built-in, no action needed)
> CONFIG_CORESIGHT_LINK_AND_SINK_TMC=y (built-in, no action needed)
> coresight-ctcu: not loaded, running modprobe...
> coresight-ctcu: loaded
> CTCU byte-cntr test
> CTCU : ctcu0
> ETR : tmc_etr0
> source : etm0
> chardev: /dev/tmc_etr0
> module : coresight-ctcu
>
> === T1: device presence ===
> PASS: CTCU device found: ctcu0
> PASS: TMC ETR device found: tmc_etr0
>
> === T2: irq_enabled sysfs attributes ===
> PASS: irq_enabled0 attribute exists
> PASS: irq_enabled0 readable, value=0
> PASS: irq_enabled1 attribute exists
> PASS: irq_enabled1 readable, value=0
>
> === T3: irq_enabled write/read round-trip ===
> PASS: irq_enabled0: write 1 -> read back 1
> PASS: irq_enabled0: write 0 -> read back 0
> PASS: irq_enabled1: write 1 -> read back 1
> PASS: irq_enabled1: write 0 -> read back 0
>
> === T4: byte-cntr read with active trace ===
> [step] cleanup: byte_cntr_disable
> [step] enable_source = 0 (etm0)
> [step] enable_sink = 0 (tmc_etr0)
> [step] set irq_enabled0 = 0
> [step] byte_cntr_disable done
> [step] byte_cntr_enable
> [step] set irq_enabled0 = 1
> [step] set buffer_size = 0x2000000
> [step] enable_sink = 1 (tmc_etr0)
> [step] enable_source = 1 (etm0)
> [step] byte_cntr_enable done
> [step] cat /dev/tmc_etr0 > /tmp/tmc_etr0.bin &
> [step] sleep 5 (accumulate trace data)
> [step] byte_cntr_disable
> [step] enable_source = 0 (etm0)
> [step] enable_sink = 0 (tmc_etr0)
> [step] set irq_enabled0 = 0
> [step] byte_cntr_disable done
> PASS: T4: cat exited naturally after source disabled (EOF delivered)
> PASS: byte-cntr read returned 35333968 bytes -> /tmp/tmc_etr0.bin
> PASS: no kernel warnings/oops after: byte-cntr read
>
> === T5: EBUSY on concurrent open while byte-cntr reading ===
> [step] enable_source = 0 (etm0)
> [step] enable_sink = 0 (tmc_etr0)
> [step] set irq_enabled0 = 0
> [step] byte_cntr_disable done
> [step] set irq_enabled0 = 1
> [step] set buffer_size = 0x2000000
> [step] enable_sink = 1 (tmc_etr0)
> [step] enable_source = 1 (etm0)
> [step] byte_cntr_enable done
> PASS: T5: second open correctly refused (EBUSY)
> [step] enable_source = 0 (etm0)
> [step] enable_sink = 0 (tmc_etr0)
> [step] set irq_enabled0 = 0
> [step] byte_cntr_disable done
> PASS: no kernel warnings/oops after: concurrent open test
>
> === T6: rmmod while byte-cntr read is active ===
> [step] enable_source = 0 (etm0)
> [step] enable_sink = 0 (tmc_etr0)
> [step] set irq_enabled0 = 0
> [step] byte_cntr_disable done
> [step] set irq_enabled0 = 1
> [step] set buffer_size = 0x2000000
> [step] enable_sink = 1 (tmc_etr0)
> [step] enable_source = 1 (etm0)
> [step] byte_cntr_enable done
> PASS: T6: rmmod returned non-zero (device busy), no panic
> PASS: no kernel warnings/oops after: rmmod while reading
> [step] enable_source = 0 (etm0)
> [step] enable_sink = 0 (tmc_etr0)
> [step] set irq_enabled0 = 0
> [step] byte_cntr_disable done
>
> === T7: insmod after rmmod and re-probe sanity ===
> [step] module still loaded after T6, retrying rmmod
> PASS: T7: modprobe coresight-ctcu succeeded
> PASS: T7: CTCU device reappeared: ctcu0
> PASS: no kernel warnings/oops after: insmod / re-probe
>
> ===================================
> ===================================
>
> Results: PASS=20 FAIL=0 SKIP=0
> ---
> Changes in v18:
> 1. add a NULL check for the in_conns instance in patch 1.
> 2. fix a bug in patch 2: the tmc_alloc_etr_buf never return NULL and the
> previous check for the return value is incorrect.
> 3. add more kernel_doc description for tmc_clean_etr_buf_list function
> in patch 2
> - Link to v17: https://lore.kernel.org/r/20260421-enable-byte-cntr-for-ctcu-v17-0-9cf36ff55fc0@oss.qualcomm.com
>
> Changes in v17:
> 1. fix race issue during allocat buffer.
> 2. fix user after free issue observed when remove module.
> - Link to v16: https://lore.kernel.org/r/20260323-enable-byte-cntr-for-ctcu-v16-0-7a413d211b8d@oss.qualcomm.com
>
> Changes in v16:
> 1. Remove lock/unlock processes in patch "coresight: tmc: add create/clean
> functions for etr_buf_list" because we are allocating/freeing memory.
> - Link to v15: https://lore.kernel.org/r/20260313-enable-byte-cntr-for-ctcu-v15-0-1777f14ed319@oss.qualcomm.com
>
> Changes in v15:
> 1. add lockdep_assert_held in patch "coresight: tmc: add create/clean
> functions for etr_buf_list"
> 2. optimize tmc_clean_etr_buf_list function
> 3. optimize the patch "enable byte-cntr for TMC ETR devices" according
> to Suzuki's comments
> - call byte_cntr_sysfs_ops from etr_sysfs_ops
> - optimize the lock usage in all functions
> - remove the buf_node parameter in etr_drvdata, move it to
> byte_cntr_data
> - move the tmc_reset_sysfs_buf function to tmc-etr.c
> - add a read flag to struct etr_buf_node to allow updating pos while
> traversing etr_buf_list during data reads.
> Link to v14: https://lore.kernel.org/r/20260309-enable-byte-cntr-for-ctcu-v14-0-c08823e5a8e6@oss.qualcomm.com
>
> Changes in V14:
> 1. Drop the patch: integrate byte-cntr's sysfs_ops with tmc sysfs file_ops
> 2. Replace tmc_sysfs_ops with byte_cntr_sysfs_ops in byte_cntr_start
> function and restore etr_sysfs_ops in byte_cntr_unprepare function.
> 3. Remove redundant checks in byte‑cntr functions.
> Link to V13: https://lore.kernel.org/all/20260223-enable-byte-cntr-for-ctcu-v13-0-9cb44178b250@oss.qualcomm.com/
>
> Changes in v13:
> 1. initilize the byte_cntr_data->raw_spin_lock before using.
> 2. replace kzalloc with kzalloc_obj.
> Link to V12: https://lore.kernel.org/all/20260203-enable-byte-cntr-for-ctcu-v12-0-7bf81b86b70e@oss.qualcomm.com/
>
> Changes in v12:
> 1. Add a new function for retrieving the CTCU's coresight_dev instead of
> refactor the existing function.
> Link to v11: https://lore.kernel.org/r/20260126-enable-byte-cntr-for-ctcu-v11-0-c0af66ba15cf@oss.qualcomm.com
>
> Changes in v11:
> 1. Correct the description in patch1 for the function coresight_get_in_port.
> 2. Renaming the sysfs_ops to tmc_sysfs_ops per Suzuki's suggestion.
> Link to v10: https://lore.kernel.org/r/20260122-enable-byte-cntr-for-ctcu-v10-0-22978e3c169f@oss.qualcomm.com
>
> Changes in v10:
> 1. fix a free memory issue that is reported by robot for patch 2.
> Link to v9: https://lore.kernel.org/r/20251224-enable-byte-cntr-for-ctcu-v9-0-886c4496fed4@oss.qualcomm.com
>
> Changes in v9:
> 1. Drop the patch: add a new API to retrieve the helper device
> 2. Add a new patch to refactor the tmc_etr_get_catu_device function,
> making it generic to support all types of helper devices associated with ETR.
> 3. Optimizing the code for creating irq_threshold sysfs node.
> 4. Remove interrupt-name property and obtain the IRQ based on the
> in-port number.
> Link to v8: https://lore.kernel.org/r/20251211-enable-byte-cntr-for-ctcu-v8-0-3e12ff313191@oss.qualcomm.com
>
> Changes in V8:
> 1. Optimizing the patch 1 and patch 2 according to Suzuki's comments.
> 2. Combine the patch 3 and patch 4 together.
> 3. Rename the interrupt-name to prevent confusion, for example:etr0->etrirq0.
> Link to V7 - https://lore.kernel.org/all/20251013-enable-byte-cntr-for-ctcu-v7-0-e1e8f41e15dd@oss.qualcomm.com/
>
> Changes in V7:
> 1. rebased on tag next-20251010
> 2. updated info for sysfs node document
> Link to V6 - https://lore.kernel.org/all/20250908-enable-byte-cntr-for-tmc-v6-0-1db9e621441a@oss.qualcomm.com/
>
> Changes in V6:
> 1. rebased on next-20250905.
> 2. fixed the issue that the dtsi file has re-named from sa8775p.dtsi to
> lemans.dtsi.
> 3. fixed some minor issues about comments.
> Link to V5 - https://lore.kernel.org/all/20250812083731.549-1-jie.gan@oss.qualcomm.com/
>
> Changes in V5:
> 1. Add Mike's reviewed-by tag for patchset 1,2,5.
> 2. Remove the function pointer added to helper_ops according to Mike's
> comment, it also results the patchset has been removed.
> 3. Optimizing the paired create/clean functions for etr_buf_list.
> 4. Remove the unneeded parameter "reading" from the etr_buf_node.
> Link to V4 - https://lore.kernel.org/all/20250725100806.1157-1-jie.gan@oss.qualcomm.com/
>
> Changes in V4:
> 1. Rename the function to coresight_get_in_port_dest regarding to Mike's
> comment (patch 1/10).
> 2. Add lock to protect the connections regarding to Mike's comment
> (patch 2/10).
> 3. Move all byte-cntr functions to coresight-ctcu-byte-cntr file.
> 4. Add tmc_read_ops to wrap all read operations for TMC device.
> 5. Add a function in helper_ops to check whether the byte-cntr is
> enabkled.
> 6. Call byte-cntr's read_ops if byte-cntr is enabled when reading data
> from the sysfs node.
> Link to V3 resend - https://lore.kernel.org/all/20250714063109.591-1-jie.gan@oss.qualcomm.com/
>
> Changes in V3 resend:
> 1. rebased on next-20250711.
> Link to V3 - https://lore.kernel.org/all/20250624060438.7469-1-jie.gan@oss.qualcomm.com/
>
> Changes in V3:
> 1. The previous solution has been deprecated.
> 2. Add a etr_buf_list to manage allcated etr buffers.
> 3. Add a logic to switch buffer for ETR.
> 4. Add read functions to read trace data from synced etr buffer.
> Link to V2 - https://lore.kernel.org/all/20250410013330.3609482-1-jie.gan@oss.qualcomm.com/
>
> Changes in V2:
> 1. Removed the independent file node /dev/byte_cntr.
> 2. Integrated the byte-cntr's file operations with current ETR file
> node.
> 3. Optimized the driver code of the CTCU that associated with byte-cntr.
> 4. Add kernel document for the export API tmc_etr_get_rwp_offset.
> 5. Optimized the way to read the rwp_offset according to Mike's
> suggestion.
> 6. Removed the dependency of the dts patch.
> Link to V1 - https://lore.kernel.org/all/20250310090407.2069489-1-quic_jiegan@quicinc.com/
>
> To: Suzuki K Poulose <suzuki.poulose@arm.com>
> To: Mike Leach <mike.leach@arm.com>
> To: James Clark <james.clark@linaro.org>
> To: Alexander Shishkin <alexander.shishkin@linux.intel.com>
> To: Rob Herring <robh@kernel.org>
> To: Krzysztof Kozlowski <krzk+dt@kernel.org>
> To: Conor Dooley <conor+dt@kernel.org>
> To: Tingwei Zhang <tingwei.zhang@oss.qualcomm.com>
> To: Bjorn Andersson <andersson@kernel.org>
> To: Konrad Dybcio <konradybcio@kernel.org>
> Cc: coresight@lists.linaro.org
> Cc: linux-arm-kernel@lists.infradead.org
> Cc: linux-kernel@vger.kernel.org
> Cc: linux-arm-msm@vger.kernel.org
> Cc: devicetree@vger.kernel.org
> Signed-off-by: Jie Gan <jie.gan@oss.qualcomm.com>
>
> ---
> Jie Gan (7):
> coresight: core: refactor ctcu_get_active_port and make it generic
> coresight: tmc: add create/clean functions for etr_buf_list
> coresight: tmc: introduce tmc_sysfs_ops to wrap sysfs read operations
> coresight: etr: add a new function to retrieve the CTCU device
> dt-bindings: arm: add an interrupt property for Coresight CTCU
> coresight: ctcu: enable byte-cntr for TMC ETR devices
> arm64: dts: qcom: lemans: add interrupts to CTCU device
>
> .../ABI/testing/sysfs-bus-coresight-devices-ctcu | 9 +
> .../bindings/arm/qcom,coresight-ctcu.yaml | 10 +
> arch/arm64/boot/dts/qcom/lemans.dtsi | 3 +
> drivers/hwtracing/coresight/Makefile | 2 +-
> drivers/hwtracing/coresight/coresight-core.c | 27 ++
> .../hwtracing/coresight/coresight-ctcu-byte-cntr.c | 304 +++++++++++++++++++++
> drivers/hwtracing/coresight/coresight-ctcu-core.c | 146 ++++++++--
> drivers/hwtracing/coresight/coresight-ctcu.h | 79 +++++-
> drivers/hwtracing/coresight/coresight-priv.h | 2 +
> drivers/hwtracing/coresight/coresight-tmc-core.c | 55 ++--
> drivers/hwtracing/coresight/coresight-tmc-etr.c | 243 +++++++++++++++-
> drivers/hwtracing/coresight/coresight-tmc.h | 42 +++
> 12 files changed, 850 insertions(+), 72 deletions(-)
> ---
> base-commit: 936c21068d7ade00325e40d82bfd2f3f29d9f659
> change-id: 20260309-enable-byte-cntr-for-ctcu-ff86e6198b7f
>
> Best regards,
^ permalink raw reply
* Re: [PATCH] ARM: dts: aspeed: anacapa: name EDSFF and thermtrip SGPIO lines
From: Andrew Jeffery @ 2026-05-18 6:47 UTC (permalink / raw)
To: Rex.Fu, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Joel Stanley
Cc: devicetree, linux-arm-kernel, linux-aspeed, linux-kernel
In-Reply-To: <20260430-anacapa-sgpio-edsff-thermtrip-v1-1-2fd5e72435d0@amd.com>
Hello Rex,
On Thu, 2026-04-30 at 13:44 +0800, Rex Fu via B4 Relay wrote:
> From: Rex Fu <Rex.Fu@amd.com>
>
> Name the Anacapa SGPIO lines used for EDSFF power-good and thermtrip
> assertion signals.
>
> The affected lines replace legacy
>
Which are legacy?
> or unused
>
Which are unused?
> CPU-related names with the
> platform signal names used by userspace monitoring.
This is the kind of change that has the potential to break old
userspace. Why is it appropriate? I'd like a more precise discussion in
the commit message.
Was there some other underlying change (e.g. a new revision of the
platform design)?
Andrew
>
> Signed-off-by: Rex Fu <Rex.Fu@amd.com>
> ---
> arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-anacapa.dts | 10 +++++-----
> 1 file changed, 5 insertions(+), 5 deletions(-)
>
> diff --git a/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-anacapa.dts b/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-anacapa.dts
> index 2cb7bd128d24..fe960bb7bc27 100644
> --- a/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-anacapa.dts
> +++ b/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-anacapa.dts
> @@ -912,7 +912,7 @@ &sgpiom0 {
> "PWRGD_PVDDIO_P0", "",
> "PWRGD_PVDDIO_MEM_S3_P0", "",
> "PWRGD_CHMP_CPU0_FPGA", "",
> - "PWRGD_CHIL_CPU0_FPGA", "",
> + "HPM_EDSFF_PG", "",
> "PWRGD_CHEH_CPU0_FPGA", "",
> "PWRGD_CHAD_CPU0_FPGA", "FM_BMC_READY_PLD",
> "", "",
> @@ -957,8 +957,8 @@ &sgpiom0 {
> "PDB_ALERT_R_N", "",
>
> /* L0-L7 line 176-191 */
> - "CPU0_SP7R1", "", "CPU0_SP7R2", "",
> - "CPU0_SP7R3", "", "CPU0_SP7R4", "",
> + "L_EDSFF2_PG", "", "L_EDSFF3_PG", "",
> + "R_EDSFF2_PG", "", "R_EDSFF3_PG", "",
> "CPU0_CORETYPE0", "", "CPU0_CORETYPE1", "",
> "CPU0_CORETYPE2", "", "FM_BIOS_POST_CMPLT_R_N", "",
>
> @@ -984,8 +984,8 @@ &sgpiom0 {
> "HPM_PWR_FAIL", "Port80_b0",
> "FM_DIMM_IP_FAIL", "Port80_b1",
> "FM_DIMM_AH_FAIL", "Port80_b2",
> - "HPM_AMC_THERMTRIP_R_L", "Port80_b3",
> - "FM_CPU0_THERMTRIP_N", "Port80_b4",
> + "AMC_THERMTRIP_ASSERT", "Port80_b3",
> + "CPU_THERMTRIP_ASSERT", "Port80_b4",
> "PVDDCR_SOC_P0_OCP_L", "Port80_b5",
> "CPLD_SGPIO_RDY", "Port80_b6",
> "", "Port80_b7",
>
> ---
> base-commit: 9974969c14031a097d6b45bcb7a06bb4aa525c40
> change-id: 20260430-anacapa-sgpio-edsff-thermtrip-acb228bf61be
>
> Best regards,
> --
> Rex Fu <Rex.Fu@amd.com>
>
^ permalink raw reply
* Re: [PATCH] soc: aspeed: Move MODULE_DEVICE_TABLE next to the table itself
From: Andrew Jeffery @ 2026-05-18 6:43 UTC (permalink / raw)
To: Joel Stanley, linux-arm-kernel, linux-aspeed, linux-kernel,
Krzysztof Kozlowski
In-Reply-To: <20260505102635.160772-2-krzysztof.kozlowski@oss.qualcomm.com>
On Tue, 05 May 2026 12:26:36 +0200, Krzysztof Kozlowski wrote:
> By convention MODULE_DEVICE_TABLE() immediately follows the ID table it
> exports, because this is easier to read and verify. It also makes more
> sense since #ifdef for ACPI or OF could hide both of them.
>
> Most of the privers already have this correctly placed, so adjust
> the missing ones. No functional impact.
>
> [...]
Thanks, I've applied this to the BMC tree.
--
Andrew Jeffery <andrew@codeconstruct.com.au>
^ permalink raw reply
* Re: [PATCH 2/3] memory: mtk-smi: Add a flag skip_rpm
From: Xueqi Zhang (张雪琦) @ 2026-05-18 6:42 UTC (permalink / raw)
To: robh@kernel.org, matthias.bgg@gmail.com,
Yong Wu (吴勇), AngeloGioacchino Del Regno,
krzk@kernel.org, conor+dt@kernel.org
Cc: Wendy-ST Lin (林詩庭),
linux-kernel@vger.kernel.org, linux-mediatek@lists.infradead.org,
linux-arm-kernel@lists.infradead.org, iommu@lists.linux.dev,
Project_Global_Chrome_Upstream_Group, devicetree@vger.kernel.org
In-Reply-To: <46e0e1f1-e094-40f9-99f9-22678bb40d39@collabora.com>
hi Angelo
First of all, please accept my apologies for the delayed response. I
have been deeply occupied with MT8196 Aluminium pKVM SMMU and SMI
related tasks recently.
Regarding your question, my previous description in the patch was not
accurate enough and may have caused some confusion. In fact, not all
SMI commons have their backup/restore handled by the RTFF hardware. The
SMI commons are distributed across various subsystems (e.g., mminfra,
venc, display, cam, etc.). Currently, only the SMI common under the
mminfra subsystem is backed up and restored by the RTFF hardware.
Therefore, I believe adding a specific skip_rpm flag is more
appropriate here. If we were to differentiate this based on a new
MTK_SMI_GEN3 type, it would imply that all SMI common modules of that
generation would skip the RPM operations, which is not the intended
behavior.
To make this clearer, I plan to update the commit message in the next
version as follows:
Subject: memory: mtk-smi: Add skip_rpm flag for certain MT8196 SMI
commons
Body:
On MT8196, certain SMI commons are backed up and restored by the RTFF
(Real-Time Function Fix) hardware rather than by software.
For these specific SMI commons, software-controlled register backup and
restore in the runtime callback is no longer necessary. Therefore,
introduce a skip_rpm flag to bypass these redundant RPM operations for
these SMI commons.
What do you think about this approach?
For reference, here is the link to the patch series on Patchwork:
https://patchwork.kernel.org/project/linux-mediatek/list/?series=945811&archive=both
Thanks,
Xueqi
On Thu, 2025-03-20 at 13:11 +0100, AngeloGioacchino Del Regno wrote:
> External email : Please do not click links or open attachments until
> you have verified the sender or the content.
>
>
> Il 20/03/25 08:36, Xueqi Zhang ha scritto:
> > MT8196 SMI commons is backed up/restored by RTFF HW.
> > It doesn't need SW control the register backup/store
> > in the runtime callback.Therefore, add a flag skip_rpm
> > to help skip RPM operations for SMI commons.
> >
> > Signed-off-by: Xueqi Zhang <xueqi.zhang@mediatek.com>
>
> So the MT8196 SMI common doesn't require any clocks?
>
> That's fine for me, but this looks bloody similar to MT6989's SMI
> common, which
> is SMI GEN3 and not GEN2....
>
> ....so, are you sure that you need a `skip_rpm` flag and not new
> MTK_SMI_GEN3 and
> MTK_SMI_GEN3_SUB_COMM types? :-)
>
> Regards,
> Angelo
>
> > ---
> > drivers/memory/mtk-smi.c | 11 ++++++++---
> > 1 file changed, 8 insertions(+), 3 deletions(-)
> >
> > diff --git a/drivers/memory/mtk-smi.c b/drivers/memory/mtk-smi.c
> > index a8f5467d6b31..b9affa3c3185 100644
> > --- a/drivers/memory/mtk-smi.c
> > +++ b/drivers/memory/mtk-smi.c
> > @@ -123,6 +123,7 @@ static const char * const mtk_smi_common_clks[]
> > = {"apb", "smi", "gals0", "gals1
> > struct mtk_smi_common_plat {
> > enum mtk_smi_type type;
> > bool has_gals;
> > + bool skip_rpm;
> > u32 bus_sel; /* Balance some larbs to
> > enter mmu0 or mmu1 */
> >
> > const struct mtk_smi_reg_pair *init;
> > @@ -547,6 +548,9 @@ static int mtk_smi_dts_clk_init(struct device
> > *dev, struct mtk_smi *smi,
> > {
> > int i, ret;
> >
> > + if (smi->plat->skip_rpm)
> > + return 0;
> > +
> > for (i = 0; i < clk_nr_required; i++)
> > smi->clks[i].id = clks[i];
> > ret = devm_clk_bulk_get(dev, clk_nr_required, smi->clks);
> > @@ -783,7 +787,7 @@ static int mtk_smi_common_probe(struct
> > platform_device *pdev)
> > common->dev = dev;
> > common->plat = of_device_get_match_data(dev);
> >
> > - if (common->plat->has_gals) {
> > + if (!common->plat->skip_rpm && common->plat->has_gals) {
> > if (common->plat->type == MTK_SMI_GEN2)
> > clk_required = MTK_SMI_COM_GALS_REQ_CLK_NR;
> > else if (common->plat->type == MTK_SMI_GEN2_SUB_COMM)
> > @@ -814,13 +818,14 @@ static int mtk_smi_common_probe(struct
> > platform_device *pdev)
> > }
> >
> > /* link its smi-common if this is smi-sub-common */
> > - if (common->plat->type == MTK_SMI_GEN2_SUB_COMM) {
> > + if (common->plat->type == MTK_SMI_GEN2_SUB_COMM && !common-
> > >plat->skip_rpm) {
> > ret = mtk_smi_device_link_common(dev, &common-
> > >smi_common_dev);
> > if (ret < 0)
> > return ret;
> > }
> >
> > - pm_runtime_enable(dev);
> > + if (!common->plat->skip_rpm)
> > + pm_runtime_enable(dev);
> > platform_set_drvdata(pdev, common);
> > return 0;
> > }
>
>
^ permalink raw reply
* [PATCH v2 1/1] arm64: dts: s32g: add PIT support for s32g2 and s32g3
From: Khristine Andreea Barbulescu @ 2026-05-18 6:35 UTC (permalink / raw)
To: Chester Lin, Matthias Brugger, Ghennadi Procopciuc, Frank Li,
Sascha Hauer, Fabio Estevam, Rob Herring, Krzysztof Kozlowski,
Conor Dooley
Cc: Pengutronix Kernel Team, linux-arm-kernel, imx, devicetree,
linux-kernel, NXP S32 Linux, Christophe Lizzi, Alberto Ruiz,
Enric Balletbo
In-Reply-To: <20260518063547.2890353-1-khristineandreea.barbulescu@oss.nxp.com>
Add PIT0 and PIT1 for S32G2 and S32G3 SoCs
Signed-off-by: Khristine Andreea Barbulescu <khristineandreea.barbulescu@oss.nxp.com>
---
arch/arm64/boot/dts/freescale/s32g2.dtsi | 20 +++++++++++++++++++-
arch/arm64/boot/dts/freescale/s32g3.dtsi | 20 +++++++++++++++++++-
2 files changed, 38 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/boot/dts/freescale/s32g2.dtsi b/arch/arm64/boot/dts/freescale/s32g2.dtsi
index 51d00dac12de..57ff97e44507 100644
--- a/arch/arm64/boot/dts/freescale/s32g2.dtsi
+++ b/arch/arm64/boot/dts/freescale/s32g2.dtsi
@@ -3,7 +3,7 @@
* NXP S32G2 SoC family
*
* Copyright (c) 2021 SUSE LLC
- * Copyright 2017-2021, 2024-2025 NXP
+ * Copyright 2017-2021, 2024-2026 NXP
*/
#include <dt-bindings/interrupt-controller/arm-gic.h>
@@ -417,6 +417,15 @@ edma0: dma-controller@40144000 {
clock-names = "dmamux0", "dmamux1";
};
+ pit0: pit@40188000 {
+ compatible = "nxp,s32g2-pit";
+ reg = <0x40188000 0x3000>;
+ interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks 61>;
+ clock-names = "pit";
+ status = "disabled";
+ };
+
can0: can@401b4000 {
compatible = "nxp,s32g2-flexcan";
reg = <0x401b4000 0xa000>;
@@ -622,6 +631,15 @@ edma1: dma-controller@40244000 {
clock-names = "dmamux0", "dmamux1";
};
+ pit1: pit@40288000 {
+ compatible = "nxp,s32g2-pit";
+ reg = <0x40288000 0x3000>;
+ interrupts = <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks 61>;
+ clock-names = "pit";
+ status = "disabled";
+ };
+
can2: can@402a8000 {
compatible = "nxp,s32g2-flexcan";
reg = <0x402a8000 0xa000>;
diff --git a/arch/arm64/boot/dts/freescale/s32g3.dtsi b/arch/arm64/boot/dts/freescale/s32g3.dtsi
index e314f3c7d61d..efe5398e1240 100644
--- a/arch/arm64/boot/dts/freescale/s32g3.dtsi
+++ b/arch/arm64/boot/dts/freescale/s32g3.dtsi
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
/*
- * Copyright 2021-2025 NXP
+ * Copyright 2021-2026 NXP
*
* Authors: Ghennadi Procopciuc <ghennadi.procopciuc@nxp.com>
* Ciprian Costea <ciprianmarian.costea@nxp.com>
@@ -475,6 +475,15 @@ edma0: dma-controller@40144000 {
clock-names = "dmamux0", "dmamux1";
};
+ pit0: pit@40188000 {
+ compatible = "nxp,s32g3-pit", "nxp,s32g2-pit";
+ reg = <0x40188000 0x3000>;
+ interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks 61>;
+ clock-names = "pit";
+ status = "disabled";
+ };
+
can0: can@401b4000 {
compatible = "nxp,s32g3-flexcan",
"nxp,s32g2-flexcan";
@@ -693,6 +702,15 @@ edma1: dma-controller@40244000 {
clock-names = "dmamux0", "dmamux1";
};
+ pit1: pit@40288000 {
+ compatible = "nxp,s32g3-pit", "nxp,s32g2-pit";
+ reg = <0x40288000 0x3000>;
+ interrupts = <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks 61>;
+ clock-names = "pit";
+ status = "disabled";
+ };
+
can2: can@402a8000 {
compatible = "nxp,s32g3-flexcan",
"nxp,s32g2-flexcan";
--
2.34.1
^ permalink raw reply related
* [PATCH v2 0/1] add PIT DTS support for S32G2/S32G3 SoCs
From: Khristine Andreea Barbulescu @ 2026-05-18 6:35 UTC (permalink / raw)
To: Chester Lin, Matthias Brugger, Ghennadi Procopciuc, Frank Li,
Sascha Hauer, Fabio Estevam, Rob Herring, Krzysztof Kozlowski,
Conor Dooley
Cc: Pengutronix Kernel Team, linux-arm-kernel, imx, devicetree,
linux-kernel, NXP S32 Linux, Christophe Lizzi, Alberto Ruiz,
Enric Balletbo
This patchset aims to add one change to the S32G2/S32G3 dtsi support:
- Add PIT dts support for S32G SoC based boards
v2 -> v1:
- Drop the redundant PIT example from the binding
Khristine Andreea Barbulescu (1):
arm64: dts: s32g: add PIT support for s32g2 and s32g3
arch/arm64/boot/dts/freescale/s32g2.dtsi | 20 +++++++++++++++++++-
arch/arm64/boot/dts/freescale/s32g3.dtsi | 20 +++++++++++++++++++-
2 files changed, 38 insertions(+), 2 deletions(-)
--
2.34.1
^ permalink raw reply
* Re: [PATCH 1/1] ARM: dts: aspeed: msx4: enable BMC networking via MAC0
From: Andrew Jeffery @ 2026-05-18 6:35 UTC (permalink / raw)
To: Ender Hsieh, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Joel Stanley
Cc: devicetree, linux-arm-kernel, linux-aspeed, linux-kernel,
Andrew Lunn, Marc Olberding, Jacky Chou
In-Reply-To: <20260505050541.3031447-2-andhsieh@nvidia.com>
On Tue, 2026-05-05 at 14:05 +0900, Ender Hsieh wrote:
> Add &mac0, &mdio3, and the ethphy3 PHY node to enable BMC networking
> on the AST2600-based NVIDIA MSX4 board. The PHY is attached to MDIO3
> at address 2 and uses RGMII with PHY-internal delays.
>
> These nodes were intentionally omitted in commit f28674fab34f ("ARM:
> dts: aspeed: Add NVIDIA MSX4 HPM") at Andrew Lunn's request, pending
> clarification of the RGMII delay handling. Following his guidance on
> linux-aspeed, the bootloader has been modified to stop enabling MAC
> clock delays on the SoC side, so phy-mode = "rgmii-id" correctly
> results in the PHY adding the required ~2ns delay without any
> double-delay from the MAC controller.
>
> The corresponding U-Boot change has been submitted to openbmc/u-boot.
>
> Link: https://patch.msgid.link/eac09481-0ba1-4ac2-ad8c-d859822ff0d5@lunn.ch
> Link: https://patch.msgid.link/20260504044702.2613879-1-andhsieh@nvidia.com
> Cc: Andrew Lunn <andrew@lunn.ch>
> Cc: Marc Olberding <molberding@nvidia.com>
> Signed-off-by: Ender Hsieh <andhsieh@nvidia.com>
> ---
> .../dts/aspeed/aspeed-bmc-nvidia-msx4-bmc.dts | 15 +++++++++++++++
> 1 file changed, 15 insertions(+)
>
I've applied this to the BMC tree. I've also applied the linked u-boot
patch to openbmc/u-boot, and backported this change to openbmc/linux.
Cheers,
Andrew
^ permalink raw reply
* Re: [PATCH v5 1/3] firmware: smccc: coco: Manage arm-smccc platform device and CCA auxiliary drivers
From: Aneesh Kumar K.V @ 2026-05-18 6:29 UTC (permalink / raw)
To: Greg KH
Cc: Suzuki K Poulose, linux-coco, linux-arm-kernel, linux-kernel,
Catalin Marinas, Jeremy Linton, Jonathan Cameron,
Lorenzo Pieralisi, Mark Rutland, Sudeep Holla, Will Deacon,
Steven Price
In-Reply-To: <2026051404-headboard-cabbage-e09a@gregkh>
Greg KH <gregkh@linuxfoundation.org> writes:
> On Thu, May 14, 2026 at 08:07:27PM +0530, Aneesh Kumar K.V wrote:
>> Greg KH <gregkh@linuxfoundation.org> writes:
>>
>> > On Thu, May 14, 2026 at 12:04:13PM +0100, Suzuki K Poulose wrote:
>> >> Hi Aneesh
>> >>
>> >> On 14/05/2026 10:40, Aneesh Kumar K.V (Arm) wrote:
>> >> > Make the SMCCC driver responsible for registering the arm-smccc platform
>> >> > device and after confirming the relevant SMCCC function IDs, create
>> >> > the arm_cca_guest auxiliary device.
>> >> >
>> >>
>> >> There are a few changes squashed in to this patch. Please could we
>> >> split the patch in the following order ?
>> >>
>> >> 1. Add platform device for arm-smccc
>> >
>> > Do not make any more "fake" platform devices please.
>> >
>> >> 2. Move TRNG to Auxilliary Device - (Even though it is a later patch, move
>> >> it before the RSI changes)
>> >
>> > No, move it to the faux api please.
>> >
>>
>>
>> Maybe I was not complete in my previous reply. I did not want to repeat
>> the entire thread, so I quoted the lore link for more details.
>>
>> 1. We have platform firmware-provided SMCCC interfaces. Based on the
>> support/availability of these function IDs, we want to load multiple
>> drivers.
>> 2. This patch series adds a platform device to represent the
>> firmware-provided SMCCC resource.
>> 3. Different SMCCC ranges are now represented as auxiliary devices.
>> 4. Different subsystems, such as TSM, can autoload their backend drivers
>> based on the availability of these SMCCC ranges, which are now
>> represented as auxiliary devices.
>>
>> You had agreed to all of this in the previous discussion here:
>> https://lore.kernel.org/all/2025101516-handbook-hyphen-62ec@gregkh
>
> Then why did someone say "this is a fake platform device with no actual
> resources"? That's what I was triggering off of.
>
> Again, if you have actual platform resources, GREAT, use a platform
> device and aux. If you do not, then do NOT use a platform device.
>
> totally confused,
>
> greg k-h
I have now rewritten the cover letter as below. Let me know if this
helps.
Switch Arm SMCCC firmware services to auxiliary devices
As discussed here:
https://lore.kernel.org/all/20250728135216.48084-12-aneesh.kumar@kernel.org
The earlier CCA guest support used an arm-cca-dev platform device as a pure
software anchor for the TSM class device. That platform device did not
correspond to a DT/ACPI described device, MMIO range, interrupt, or other
platform resource; it existed only to make the CCA guest driver bind and to
place the resulting TSM device in the driver model. The same pattern also
exists for smccc_trng. Creating separate platform devices for such
SMCCC-discovered features is misleading, because those features are not
independent platform devices.
This series changes the model so that there is a single arm-smccc platform
device representing the SMCCC firmware interface itself. The firmware
interface, including its discoverable SMCCC function space, is the
resource: after PSCI/SMCCC conduit discovery, the kernel can query SMCCC
function IDs and determine whether optional firmware services are present.
Services such as SMCCC TRNG and Realm Services Interface (RSI) are
therefore represented as children of the arm-smccc device, and are created
only when the required SMCCC function IDs and ABI checks succeed.
The child devices use the auxiliary bus deliberately: they are intended to
bind independent feature drivers, not just to provide a driverless object for
sysfs or other class-device anchoring. They are firmware-provided functions
of the parent SMCCC interface that are consumed by separate kernel drivers
in different subsystems, such as hwrng and virt/coco/TSM. Those drivers
need normal driver-core matching, probe/remove lifetime, and module
autoloading based on the discovered firmware feature. The auxiliary bus
provides a MODALIAS and id-table based binding model for that case, while
keeping the feature drivers off the platform bus. A faux device was
considered, but not used because it is suited for simple software objects
that do not need independent bus/driver binding. The faux bus has no
feature-driver id-table or MODALIAS matching, so it would not preserve the
module-autoload flow that the current platform-device based users rely on.
In other words, the parent arm-smccc device represents the firmware
resource exposed through the SMCCC conduit, and each auxiliary child
represents one discovered firmware service of that parent. This removes the
unnecessary per-feature platform devices while retaining automatic loading
and independent subsystem drivers for the SMCCC services.
The TSM framework uses the device abstraction to provide cross-architecture
TSM and TEE I/O functionality, including enumerating available platform TEE
I/O capabilities and provisioning connections between the platform TSM and
device DSMs. For Arm CCA, the RSI auxiliary device continues to provide the
device anchor used by the CCA guest TSM provider.
For the CCA platform, the resulting device hierarchy appears as follows.
Note that the auxiliary device is parented by the arm-smccc platform device,
so the sysfs path remains under /devices/platform/arm-smccc/:
$ cd /sys/class/tsm/
$ ls -al
total 0
drwxr-xr-x 2 root root 0 Jan 1 00:02 .
drwxr-xr-x 23 root root 0 Jan 1 00:00 ..
lrwxrwxrwx 1 root root 0 Jan 1 00:03 tsm0 -> ../../devices/platform/arm-smccc/arm_cca_guest.arm-rsi-dev.0/tsm/tsm0
$
The series also replaces the old arm-cca-dev userspace-visible dummy device
with /sys/firmware/cca/realm_guest for detecting whether the kernel is
running in a Realm. This keeps the guest-state ABI under /sys/firmware and
separates it from the internal driver-binding device used by the CCA guest
TSM provider.
-aneesh
^ permalink raw reply
* Re: [PATCH v7 0/4] PCI: Add support for resetting the Root Ports in a platform specific way
From: Manivannan Sadhasivam @ 2026-05-18 6:21 UTC (permalink / raw)
To: Niklas Cassel
Cc: manivannan.sadhasivam, Bjorn Helgaas, Mahesh J Salgaonkar,
Oliver O'Halloran, Will Deacon, Lorenzo Pieralisi,
Krzysztof Wilczyński, Rob Herring, Heiko Stuebner,
Philipp Zabel, linux-pci, linux-kernel, linuxppc-dev,
linux-arm-kernel, linux-arm-msm, linux-rockchip, Wilfred Mallawa,
Krishna Chaitanya Chundru, Lukas Wunner, Richard Zhu,
Brian Norris, Wilson Ding, Frank Li
In-Reply-To: <abk3rU2EDKjkefUD@ryzen>
On Tue, Mar 17, 2026 at 12:16:47PM +0100, Niklas Cassel wrote:
> On Wed, Mar 11, 2026 at 08:44:15PM +0530, Manivannan Sadhasivam wrote:
> > On Wed, Mar 11, 2026 at 08:09:53PM +0530, Manivannan Sadhasivam wrote:
> > > On Wed, Mar 11, 2026 at 12:05:15PM +0100, Niklas Cassel wrote:
> > > > On Tue, Mar 10, 2026 at 07:31:58PM +0530, Manivannan Sadhasivam via B4 Relay wrote:
> > > > > Changes in v7:
> > > > > - Dropped Rockchip Root port reset patch due to reported issues. But the series
> > > > > works on other platforms as tested by others.
> > > >
> > > > Are you referring to
> > > >
> > > > ## On EP side:
> > > > # echo 0 > /sys/kernel/config/pci_ep/controllers/a40000000.pcie-ep/start && \
> > > > sleep 0.1 && echo 1 > /sys/kernel/config/pci_ep/controllers/a40000000.pcie-ep/start
> > > >
> > > > Then running pcitest only having 7 / 16 tests passed ?
> > > >
> > > > If so, isn't that a problem also for qcom?
> > > >
> > >
> > > No, tests are passing on my setup after link up.
> > >
> > > >
> > > > There is no chance that the patch:
> > > > "misc: pci_endpoint_test: Add AER error handlers"
> > > > improves things in this regard?
> > > >
> > > > Or will it simply avoid the "AER: device recovery failed" print?
> > > >
> > >
> > > Yes, as mentioned in the commit message, it just avoids the AER recovery failure
> > > message.
> > >
> >
> > I also realized that Endpoint state is not saved in all the code paths. So the
> > pci_endpoint_test driver has to save/restore the state also. But it is still not
> > clear why that didn't help you.
> >
> > Can you share the snapshot of the entire config space before and after reset
> > using 'lspci -xxxx -s "0000:01:00"'?
>
> If I don't add something like:
>
> diff --git a/drivers/misc/pci_endpoint_test.c b/drivers/misc/pci_endpoint_test.c
> index 1eced7a419eb..9d7ee39164d4 100644
> --- a/drivers/misc/pci_endpoint_test.c
> +++ b/drivers/misc/pci_endpoint_test.c
> @@ -1059,6 +1059,9 @@ static int pci_endpoint_test_set_irq(struct pci_endpoint_test *test,
> return ret;
> }
>
> + pr_info("saving PCI state (irq_type: %d)\n", req_irq_type);
> + pci_save_state(pdev);
> +
> return 0;
> }
>
> @@ -1453,6 +1456,7 @@ static pci_ers_result_t pci_endpoint_test_error_detected(struct pci_dev *pdev,
>
> static pci_ers_result_t pci_endpoint_test_slot_reset(struct pci_dev *pdev)
> {
> + pci_restore_state(pdev);
> return PCI_ERS_RESULT_RECOVERED;
> }
>
> On top of your patch.
>
> Then all the BAR tests + MSI and MSI-X tests fail.
>
> There is a huge difference in lspci -vvv output (as I guess is expected),
> including all BARs being marked as disabled.
>
>
> With the patch above. There is zero difference before/after reset, and all
> the BAR tests pass. However, MSI/MSI-X tests still fail with:
>
> # pci_endpoint_test.c:143:MSI_TEST:Expected 0 (0) == ret (-110)
> # pci_endpoint_test.c:143:MSI_TEST:Test failed for MSI1
>
> ETIMEDOUT.
>
> This suggests that pci_endpoint_test on the host side did not receive an
> interrupt.
>
> I don't know why, but considering that lspci output is now (with the
> save+restore) identical, I assume that the problem is not related to
> the host. Unless somehow the host will use a new/different MSI address
> after the root port has been reset, and we restore the old MSI address,
> but looking at the code, dw_pcie_msi_init() is called by
> dw_pcie_setup_rc(), so I would expect the MSI address to be the same.
>
Hi Niklas,
When I rebased this series on top of v7.1-rc1, I ended up seeing the issue what
you described here (not sure why I didn't see it earlier). So after the Root
Port reset, MSI tests fail, but BAR tests succeed. Also, I got IOMMU faults on
the host after endpoint triggers MSI.
I investigated it and found that the MSI iATU mapping gets cleared in hw after
LDn happens. But the host continues to use the same address/size for the
endpoint MSI even after reset. Due to this, the existing checks in
dw_pcie_ep_raise_msi_irq() don't pass and the stale MSI iATU mapping gets
reused.
The fix would be to clear the mapping in dw_pcie_ep_cleanup(), which gets called
as part of the PERST# assert/deassert sequence post LDn and also set
msi_iatu_mapped flag to 'false'. This will force dw_pcie_ep_raise_msi_irq() to
use fresh iATU mapping when it gets called for the first time:
diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c b/drivers/pci/controller/dwc/pcie-designware-ep.c
index d4dc3b24da60..4ae0e1b55f39 100644
--- a/drivers/pci/controller/dwc/pcie-designware-ep.c
+++ b/drivers/pci/controller/dwc/pcie-designware-ep.c
@@ -1035,6 +1035,11 @@ void dw_pcie_ep_cleanup(struct dw_pcie_ep *ep)
{
struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
+ if (ep->msi_iatu_mapped) {
+ dw_pcie_ep_unmap_addr(ep->epc, 0, 0, ep->msi_mem_phys);
+ ep->msi_iatu_mapped = false;
+ }
+
dwc_pcie_debugfs_deinit(pci);
dw_pcie_edma_remove(pci);
}
With this change, MSI works after Root Port reset without any issues on our Qcom
endpoint/host setup.
Please test this change on your rockchip setup as well. You have to make sure
that dw_pcie_ep_cleanup() is called during PERST# assert/deassert.
I'm going to respin the series with this fix. If you confirm it works for you,
then we can merge your Rockchip Root Port change.
- Mani
--
மணிவண்ணன் சதாசிவம்
^ permalink raw reply related
* [PATCH 1/1] arm64: dts: Add usbphynop and usbotg pinctrl for S32G platforms
From: Khristine Andreea Barbulescu @ 2026-05-18 6:15 UTC (permalink / raw)
To: Chester Lin, Matthias Brugger, Ghennadi Procopciuc, Frank Li,
Sascha Hauer, Fabio Estevam, Rob Herring, Krzysztof Kozlowski,
Conor Dooley
Cc: Pengutronix Kernel Team, linux-arm-kernel, imx, devicetree,
linux-kernel, NXP S32 Linux, Christophe Lizzi, Alberto Ruiz,
Enric Balletbo
In-Reply-To: <20260518061522.2884441-1-khristineandreea.barbulescu@oss.nxp.com>
Add the usbphynop node and the usbotg pinctrl
support for the S32G2 and S32G3 SoCs.
This enables the USB controller to reference the
generic PHY and use the required pinmux for USB OTG ops.
Signed-off-by: Khristine Andreea Barbulescu <khristineandreea.barbulescu@oss.nxp.com>
---
.../boot/dts/freescale/s32gxxxa-evb.dtsi | 53 ++++++++++++++++++-
.../boot/dts/freescale/s32gxxxa-rdb.dtsi | 53 ++++++++++++++++++-
2 files changed, 104 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/boot/dts/freescale/s32gxxxa-evb.dtsi b/arch/arm64/boot/dts/freescale/s32gxxxa-evb.dtsi
index 803ff4531077..d096744cdb0f 100644
--- a/arch/arm64/boot/dts/freescale/s32gxxxa-evb.dtsi
+++ b/arch/arm64/boot/dts/freescale/s32gxxxa-evb.dtsi
@@ -1,12 +1,19 @@
// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
/*
- * Copyright 2024 NXP
+ * Copyright 2024, 2026 NXP
*
* Authors: Ciprian Marian Costea <ciprianmarian.costea@oss.nxp.com>
* Ghennadi Procopciuc <ghennadi.procopciuc@oss.nxp.com>
* Larisa Grigore <larisa.grigore@nxp.com>
*/
+/ {
+ usbphynop: usbphynop {
+ compatible = "usb-nop-xceiv";
+ #phy-cells = <0>;
+ };
+};
+
&pinctrl {
can0_pins: can0-pins {
can0-grp0 {
@@ -245,6 +252,39 @@ dspi5-grp4 {
bias-pull-up;
};
};
+
+ usbotg_pins: usbotg_pins {
+ usbotg_grp0 {
+ pinmux = <0x3802>, <0x3812>,
+ <0x3822>, <0x3832>,
+ <0x3842>, <0x3852>,
+ <0x3862>, <0x3872>,
+ <0x37f2>, <0x3882>,
+ <0x3892>;
+ };
+
+ usbotg_grp1 {
+ pinmux = <0x3e1>, <0x3f1>,
+ <0x401>, <0x411>,
+ <0xbc1>, <0xbd1>,
+ <0xbe1>, <0x701>;
+ output-enable;
+ input-enable;
+ slew-rate = <208>;
+ };
+
+ usbotg_grp2 {
+ pinmux = <0xb80>, <0xb90>, <0xbb0>;
+ input-enable;
+ slew-rate = <208>;
+ };
+
+ usbotg_grp3 {
+ pinmux = <0xba1>;
+ output-enable;
+ slew-rate = <208>;
+ };
+ };
};
&can0 {
@@ -304,3 +344,14 @@ &spi5 {
pinctrl-names = "default";
status = "okay";
};
+
+&usbmisc {
+ status = "okay";
+};
+
+&usbotg {
+ pinctrl-names = "default";
+ pinctrl-0 = <&usbotg_pins>;
+ fsl,usbphy = <&usbphynop>;
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/freescale/s32gxxxa-rdb.dtsi b/arch/arm64/boot/dts/freescale/s32gxxxa-rdb.dtsi
index 979868f6d2c5..b756bcf6469d 100644
--- a/arch/arm64/boot/dts/freescale/s32gxxxa-rdb.dtsi
+++ b/arch/arm64/boot/dts/freescale/s32gxxxa-rdb.dtsi
@@ -1,12 +1,19 @@
// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
/*
- * Copyright 2024 NXP
+ * Copyright 2024, 2026 NXP
*
* Authors: Ciprian Marian Costea <ciprianmarian.costea@oss.nxp.com>
* Ghennadi Procopciuc <ghennadi.procopciuc@oss.nxp.com>
* Larisa Grigore <larisa.grigore@nxp.com>
*/
+/ {
+ usbphynop: usbphynop {
+ compatible = "usb-nop-xceiv";
+ #phy-cells = <0>;
+ };
+};
+
&pinctrl {
can0_pins: can0-pins {
can0-grp0 {
@@ -199,6 +206,39 @@ dspi5-grp4 {
bias-pull-up;
};
};
+
+ usbotg_pins: usbotg_pins {
+ usbotg_grp0 {
+ pinmux = <0x3802>, <0x3812>,
+ <0x3822>, <0x3832>,
+ <0x3842>, <0x3852>,
+ <0x3862>, <0x3872>,
+ <0x37f2>, <0x3882>,
+ <0x3892>;
+ };
+
+ usbotg_grp1 {
+ pinmux = <0x3e1>, <0x3f1>,
+ <0x401>, <0x411>,
+ <0xbc1>, <0xbd1>,
+ <0xbe1>, <0x701>;
+ output-enable;
+ input-enable;
+ slew-rate = <208>;
+ };
+
+ usbotg_grp2 {
+ pinmux = <0xb80>, <0xb90>, <0xbb0>;
+ input-enable;
+ slew-rate = <208>;
+ };
+
+ usbotg_grp3 {
+ pinmux = <0xba1>;
+ output-enable;
+ slew-rate = <208>;
+ };
+ };
};
&can0 {
@@ -257,3 +297,14 @@ &i2c4 {
pinctrl-1 = <&i2c4_gpio_pins>;
status = "okay";
};
+
+&usbmisc {
+ status = "okay";
+};
+
+&usbotg {
+ pinctrl-names = "default";
+ pinctrl-0 = <&usbotg_pins>;
+ fsl,usbphy = <&usbphynop>;
+ status = "okay";
+};
--
2.34.1
^ permalink raw reply related
* [PATCH 0/1] add USB PHY node and USB OTG pinctrl support to S32G2/S32G3 SoCs
From: Khristine Andreea Barbulescu @ 2026-05-18 6:15 UTC (permalink / raw)
To: Chester Lin, Matthias Brugger, Ghennadi Procopciuc, Frank Li,
Sascha Hauer, Fabio Estevam, Rob Herring, Krzysztof Kozlowski,
Conor Dooley
Cc: Pengutronix Kernel Team, linux-arm-kernel, imx, devicetree,
linux-kernel, NXP S32 Linux, Christophe Lizzi, Alberto Ruiz,
Enric Balletbo
This patchset aims to add two changes to the S32G2/S32G3 dtsi support:
- Add the usbphynop node for S32G SoC based boards
- Add the usbotg pinctrl support for S32G SoC based boards
Khristine Andreea Barbulescu (1):
arm64: dts: Add usbphynop and usbotg pinctrl for S32G platforms
.../boot/dts/freescale/s32gxxxa-evb.dtsi | 53 ++++++++++++++++++-
.../boot/dts/freescale/s32gxxxa-rdb.dtsi | 53 ++++++++++++++++++-
2 files changed, 104 insertions(+), 2 deletions(-)
--
2.34.1
^ permalink raw reply
* Re: [PATCH v6 4/5] ARM: dts: microchip: add I3C controller
From: Manikandan.M @ 2026-05-18 6:10 UTC (permalink / raw)
To: claudiu.beznea
Cc: alexandre.belloni, Frank.Li, robh, krzk+dt, conor+dt,
Nicolas.Ferre, linux, mturquette, sboyd, tytso, Aubin.Constans,
Ryan.Wanner, Romain.Sioen, durai.manickamkr, Cristian.Birsan,
adrian.hunter, jarkko.nikula, npitre, linux-i3c, devicetree,
linux-kernel, linux-arm-kernel, linux-clk
In-Reply-To: <da83523d-f3ac-42e3-83a2-fb7e7d64ebf9@tuxon.dev>
Hi Claudiu,
On 16/05/26 9:37 pm, Claudiu Beznea wrote:
> EXTERNAL EMAIL: Do not click links or open attachments unless you know
> the content is safe
>
> Hi, Manikandan,
>
> On 5/7/26 11:48, Manikandan Muralidharan wrote:
>> From: Durai Manickam KR <durai.manickamkr@microchip.com>
>>
>> Add I3C controller for sama7d65 SoC.
>>
>> Signed-off-by: Durai Manickam KR <durai.manickamkr@microchip.com>
>> Signed-off-by: Manikandan Muralidharan <manikandan.m@microchip.com>
>> ---
>> Changes in v3:
>> - Remove clock-names property as driver enables the clk in bulk
>>
>> arch/arm/boot/dts/microchip/sama7d65.dtsi | 8 ++++++++
>> 1 file changed, 8 insertions(+)
>>
>> diff --git a/arch/arm/boot/dts/microchip/sama7d65.dtsi
>> b/arch/arm/boot/dts/microchip/sama7d65.dtsi
>> index 67253bbc08df..ec200848c153 100644
>> --- a/arch/arm/boot/dts/microchip/sama7d65.dtsi
>> +++ b/arch/arm/boot/dts/microchip/sama7d65.dtsi
>> @@ -1055,5 +1055,13 @@ gic: interrupt-controller@e8c11000 {
>> #address-cells = <0>;
>> interrupt-controller;
>> };
>> +
>> + i3c: i3c@e9000000 {
>> + compatible = "microchip,sama7d65-i3c-hci";
>> + reg = <0xe9000000 0x300>;
>
> From manual at [1] I see the size of I3CC region is 0x1000. Unless that is
> wrong I think we should use 0x1000 to properly describe de HW. Please
> let me
> know and I can do it while applying.
>
According to Table 78.6 (Register Summary), the I3CC register space
extends up to offset 0x258, Ideally the mapping should have been 0x400
(next power of 2 considering the memory region alignment), using 0x1000
is also acceptable. Please advise which value is preferred.
> Thank you,
> Claudiu
>
> [1]
> https://ww1.microchip.com/downloads/aemDocuments/documents/MPU32/ProductDocuments/DataSheets/SAMA7D6-Series-Data-Sheet-DS60001851.pdf
>
>> + interrupts = <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>;
>> + clocks = <&pmc PMC_TYPE_PERIPHERAL 105>, <&pmc
>> PMC_TYPE_GCK 105>;
>> + status = "disabled";
>> + };
>> };
>> };
>
--
Thanks and Regards,
Manikandan M.
^ permalink raw reply
* Re: [PATCH] KVM: arm64: vgic-its: reject restored DTE with out-of-range num_eventid_bits
From: Yao Yuan @ 2026-05-18 6:05 UTC (permalink / raw)
To: Michael Bommarito
Cc: Marc Zyngier, Oliver Upton, Joey Gouly, Suzuki K Poulose,
Zenghui Yu, Catalin Marinas, Will Deacon, linux-arm-kernel,
kvmarm, linux-kernel
In-Reply-To: <20260517174955.273004-1-michael.bommarito@gmail.com>
On Sun, May 17, 2026 at 01:49:55PM +0800, Michael Bommarito wrote:
> Userspace can trigger a host-side denial of service via
> KVM_DEV_ARM_ITS_RESTORE_TABLES. A Device Table Entry whose Size
> field encodes num_eventid_bits > VITS_TYPER_IDBITS reaches
> scan_its_table() with a sign-extended ~18 EiB length, where the
> loop holds the per-ITS mutex and never calls cond_resched(),
> pinning a host CPU for a time linear in registered guest memslot
> size. The accessor is any process that can open /dev/kvm and
> create a VM. The same out-of-range value also disables a
> subsequent live bounds check on EventID, as described below.
>
> The MAPD command handler already rejects this case in the live
> path:
>
> if (valid && num_eventid_bits > VITS_TYPER_IDBITS)
> return E_ITS_MAPD_ITTSIZE_OOR;
>
> vgic_its_restore_dte() reconstructs num_eventid_bits from the DTE
> Size field but does not apply the same cap, so userspace can
> install device state that the live MAPD path is documented to
> reject. The restored value is stored in dev->num_eventid_bits and
> is then used by vgic_its_restore_itt():
>
> size_t max_size = BIT_ULL(dev->num_eventid_bits) * ite_esz;
> ret = scan_its_table(its, base, max_size, ite_esz, ...);
>
> scan_its_table() takes the size as int and assigns it to
> unsigned long in the callee:
>
> static int scan_its_table(struct vgic_its *its, gpa_t base,
> int size, u32 esz, ...)
> {
> unsigned long len = size;
>
> For num_eventid_bits = 28 the size_t value 0x80000000 truncates to
> INT_MIN as int and sign-extends to ~18 EiB as unsigned long. The
> scan loop then walks the registered guest memslot one ite_esz at
> a time with the per-ITS mutex held and no cond_resched(). In a
> QEMU TCG arm64 guest at EL2 on v7.1-rc1, with an empty ITT, the
> ioctl returned -EFAULT after about 14 seconds with a 256 MiB
> memslot and about 56 seconds with a 1 GiB memslot (linear in
> memslot size). The per-iteration cost on native arm64 KVM
> hardware will differ; the loop shape, and so the linear scaling,
> will not.
>
> The same out-of-range num_eventid_bits also disables the live
> vgic_its_check_event_id() bounds check, because event_id is u32
> and BIT_ULL(32) is unreachable in that comparison, leaving
> subsequent MAPI/MAPTI handling without an effective EventID cap.
>
> Mirror the MAPD cap in vgic_its_restore_dte() before allocating
> the device, so out-of-range restored DTEs are rejected with
> -EINVAL up front rather than triggering the int-truncated scan or
> installing a device whose num_eventid_bits silently disables the
> live bounds check. Sizes within [1, VITS_TYPER_IDBITS] are
> unaffected.
>
> Fixes: 57a9a117154c ("KVM: arm64: vgic-its: Device table save/restore")
> Assisted-by: Claude:claude-opus-4-7
> Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
> ---
> arch/arm64/kvm/vgic/vgic-its.c | 9 +++++++++
> 1 file changed, 9 insertions(+)
>
> diff --git a/arch/arm64/kvm/vgic/vgic-its.c b/arch/arm64/kvm/vgic/vgic-its.c
> index 2ea9f1c7ebcd0..a5dcf9a6a2854 100644
> --- a/arch/arm64/kvm/vgic/vgic-its.c
> +++ b/arch/arm64/kvm/vgic/vgic-its.c
> @@ -2307,6 +2307,15 @@ static int vgic_its_restore_dte(struct vgic_its *its, u32 id,
> /* dte entry is valid */
> offset = (entry & KVM_ITS_DTE_NEXT_MASK) >> KVM_ITS_DTE_NEXT_SHIFT;
>
> + /*
> + * The MAPD command rejects this case; mirror the cap here so a
> + * restored DTE cannot install an out-of-range num_eventid_bits
> + * that vgic_its_restore_itt() would then convert into a
> + * sign-extended scan_its_table() length.
> + */
> + if (num_eventid_bits > VITS_TYPER_IDBITS)
> + return -EINVAL;
Hi,
IIUC, the same issue is still there when VITS_TYPER_IDBITS
change to >=28, I know it's limited to 16 in GITS_TYPER's
definition. I mean the issue is still there w/o really be
fixed.
Change the scan_its_table() and other related code path to
avoid such date conversion issue is more reasonable
fixing to me, please also wait others' input yet.
> +
> if (!vgic_its_check_id(its, baser, id, NULL))
> return -EINVAL;
>
> --
> 2.53.0
>
^ permalink raw reply
* [PATCH] media: meson: vdec: avoid double free on video register failure
From: Guangshuo Li @ 2026-05-18 5:43 UTC (permalink / raw)
To: Neil Armstrong, Mauro Carvalho Chehab, Greg Kroah-Hartman,
Kevin Hilman, Jerome Brunet, Martin Blumenstingl, Maxime Jourdan,
Hans Verkuil, linux-media, linux-amlogic, linux-staging,
linux-arm-kernel, linux-kernel
Cc: Guangshuo Li
vdec_probe() allocates a video_device with video_device_alloc() and
releases it from the err_vdev_release error path if
video_register_device() fails.
This can double free the video_device when __video_register_device()
reaches device_register() and that call fails:
video_register_device()
-> __video_register_device()
-> device_register() fails
-> put_device(&vdev->dev)
-> v4l2_device_release()
-> vdev->release(vdev)
-> video_device_release(vdev)
vdec_probe()
-> err_vdev_release
-> video_device_release(vdev)
Use video_device_release_empty() while registering the device so that
registration failure paths do not free vdev through vdev->release().
vdec_probe() then releases vdev exactly once from err_vdev_release.
Restore video_device_release() after successful registration so the
registered device keeps its normal lifetime handling.
This issue was found by a static analysis tool I am developing.
Fixes: 3e7f51bd9607 ("media: meson: add v4l2 m2m video decoder driver")
Signed-off-by: Guangshuo Li <lgs201920130244@gmail.com>
---
drivers/staging/media/meson/vdec/vdec.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/staging/media/meson/vdec/vdec.c b/drivers/staging/media/meson/vdec/vdec.c
index 4b77ec1af5a7..2994e46cbc25 100644
--- a/drivers/staging/media/meson/vdec/vdec.c
+++ b/drivers/staging/media/meson/vdec/vdec.c
@@ -1074,7 +1074,7 @@ static int vdec_probe(struct platform_device *pdev)
mutex_init(&core->lock);
strscpy(vdev->name, "meson-video-decoder", sizeof(vdev->name));
- vdev->release = video_device_release;
+ vdev->release = video_device_release_empty;
vdev->fops = &vdec_fops;
vdev->ioctl_ops = &vdec_ioctl_ops;
vdev->vfl_dir = VFL_DIR_M2M;
@@ -1089,6 +1089,7 @@ static int vdec_probe(struct platform_device *pdev)
dev_err(dev, "Failed registering video device\n");
goto err_vdev_release;
}
+ vdev->release = video_device_release;
return 0;
--
2.43.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