* [PATCH 3/3] ASoC: rockchip: rockchip_pdm: Reorder clock enable sequence
From: phucduc.bui @ 2026-05-22 10:03 UTC (permalink / raw)
To: broonie
Cc: lgirdwood, perex, tiwai, heiko, linux-arm-kernel, linux-kernel,
linux-sound, linux-rockchip, robh, krzk+dt, conor+dt, devicetree,
bui duc phuc
In-Reply-To: <20260522100318.73474-1-phucduc.bui@gmail.com>
From: bui duc phuc <phucduc.bui@gmail.com>
Enable the 'hclk' bus clock before the 'clk' controller
clock during runtime resume.
The bus clock provides the register access interface and
should be enabled before the controller clock.
Signed-off-by: bui duc phuc <phucduc.bui@gmail.com>
---
sound/soc/rockchip/rockchip_pdm.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/sound/soc/rockchip/rockchip_pdm.c b/sound/soc/rockchip/rockchip_pdm.c
index c69cdd6f2499..8f78f7bc1806 100644
--- a/sound/soc/rockchip/rockchip_pdm.c
+++ b/sound/soc/rockchip/rockchip_pdm.c
@@ -422,16 +422,16 @@ static int rockchip_pdm_runtime_resume(struct device *dev)
struct rk_pdm_dev *pdm = dev_get_drvdata(dev);
int ret;
- ret = clk_prepare_enable(pdm->clk);
+ ret = clk_prepare_enable(pdm->hclk);
if (ret) {
- dev_err(pdm->dev, "clock enable failed %d\n", ret);
+ dev_err(pdm->dev, "hclock enable failed %d\n", ret);
return ret;
}
- ret = clk_prepare_enable(pdm->hclk);
+ ret = clk_prepare_enable(pdm->clk);
if (ret) {
- clk_disable_unprepare(pdm->clk);
- dev_err(pdm->dev, "hclock enable failed %d\n", ret);
+ clk_disable_unprepare(pdm->hclk);
+ dev_err(pdm->dev, "clock enable failed %d\n", ret);
return ret;
}
--
2.43.0
^ permalink raw reply related
* [PATCH 2/3] ASoC: rockchip: spdif: Reorder clock enable sequence
From: phucduc.bui @ 2026-05-22 10:03 UTC (permalink / raw)
To: broonie
Cc: lgirdwood, perex, tiwai, heiko, linux-arm-kernel, linux-kernel,
linux-sound, linux-rockchip, robh, krzk+dt, conor+dt, devicetree,
bui duc phuc
In-Reply-To: <20260522100318.73474-1-phucduc.bui@gmail.com>
From: bui duc phuc <phucduc.bui@gmail.com>
Enable the 'hclk' bus clock before the 'mclk' controller
clock during runtime resume.
The bus clock provides the register access interface and
should be enabled before the controller clock.
Signed-off-by: bui duc phuc <phucduc.bui@gmail.com>
---
sound/soc/rockchip/rockchip_spdif.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/sound/soc/rockchip/rockchip_spdif.c b/sound/soc/rockchip/rockchip_spdif.c
index 581624f2682e..8de5b76cfe79 100644
--- a/sound/soc/rockchip/rockchip_spdif.c
+++ b/sound/soc/rockchip/rockchip_spdif.c
@@ -76,16 +76,16 @@ static int rk_spdif_runtime_resume(struct device *dev)
struct rk_spdif_dev *spdif = dev_get_drvdata(dev);
int ret;
- ret = clk_prepare_enable(spdif->mclk);
+ ret = clk_prepare_enable(spdif->hclk);
if (ret) {
- dev_err(spdif->dev, "mclk clock enable failed %d\n", ret);
+ dev_err(spdif->dev, "hclk clock enable failed %d\n", ret);
return ret;
}
- ret = clk_prepare_enable(spdif->hclk);
+ ret = clk_prepare_enable(spdif->mclk);
if (ret) {
- clk_disable_unprepare(spdif->mclk);
- dev_err(spdif->dev, "hclk clock enable failed %d\n", ret);
+ clk_disable_unprepare(spdif->hclk);
+ dev_err(spdif->dev, "mclk clock enable failed %d\n", ret);
return ret;
}
--
2.43.0
^ permalink raw reply related
* [PATCH 1/3] ASoC: dt-bindings: rockchip-spdif: Correct SPDIF clock descriptions
From: phucduc.bui @ 2026-05-22 10:03 UTC (permalink / raw)
To: broonie
Cc: lgirdwood, perex, tiwai, heiko, linux-arm-kernel, linux-kernel,
linux-sound, linux-rockchip, robh, krzk+dt, conor+dt, devicetree,
bui duc phuc
In-Reply-To: <20260522100318.73474-1-phucduc.bui@gmail.com>
From: bui duc phuc <phucduc.bui@gmail.com>
The clock descriptions are currently swapped relative to the
clock names used by the driver.
Update the binding descriptions to match the actual clock
usage, where 'mclk' is the controller clock and 'hclk' is
the bus clock.
Signed-off-by: bui duc phuc <phucduc.bui@gmail.com>
---
Documentation/devicetree/bindings/sound/rockchip-spdif.yaml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Documentation/devicetree/bindings/sound/rockchip-spdif.yaml b/Documentation/devicetree/bindings/sound/rockchip-spdif.yaml
index 502907dd28b3..b174d7498029 100644
--- a/Documentation/devicetree/bindings/sound/rockchip-spdif.yaml
+++ b/Documentation/devicetree/bindings/sound/rockchip-spdif.yaml
@@ -45,8 +45,8 @@ properties:
clocks:
items:
- - description: clock for SPDIF bus
- description: clock for SPDIF controller
+ - description: clock for SPDIF bus
clock-names:
items:
--
2.43.0
^ permalink raw reply related
* [PATCH 0/3] ASoC: rockchip: Reorder clock enable sequence
From: phucduc.bui @ 2026-05-22 10:03 UTC (permalink / raw)
To: broonie
Cc: lgirdwood, perex, tiwai, heiko, linux-arm-kernel, linux-kernel,
linux-sound, linux-rockchip, robh, krzk+dt, conor+dt, devicetree,
bui duc phuc
From: bui duc phuc <phucduc.bui@gmail.com>
Hi all,
This series reorders the runtime resume clock enable
sequence in the Rockchip SPDIF and PDM drivers to enable
the bus clock before the functional controller clock.
It also updates the SPDIF DT binding clock descriptions to
match the actual clock usage in the driver.
Best Regards,
Phuc
bui duc phuc (3):
ASoC: dt-bindings: rockchip-spdif: Correct SPDIF clock descriptions
ASoC: rockchip: spdif: Reorder clock enable sequence
ASoC: rockchip: rockchip_pdm: Reorder clock enable sequence
.../devicetree/bindings/sound/rockchip-spdif.yaml | 2 +-
sound/soc/rockchip/rockchip_pdm.c | 10 +++++-----
sound/soc/rockchip/rockchip_spdif.c | 10 +++++-----
3 files changed, 11 insertions(+), 11 deletions(-)
--
2.43.0
^ permalink raw reply
* Re: [PATCH v14 09/44] arm64: RMI: Provide functions to delegate/undelegate ranges of memory
From: Marc Zyngier @ 2026-05-22 10:02 UTC (permalink / raw)
To: Suzuki K Poulose
Cc: Steven Price, kvm, kvmarm, Catalin Marinas, Will Deacon,
James Morse, Oliver Upton, Zenghui Yu, linux-arm-kernel,
linux-kernel, Joey Gouly, Alexandru Elisei, Christoffer Dall,
Fuad Tabba, linux-coco, Ganapatrao Kulkarni, Gavin Shan,
Shanker Donthineni, Alper Gun, Aneesh Kumar K . V, Emi Kisanuki,
Vishal Annapurve, WeiLin.Chang, Lorenzo.Pieralisi2
In-Reply-To: <a81c3688-30f1-43e4-8d57-1d08a6e563af@arm.com>
On Thu, 21 May 2026 17:01:37 +0100,
Suzuki K Poulose <suzuki.poulose@arm.com> wrote:
>
> On 21/05/2026 14:59, Marc Zyngier wrote:
> > On Wed, 13 May 2026 14:17:17 +0100,
> > Steven Price <steven.price@arm.com> wrote:
> >>
> >> The RMM requires memory is 'delegated' to it so that it can be used
> >> either for a realm guest or for various tracking purposes within the RMM
> >> (e.g. for metadata or page tables). Memory that has been delegated
> >> cannot be accessed by the host (it will result in a Granule Protection
> >> Fault).
> >>
> >> Undelegation may fail if the memory is still in use by the RMM. This
> >> shouldn't happen (Linux should ensure it has destroyed the RMM objects
> >> before attempting to undelegate). In the event that it does happen this
> >> points to a programming bug and the only reasonable approach is for the
> >> physical pages to be leaked - it is up to the caller of
> >> rmi_undelegate_range() to handle this.
> >>
> >> Signed-off-by: Steven Price <steven.price@arm.com>
> >> ---
> >> v14:
> >> * Split into separate patch and moved out of KVM
> >> ---
> >> arch/arm64/include/asm/rmi_cmds.h | 13 +++++++++++
> >> arch/arm64/kernel/rmi.c | 36 +++++++++++++++++++++++++++++++
> >> 2 files changed, 49 insertions(+)
> >>
> >> diff --git a/arch/arm64/include/asm/rmi_cmds.h b/arch/arm64/include/asm/rmi_cmds.h
> >> index 9078a2920a7c..eb213c8e6f26 100644
> >> --- a/arch/arm64/include/asm/rmi_cmds.h
> >> +++ b/arch/arm64/include/asm/rmi_cmds.h
> >> @@ -33,6 +33,19 @@ struct rmi_sro_state {
> >> } while (RMI_RETURN_STATUS(res.a0) == RMI_BUSY || \
> >> RMI_RETURN_STATUS(res.a0) == RMI_BLOCKED)
> >> +int rmi_delegate_range(phys_addr_t phys, unsigned long size);
> >> +int rmi_undelegate_range(phys_addr_t phys, unsigned long size);
> >> +
> >> +static inline int rmi_delegate_page(phys_addr_t phys)
> >> +{
> >> + return rmi_delegate_range(phys, PAGE_SIZE);
> >> +}
> >> +
> >> +static inline int rmi_undelegate_page(phys_addr_t phys)
> >> +{
> >> + return rmi_undelegate_range(phys, PAGE_SIZE);
> >> +}
> >> +
> >> bool rmi_is_available(void);
> >> unsigned long rmi_sro_execute(struct rmi_sro_state *sro, gfp_t
> >> gfp);
> >> diff --git a/arch/arm64/kernel/rmi.c b/arch/arm64/kernel/rmi.c
> >> index 52a415e99500..08cef54acadb 100644
> >> --- a/arch/arm64/kernel/rmi.c
> >> +++ b/arch/arm64/kernel/rmi.c
> >> @@ -12,6 +12,42 @@ static bool arm64_rmi_is_available;
> >> unsigned long rmm_feat_reg0;
> >> unsigned long rmm_feat_reg1;
> >> +int rmi_delegate_range(phys_addr_t phys, unsigned long size)
> >> +{
> >> + unsigned long ret = 0;
> >> + unsigned long top = phys + size;
> >> + unsigned long out_top;
> >> +
> >> + while (phys < top) {
> >> + ret = rmi_granule_range_delegate(phys, top, &out_top);
> >> + if (ret == RMI_SUCCESS)
> >> + phys = out_top;
> >> + else if (ret != RMI_BUSY && ret != RMI_BLOCKED)
> >> + return ret;
> >> + }
> >> +
> >> + return ret;
> >> +}
> >> +
> >> +int rmi_undelegate_range(phys_addr_t phys, unsigned long size)
> >> +{
> >> + unsigned long ret = 0;
> >> + unsigned long top = phys + size;
> >> + unsigned long out_top;
> >> +
> >> + WARN_ON(size == 0);
> >
> > I find it odd to warn on size = 0. After all, free(NULL) is not an
> > error. But even then, you continue feeding this to the RMM.
> >
> > You also don't seem to be bothered with that on the delegation side...
> >
> >> +
> >> + while (phys < top) {
> >> + ret = rmi_granule_range_undelegate(phys, top, &out_top);
> >> + if (ret == RMI_SUCCESS)
> >> + phys = out_top;
> >
> > and size==0 doesn't violate any of the failure conditions listed in
> > B4.5.18.2 (beta2). Will you end-up looping around forever?
>
> That is not true ? It triggers, top_bound error condition, for both.
>
>
> pre: UInt(top) <= UInt(base)
> post: result.status == RMI_ERROR_INPUT
News flash, I can't read. Ignore me.
M.
--
Jazz isn't dead. It just smells funny.
^ permalink raw reply
* Re: [PATCH v8 next 03/10] arm_mpam: Disable reqPARTID expansion when Narrow-PARTID is unavailable
From: Zeng Heng @ 2026-05-22 9:57 UTC (permalink / raw)
To: James Morse, ben.horgan, Dave.Martin, tan.shaopeng,
reinette.chatre, fenghuay, tglx, will, hpa, bp, babu.moger,
dave.hansen, mingo, tony.luck, gshan, catalin.marinas
Cc: linux-arm-kernel, x86, linux-kernel, wangkefeng.wang, zengheng4
In-Reply-To: <9efc30be-689b-4f42-bef0-d7d62b4392fa@arm.com>
Hi James,
On 2026/5/15 1:06, James Morse wrote:
> Hi Zeng,
>
> On 13/04/2026 09:53, Zeng Heng wrote:
>> MPAM supports heterogeneous systems where some type of MSCs may implement
>> Narrow-PARTID while others do not. However, when an MSC uses
>> percentage-based throttling (non-bitmap partition control) and lacks
>> Narrow-PARTID support, resctrl cannot correctly apply control group
>> configurations across multiple PARTIDs.
>>
>> To enable free assignment of multiple reqPARTIDs to resource control
>> groups, all MSCs used by resctrl must either: Implement Narrow-PARTID,
>> allowing explicit PARTID remapping, or only have stateless resource
>> controls (non-percentage-based), such that splitting a control group
>> across multiple PARTIDs does not affect behavior.
>
> I prefer Dave's terminology for this: aliasing and non-aliasing. It implies
> there are two controls, which stateless does not.
>
OK, count me as a fan of the terminology too.
>
>> The detection occurs at initialization time on the first call to
>> get_num_reqpartid() from update_rmid_limits(). This call is guaranteed
>> to occur after mpam_resctrl_pick_{mba,caches}() have set up the
>> resource classes, ensuring the necessary properties are available
>> for the Narrow-PARTID capability check.
>>
>> When an MSC with percentage-based control lacks Narrow-PARTID support,
>> get_num_reqpartid() falls back to returning the number of intPARTIDs,
>> effectively disabling the reqPARTID expansion for monitoring groups.
>
> No MSC has percentage based controls - that's an x86ism. The MSCs have
> fixed point fractions, bitmaps or a cost/weight.
>
Yes, thanks for head-up: it's x86ism.
>
> I think you're thinking about this the wrong way up - we should only enable
> this on a small number of platforms that don't have any controls we'd have to discard.
> (hopefully yours is such a platform!)
>
> I don't think this should be added to resctrl_arch_system_num_rmid_idx(). Please make
> this decision for resctrl at mpam_resctrl_setup() time.
>
>
>> diff --git a/drivers/resctrl/mpam_resctrl.c b/drivers/resctrl/mpam_resctrl.c
>> index 5f4364c8101a..56859f354efa 100644
>> --- a/drivers/resctrl/mpam_resctrl.c
>> +++ b/drivers/resctrl/mpam_resctrl.c
>> @@ -257,9 +257,50 @@ u32 resctrl_arch_get_num_closid(struct rdt_resource *ignored)
>> return mpam_intpartid_max + 1;
>> }
>>
>> +/*
>> + * Determine the effective number of PARTIDs available for resctrl.
>> + *
>> + * This function performs a one-time check to determine if Narrow-PARTID
>> + * can be used. It must be called after mpam_resctrl_pick_{mba,caches}()
>> + * have initialized the resource classes, as class properties are used
>> + * to detect Narrow-PARTID support.
>
>> + * The first call occurs in update_rmid_limits(), ensuring the
>> + * prerequisite initialization is complete.
>
> This is fragile to changes in the order resctrl makes these calls. We need these
> properties to be fixed before we call resctrl_init().
>
> (yes - I think CDP is fragile too!)
It makes sense to me.
>
>
>> + */
>> +static u32 get_num_reqpartid(void)
>> +{
>> + struct mpam_resctrl_res *res;
>> + struct mpam_props *cprops;
>> + static bool first = true;
>> + int rid;
>> +
>> + if (first) {
>> + for_each_mpam_resctrl_control(res, rid) {
>> + if (!res->class)
>> + continue;
>> +
>> + cprops = &res->class->props;
>> + if (mpam_has_feature(mpam_feat_partid_nrw, cprops))
>> + continue;
>
>
>> + if (mpam_has_feature(mpam_feat_mbw_max, cprops) ||
>> + mpam_has_feature(mpam_feat_mbw_min, cprops) ||
>> + mpam_has_feature(mpam_feat_cmax_cmax, cprops) ||
>> + mpam_has_feature(mpam_feat_cmax_cmin, cprops)) {
>
> Please make this a helper in mpam_internal.h with 'controls' and 'aliasing' in its name.
> (maybe has_aliasing_controls()).
>
> What about the priority for PRI and the proportional-stride?
>
> I don't think proportional-stride aliases properly: if I have groups with stride 1 and 2,
> I can't add a second '2' without decreasing the first groups stride from 1/3 to 1/5. If I
> halve the second groups, they each get half the bandwidth instead of sharing it.
>
> Can you check whether the priority for PRI aliases?
>
Proportional-stride is indeed a non-aliasing control, and this was an
oversight on my part (I haven't actually encountered this control option
before).
I'd argue that PRI is an aliasing control: the priority value defines a
scheduling class or identity. When multiple PARTIDs share the same
priority, it's akin to multiple users holding the same VIP tier. They
compete for resources within that same category, rather than each
receiving an independent, additive allocation.
Best regards,
Zeng Heng
^ permalink raw reply
* [PATCH] ASoC: sunxi: sun50i-dmic: Reorder clock enable sequence
From: phucduc.bui @ 2026-05-22 9:55 UTC (permalink / raw)
To: broonie
Cc: codekipper, jernej.skrabec, lgirdwood, linux-arm-kernel,
linux-kernel, linux-sound, linux-sunxi, nichen, perex, samuel,
tiwai, wens, bui duc phuc
From: bui duc phuc <phucduc.bui@gmail.com>
Enable the bus clock before the DMIC module clock during
runtime resume.
The bus clock provides the register access interface and
should be enabled before the module clock.
Signed-off-by: bui duc phuc <phucduc.bui@gmail.com>
---
sound/soc/sunxi/sun50i-dmic.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/sound/soc/sunxi/sun50i-dmic.c b/sound/soc/sunxi/sun50i-dmic.c
index eddfebe16616..7aff1afdf265 100644
--- a/sound/soc/sunxi/sun50i-dmic.c
+++ b/sound/soc/sunxi/sun50i-dmic.c
@@ -323,16 +323,16 @@ static int sun50i_dmic_runtime_suspend(struct device *dev)
static int sun50i_dmic_runtime_resume(struct device *dev)
{
- struct sun50i_dmic_dev *host = dev_get_drvdata(dev);
+ struct sun50i_dmic_dev *host = dev_get_drvdata(dev);
int ret;
- ret = clk_prepare_enable(host->dmic_clk);
+ ret = clk_prepare_enable(host->bus_clk);
if (ret)
return ret;
- ret = clk_prepare_enable(host->bus_clk);
+ ret = clk_prepare_enable(host->dmic_clk);
if (ret) {
- clk_disable_unprepare(host->dmic_clk);
+ clk_disable_unprepare(host->bus_clk);
return ret;
}
--
2.43.0
^ permalink raw reply related
* Re: [PATCH v14 04/44] arm64: RMI: Add SMC definitions for calling the RMM
From: Marc Zyngier @ 2026-05-22 9:58 UTC (permalink / raw)
To: Steven Price
Cc: kvm, kvmarm, Catalin Marinas, 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, Gavin Shan,
Shanker Donthineni, Alper Gun, Aneesh Kumar K . V, Emi Kisanuki,
Vishal Annapurve, WeiLin.Chang, Lorenzo.Pieralisi2
In-Reply-To: <3261b04f-1a0c-451d-8981-1e2bccc8a9ca@arm.com>
On Thu, 21 May 2026 16:33:09 +0100,
Steven Price <steven.price@arm.com> wrote:
>
> On 21/05/2026 13:40, Marc Zyngier wrote:
> > On Wed, 13 May 2026 14:17:12 +0100,
> > Steven Price <steven.price@arm.com> 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/
> >
> > How long is this spec going to be available on the ARM web site, which
> > has a tendency of being reorganised every other week? And there is
> > already a beta2.
>
> Obviously I can't predict the next reorganisation - but at least it's a
> link that could be fed into archive.org or similar.
I found that the PDF spec was less susceptible to creative nonsense,
and people can download it for future reference, whereas ARM has
happily *deleted* specs from the website over time (try to find PSCI
0.1, for example...).
[...]
> >> +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];
> >
> > SZ_1K? And similarly all over the shop?
>
> I'm a bit less sure that makes the code more readable - these structures
> are a bit of a pain because they are somewhat sparse. I've left a
> comment where the beginning of each union is, and personally I find it
> easier to see 0x0 + 0x400 == 0x400 rather than trying to work out what
> SZ_1K is in hex. This is particularly the case in terms of:
>
> > 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];
> > };
> > };
>
> Where 0xd00 doesn't even have a correspoding SZ_ define.
Indeed, but it is (SZ_4K - SZ_256 * 3). And a lot of these structures
seem to be designed to form a 4kB blob. I'm sure we can make use of
that information (BUILD_BUG_ON?).
>
> The RMM deals with this with macro magic:
>
> > struct rmi_rec_params {
> > /* Flags */
> > SET_MEMBER_RMI(unsigned long flags, 0, 0x100); /* Offset 0 */
> > /* MPIDR of the REC */
> > SET_MEMBER_RMI(unsigned long mpidr, 0x100, 0x200); /* 0x100 */
> > /* Program counter */
> > SET_MEMBER_RMI(unsigned long pc, 0x200, 0x300); /* 0x200 */
> > /* General-purpose registers */
> > SET_MEMBER_RMI(unsigned long gprs[REC_CREATE_NR_GPRS], 0x300, 0x1000); /* 0x300 */
> > };
>
> where the offsets are just directly encoded in the macro - but it's not
> an especially robust macro and I'm not convinced it's more readable.
I think this is just as horrible, but at least it seems to take the
boundaries of the structure into account.
>
> I'm happy to hear other suggestions on how to encode this neatly.
Honestly, I wouldn't mind having the structures described in a more
abstract way and then pre-processed to generate the include files. If
the architectural MRS wasn't so huge, I would have added it to the
kernel and used that directly for KVM.
>
> > I haven't checked the details of the encodings (life is too short),
> > but I wonder how much of this exists as an MRS and could be
> > automatically generated?
>
> Automatically generating this would be good - I'm not sure whether we
> have a (public) source available to generate from at the moment. I have
> tried to methodically work through the spec when updating this file, but
> as Gavin has already pointed out there was at least one mistake (in
> currently unused definitions) this time.
I'm slightly baffled that even the RMM is written this way. Given the
formalism used in the RMM spec, I was expecting that you'd have a
bunch of JSON at hand and able to generate any output from that. Doing
this stuff by hand is both incredibly dull work *and* extremely error
prone.
Thanks,
M.
--
Jazz isn't dead. It just smells funny.
^ permalink raw reply
* [PATCH v2 3/3] ASoC: sunxi: sun4i-spdif: Reorder clock enable sequence
From: phucduc.bui @ 2026-05-22 9:54 UTC (permalink / raw)
To: broonie
Cc: codekipper, jernej.skrabec, lgirdwood, linux-arm-kernel,
linux-kernel, linux-sound, linux-sunxi, nichen, perex, samuel,
tiwai, wens, bui duc phuc
In-Reply-To: <20260522095401.72915-1-phucduc.bui@gmail.com>
From: bui duc phuc <phucduc.bui@gmail.com>
Enable the APB bus clock before the SPDIF module clock
during runtime resume, as register accesses depend on the
bus clock being enabled first.
Signed-off-by: bui duc phuc <phucduc.bui@gmail.com>
---
sound/soc/sunxi/sun4i-spdif.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/sound/soc/sunxi/sun4i-spdif.c b/sound/soc/sunxi/sun4i-spdif.c
index f54eb14c9ed8..102db1a2afbb 100644
--- a/sound/soc/sunxi/sun4i-spdif.c
+++ b/sound/soc/sunxi/sun4i-spdif.c
@@ -643,15 +643,15 @@ static int sun4i_spdif_runtime_suspend(struct device *dev)
static int sun4i_spdif_runtime_resume(struct device *dev)
{
- struct sun4i_spdif_dev *host = dev_get_drvdata(dev);
+ struct sun4i_spdif_dev *host = dev_get_drvdata(dev);
int ret;
- ret = clk_prepare_enable(host->spdif_clk);
+ ret = clk_prepare_enable(host->apb_clk);
if (ret)
return ret;
- ret = clk_prepare_enable(host->apb_clk);
+ ret = clk_prepare_enable(host->spdif_clk);
if (ret)
- clk_disable_unprepare(host->spdif_clk);
+ clk_disable_unprepare(host->apb_clk);
return ret;
}
--
2.43.0
^ permalink raw reply related
* [PATCH v2 1/3] ASoC: sunxi: sun4i-spdif: Use guard() for spin locks
From: phucduc.bui @ 2026-05-22 9:53 UTC (permalink / raw)
To: broonie
Cc: codekipper, jernej.skrabec, lgirdwood, linux-arm-kernel,
linux-kernel, linux-sound, linux-sunxi, nichen, perex, samuel,
tiwai, wens, bui duc phuc
In-Reply-To: <20260522095401.72915-1-phucduc.bui@gmail.com>
From: bui duc phuc <phucduc.bui@gmail.com>
Clean up the code using guard() for spin locks.
Merely code refactoring, and no behavior change.
Signed-off-by: bui duc phuc <phucduc.bui@gmail.com>
---
Change in v2:
- Switched from using guard() to scoped_guard()
sound/soc/sunxi/sun4i-spdif.c | 62 ++++++++++++++++-------------------
1 file changed, 28 insertions(+), 34 deletions(-)
diff --git a/sound/soc/sunxi/sun4i-spdif.c b/sound/soc/sunxi/sun4i-spdif.c
index c2ec19437cd7..89eccc83a130 100644
--- a/sound/soc/sunxi/sun4i-spdif.c
+++ b/sound/soc/sunxi/sun4i-spdif.c
@@ -427,24 +427,21 @@ static int sun4i_spdif_get_status(struct snd_kcontrol *kcontrol,
struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kcontrol);
struct sun4i_spdif_dev *host = snd_soc_dai_get_drvdata(cpu_dai);
u8 *status = ucontrol->value.iec958.status;
- unsigned long flags;
unsigned int reg;
- spin_lock_irqsave(&host->lock, flags);
+ scoped_guard(spinlock_irqsave, &host->lock) {
+ regmap_read(host->regmap, SUN4I_SPDIF_TXCHSTA0, ®);
- regmap_read(host->regmap, SUN4I_SPDIF_TXCHSTA0, ®);
+ status[0] = reg & 0xff;
+ status[1] = (reg >> 8) & 0xff;
+ status[2] = (reg >> 16) & 0xff;
+ status[3] = (reg >> 24) & 0xff;
- status[0] = reg & 0xff;
- status[1] = (reg >> 8) & 0xff;
- status[2] = (reg >> 16) & 0xff;
- status[3] = (reg >> 24) & 0xff;
+ regmap_read(host->regmap, SUN4I_SPDIF_TXCHSTA1, ®);
- regmap_read(host->regmap, SUN4I_SPDIF_TXCHSTA1, ®);
-
- status[4] = reg & 0xff;
- status[5] = (reg >> 8) & 0x3;
-
- spin_unlock_irqrestore(&host->lock, flags);
+ status[4] = reg & 0xff;
+ status[5] = (reg >> 8) & 0x3;
+ }
return 0;
}
@@ -455,35 +452,32 @@ static int sun4i_spdif_set_status(struct snd_kcontrol *kcontrol,
struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kcontrol);
struct sun4i_spdif_dev *host = snd_soc_dai_get_drvdata(cpu_dai);
u8 *status = ucontrol->value.iec958.status;
- unsigned long flags;
unsigned int reg;
bool chg0, chg1;
- spin_lock_irqsave(&host->lock, flags);
-
- reg = (u32)status[3] << 24;
- reg |= (u32)status[2] << 16;
- reg |= (u32)status[1] << 8;
- reg |= (u32)status[0];
+ scoped_guard(spinlock_irqsave, &host->lock) {
+ reg = (u32)status[3] << 24;
+ reg |= (u32)status[2] << 16;
+ reg |= (u32)status[1] << 8;
+ reg |= (u32)status[0];
- regmap_update_bits_check(host->regmap, SUN4I_SPDIF_TXCHSTA0,
- GENMASK(31,0), reg, &chg0);
+ regmap_update_bits_check(host->regmap, SUN4I_SPDIF_TXCHSTA0,
+ GENMASK(31, 0), reg, &chg0);
- reg = (u32)status[5] << 8;
- reg |= (u32)status[4];
+ reg = (u32)status[5] << 8;
+ reg |= (u32)status[4];
- regmap_update_bits_check(host->regmap, SUN4I_SPDIF_TXCHSTA1,
- GENMASK(9,0), reg, &chg1);
+ regmap_update_bits_check(host->regmap, SUN4I_SPDIF_TXCHSTA1,
+ GENMASK(9, 0), reg, &chg1);
- reg = SUN4I_SPDIF_TXCFG_CHSTMODE;
- if (status[0] & IEC958_AES0_NONAUDIO)
- reg |= SUN4I_SPDIF_TXCFG_NONAUDIO;
+ reg = SUN4I_SPDIF_TXCFG_CHSTMODE;
+ if (status[0] & IEC958_AES0_NONAUDIO)
+ reg |= SUN4I_SPDIF_TXCFG_NONAUDIO;
- regmap_update_bits(host->regmap, SUN4I_SPDIF_TXCFG,
- SUN4I_SPDIF_TXCFG_CHSTMODE |
- SUN4I_SPDIF_TXCFG_NONAUDIO, reg);
-
- spin_unlock_irqrestore(&host->lock, flags);
+ regmap_update_bits(host->regmap, SUN4I_SPDIF_TXCFG,
+ SUN4I_SPDIF_TXCFG_CHSTMODE |
+ SUN4I_SPDIF_TXCFG_NONAUDIO, reg);
+ }
return chg0 || chg1;
}
--
2.43.0
^ permalink raw reply related
* [PATCH v2 2/3] ASoC: sunxi: sun4i-spdif: Resume device before kcontrol register access
From: phucduc.bui @ 2026-05-22 9:54 UTC (permalink / raw)
To: broonie
Cc: codekipper, jernej.skrabec, lgirdwood, linux-arm-kernel,
linux-kernel, linux-sound, linux-sunxi, nichen, perex, samuel,
tiwai, wens, bui duc phuc
In-Reply-To: <20260522095401.72915-1-phucduc.bui@gmail.com>
From: bui duc phuc <phucduc.bui@gmail.com>
Accessing registers while the device is runtime-suspended
may lead to invalid hardware accesses on systems where the
APB bus clock is gated during runtime suspend.
Ensure the device is resumed before accessing registers.
Signed-off-by: bui duc phuc <phucduc.bui@gmail.com>
---
sound/soc/sunxi/sun4i-spdif.c | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/sound/soc/sunxi/sun4i-spdif.c b/sound/soc/sunxi/sun4i-spdif.c
index 89eccc83a130..f54eb14c9ed8 100644
--- a/sound/soc/sunxi/sun4i-spdif.c
+++ b/sound/soc/sunxi/sun4i-spdif.c
@@ -428,6 +428,11 @@ static int sun4i_spdif_get_status(struct snd_kcontrol *kcontrol,
struct sun4i_spdif_dev *host = snd_soc_dai_get_drvdata(cpu_dai);
u8 *status = ucontrol->value.iec958.status;
unsigned int reg;
+ int ret;
+
+ ret = pm_runtime_resume_and_get(cpu_dai->dev);
+ if (ret)
+ return ret;
scoped_guard(spinlock_irqsave, &host->lock) {
regmap_read(host->regmap, SUN4I_SPDIF_TXCHSTA0, ®);
@@ -443,6 +448,8 @@ static int sun4i_spdif_get_status(struct snd_kcontrol *kcontrol,
status[5] = (reg >> 8) & 0x3;
}
+ pm_runtime_put(cpu_dai->dev);
+
return 0;
}
@@ -453,8 +460,13 @@ static int sun4i_spdif_set_status(struct snd_kcontrol *kcontrol,
struct sun4i_spdif_dev *host = snd_soc_dai_get_drvdata(cpu_dai);
u8 *status = ucontrol->value.iec958.status;
unsigned int reg;
+ int ret;
bool chg0, chg1;
+ ret = pm_runtime_resume_and_get(cpu_dai->dev);
+ if (ret)
+ return ret;
+
scoped_guard(spinlock_irqsave, &host->lock) {
reg = (u32)status[3] << 24;
reg |= (u32)status[2] << 16;
@@ -479,6 +491,8 @@ static int sun4i_spdif_set_status(struct snd_kcontrol *kcontrol,
SUN4I_SPDIF_TXCFG_NONAUDIO, reg);
}
+ pm_runtime_put(cpu_dai->dev);
+
return chg0 || chg1;
}
--
2.43.0
^ permalink raw reply related
* Re: [PATCH] media: bcm2835-unicam: Fix pipeline wrong validation for unpacked formats
From: Dave Stevenson @ 2026-05-22 9:54 UTC (permalink / raw)
To: Eugen Hristev
Cc: Raspberry Pi Kernel Maintenance, Mauro Carvalho Chehab,
Florian Fainelli, Ray Jui, Scott Branden,
Broadcom internal kernel review list, Hans Verkuil,
Laurent Pinchart, Maxime Ripard, Sakari Ailus, linux-media,
linux-rpi-kernel, linux-arm-kernel, linux-kernel
In-Reply-To: <20260520-bcmpi-v1-1-41d80125a7b9@kernel.org>
Hi Eugen
Thanks for the patch.
On Wed, 20 May 2026 at 16:37, 'Eugen Hristev' via kernel-list
<kernel-list@raspberrypi.com> wrote:
>
> The commit
> 08f9794d9b79 ("media: bcm2835-unicam: Fix RGB format / mbus code association")
> introduced a check to see whether the format requested is the same as the
> fourcc in the format list.
>
> However, this breaks the case when userspace requested an unpacked fourcc,
> e.g. RG10.
>
> Unicam can work with or without unpacking pixels, e.g. pRAA or RG10, depending
> on what userspace requests.
> In the unpacking case, a dedicated register is being set.
>
> If the userspace requests pRAA, this works, because the check validates the
> pipeline:
>
> v4l2-ctl -d /dev/video0 --set-fmt-video=width=3280,height=2464,pixelformat=pRAA \
> --stream-mmap --stream-count=1 --stream-to=frame.raw
>
> but, with
> v4l2-ctl -d /dev/video0 --set-fmt-video=width=3280,height=2464,pixelformat=RG10 \
> --stream-mmap --stream-count=1 --stream-to=frame.raw
>
> unicam complains at validation level:
>
> image: format mismatch: 0x300f <=> RG10 little-endian (0x30314752)
>
> This should work, because MEDIA_BUS_FMT_SRGGB10_1X10 can be packed into either
> RG10 or pRAA depending on the packing register.
>
> To fix this, modified the condition check to also allow in the case when
> requested format (fmt->pixelformat) is equal to fmtinfo->unpacked_fourcc.
>
> Fixes: 08f9794d9b79 ("media: bcm2835-unicam: Fix RGB format / mbus code association")
> Signed-off-by: Eugen Hristev <ehristev@kernel.org>
Reviewed-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
> ---
> drivers/media/platform/broadcom/bcm2835-unicam.c | 3 ++-
> 1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/media/platform/broadcom/bcm2835-unicam.c b/drivers/media/platform/broadcom/bcm2835-unicam.c
> index 8d28ba0b59a3..cc7627e9a51a 100644
> --- a/drivers/media/platform/broadcom/bcm2835-unicam.c
> +++ b/drivers/media/platform/broadcom/bcm2835-unicam.c
> @@ -2158,7 +2158,8 @@ static int unicam_video_link_validate(struct media_link *link)
> * In order to allow the applications using the old behaviour to
> * run, let's accept the old combination, but warn about it.
> */
> - if (fmtinfo->fourcc != fmt->pixelformat) {
> + if (fmt->pixelformat != fmtinfo->fourcc &&
> + fmt->pixelformat != fmtinfo->unpacked_fourcc) {
> if ((fmt->pixelformat == V4L2_PIX_FMT_BGR24 &&
> format->code == MEDIA_BUS_FMT_BGR888_1X24) ||
> (fmt->pixelformat == V4L2_PIX_FMT_RGB24 &&
>
> ---
> base-commit: e98d21c170b01ddef366f023bbfcf6b31509fa83
> change-id: 20260520-bcmpi-2c4850314e21
>
> Best regards,
> --
> Eugen Hristev <ehristev@kernel.org>
>
^ permalink raw reply
* [PATCH v2 0/3] ASoC: sunxi: sun4i-spdif: Cleanup and runtime PM improvements
From: phucduc.bui @ 2026-05-22 9:53 UTC (permalink / raw)
To: broonie
Cc: codekipper, jernej.skrabec, lgirdwood, linux-arm-kernel,
linux-kernel, linux-sound, linux-sunxi, nichen, perex, samuel,
tiwai, wens, bui duc phuc
From: bui duc phuc <phucduc.bui@gmail.com>
Hi,
This series contains a few improvements for the sun4i-spdif driver,
including guard() conversions and ensuring the device is resumed
via runtime PM before kcontrol register accesses.
Link v1:
https://lore.kernel.org/all/20260513105003.81880-1-phucduc.bui@gmail.com/
Change in v2:
- Switched from using guard() to scoped_guard()
- Added runtime PM handling for kcontrol register accesses.
Best Regards,
Phuc
bui duc phuc (3):
ASoC: sunxi: sun4i-spdif: Use guard() for spin locks
ASoC: sunxi: sun4i-spdif: Resume device before kcontrol register
access
ASoC: sunxi: sun4i-spdif: Reorder clock enable sequence
sound/soc/sunxi/sun4i-spdif.c | 76 +++++++++++++++++++----------------
1 file changed, 42 insertions(+), 34 deletions(-)
--
2.43.0
^ permalink raw reply
* Re: [PATCH] arm64: mm: call pagetable dtor when freeing hot-removed page tables
From: Vishal Moola @ 2026-05-22 9:36 UTC (permalink / raw)
To: Catalin Marinas
Cc: Andrew Morton, Alistair Popple, linux-arm-kernel, linux-kernel,
linux-mm, will, david
In-Reply-To: <ahACfQ6kCfONqz5h@arm.com>
On Fri, May 22, 2026 at 08:15:09AM +0100, Catalin Marinas wrote:
> On Thu, May 21, 2026 at 03:31:30PM -0700, Andrew Morton wrote:
> > On Thu, 21 May 2026 13:27:30 +1000 Alistair Popple <apopple@nvidia.com> wrote:
> > > Since 5e8eb9aeeda3 ("arm64: mm: always call PTE/PMD ctor in
> > > __create_pgd_mapping()") page-table allocation on ARM64 always
> > > calls pagetable_{pte,pmd,pud,p4d}_ctor(). This sets the page_type
> > > to PGTY_table, increments NR_PAGETABLE and possible allocates a PTL.
> > > However the matching pagetable_dtor() calls were never added.
> > >
> > > With DEBUG_VM enabled on kernel versions prior to v6.17 without
> > > 2dfcd1608f3a9 ("mm/page_alloc: let page freeing clear any set page
> > > type") this leads to the following warning when freeing these pages due
> > > to page->page_type sharing page->_mapcount:
> > >
> > > BUG: Bad page state in process ... pfn:284fbb
> > > page: refcount:0 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x284fbb
> > > flags: 0x17fffc000000000(node=0|zone=2|lastcpupid=0x1ffff)
> > > page_type: f2(table)
> > > page dumped because: nonzero mapcount
> > > Call trace:
> > > bad_page+0x13c/0x160
> > > __free_frozen_pages+0x6cc/0x860
> > > ___free_pages+0xf4/0x180
> > > free_pages+0x54/0x80
> > > free_hotplug_page_range.part.0+0x58/0x90
> > > free_empty_tables+0x438/0x500
> > > __remove_pgd_mapping.constprop.0+0x60/0xa8
> > > arch_remove_memory+0x48/0x80
> > > try_remove_memory+0x158/0x1d8
> > > offline_and_remove_memory+0x138/0x180
> > >
> > > It can also lead to leaking the ptl allocation if ALLOC_SPLIT_PTLOCKS
> > > is defined and incorrect NR_PAGETABLE stats. Fix this by calling
> > > pagetable_dtor() in free_hotplug_pgtable_page() prior to freeing the
> > > page to undo the effects of calling pagetable_*_ctor().
> > >
> > > Fixes: 5e8eb9aeeda3 ("arm64: mm: always call PTE/PMD ctor in __create_pgd_mapping()")
> >
> > 6.16+, so I assume we want cc:stable here.
> >
> > > arch/arm64/mm/mmu.c | 1 +
> > > 1 file changed, 1 insertion(+)
> > >
> > > diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
> > > index 8e1d80a7033e..0c24fe650e95 100644
> > > --- a/arch/arm64/mm/mmu.c
> > > +++ b/arch/arm64/mm/mmu.c
> > > @@ -1422,6 +1422,7 @@ static void free_hotplug_page_range(struct page *page, size_t size,
> > >
> > > static void free_hotplug_pgtable_page(struct page *page)
> > > {
> > > + pagetable_dtor(page_ptdesc(page));
> > > free_hotplug_page_range(page, PAGE_SIZE, NULL);
> > > }
> >
> > I'd of course prefer that arm maintainers handle this. But
> > 5e8eb9aeeda3 came via myself so convention kinda-dictates that I get to
> > fix it.
>
> That's fine but Sashiko has some points:
>
> https://sashiko.dev/#/patchset/20260521032730.2104017-1-apopple@nvidia.com
>
> The __remove_pgd_mapping() path is fine but we also have the
> vmemmap_free() path where the constructor was never called.
>
> We could pass around a bool dtor argument but I wonder whether we could
> just check it's a pgtable page:
Free_empty_tables() looks like the only way we'd ever get to
free_hotplug_pgtable_page(). I'm a little curious why we can't
consolidate unmap_hotplug_range() and free_empty_tables().
I.e. just fold unmap_hotplug_range() into the latter.
> diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
> index 4c8959153ac4..9d42cbddce27 100644
> --- a/arch/arm64/mm/mmu.c
> +++ b/arch/arm64/mm/mmu.c
> @@ -1441,6 +1441,9 @@ static void free_hotplug_page_range(struct page *page, size_t size,
>
> static void free_hotplug_pgtable_page(struct page *page)
> {
> + if (folio_test_pgtable(page_folio(page)))
This should work.
> + pagetable_dtor(page_ptdesc(page));
> +
> free_hotplug_page_range(page, PAGE_SIZE, NULL);
In the case we presumably have a page table page (ptdesc) at this
point, we should really be freeing it with pagetable_free() as well.
Its not a big deal that we don't right now, but losing track of the
matching allocation/free sites will become a headache when separately
allocating from struct page.
> }
>
>
> --
> Catalin
^ permalink raw reply
* Re: [PATCH 02/10] dt-bindings: clock: Add Amlogic A9 PLL clock controller
From: Krzysztof Kozlowski @ 2026-05-22 9:16 UTC (permalink / raw)
To: Jian Hu
Cc: Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Neil Armstrong, Jerome Brunet, Xianwei Zhao,
Kevin Hilman, Martin Blumenstingl, linux-kernel, linux-clk,
devicetree, linux-amlogic, linux-arm-kernel
In-Reply-To: <40e83bed-e7a0-4c66-806c-c2988c5d0f33@amlogic.com>
On 22/05/2026 08:20, Jian Hu wrote:
> Hi Krzysztof,
>
> Thanks for your review.
>
> On 5/15/2026 4:09 PM, Krzysztof Kozlowski wrote:
>> [ EXTERNAL EMAIL ]
>>
>> On Mon, May 11, 2026 at 08:47:24PM +0800, Jian Hu wrote:
>>> Add the PLL clock controller dt-bindings for the Amlogic A9 SoC family.
>>>
>>> Signed-off-by: Jian Hu <jian.hu@amlogic.com>
>>> ---
>>> .../bindings/clock/amlogic,a9-pll-clkc.yaml | 110 +++++++++++++++++++++
>>> include/dt-bindings/clock/amlogic,a9-pll-clkc.h | 55 +++++++++++
>>> 2 files changed, 165 insertions(+)
>>>
>>> diff --git a/Documentation/devicetree/bindings/clock/amlogic,a9-pll-clkc.yaml b/Documentation/devicetree/bindings/clock/amlogic,a9-pll-clkc.yaml
>>> new file mode 100644
>>> index 000000000000..4ee6013ba1a1
>>> --- /dev/null
>>> +++ b/Documentation/devicetree/bindings/clock/amlogic,a9-pll-clkc.yaml
>>> @@ -0,0 +1,110 @@
>>> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
>>> +# Copyright (C) 2026 Amlogic, Inc. All rights reserved
>>> +%YAML 1.2
>>> +---
>>> +$id: http://devicetree.org/schemas/clock/amlogic,a9-pll-clkc.yaml#
>>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>>> +
>>> +title: Amlogic A9 Series PLL Clock Controller
>>> +
>>> +maintainers:
>>> + - Neil Armstrong <neil.armstrong@linaro.org>
>>> + - Jerome Brunet <jbrunet@baylibre.com>
>>> + - Jian Hu <jian.hu@amlogic.com>
>>> + - Xianwei Zhao <xianwei.zhao@amlogic.com>
>>> +
>>> +properties:
>>> + compatible:
>>> + enum:
>>> + - amlogic,a9-gp0-pll
>>> + - amlogic,a9-hifi0-pll
>>> + - amlogic,a9-hifi1-pll
>>> + - amlogic,a9-mclk0-pll
>>> + - amlogic,a9-mclk1-pll
>>> +
>>> + reg:
>>> + maxItems: 1
>>> +
>>> + '#clock-cells':
>>> + const: 1
>>> +
>>> + clocks:
>>> + items:
>>> + - description: pll input oscillator gate
>>> + - description: fixed input clock source for mclk_sel_0
>>> + - description: u3p2pll input clock source for mclk_sel_0 (optional)
>> Second clock is also optional. Drop "(optional)" comment, just
>> confusing.
>
>
> GP0 has only one parent clock, while MCLK has three.
>
> The second and third parent entries of GP0 are vacant,
>
> so they need to be marked optional.
>
> I will add the optional property for the second clock in the next revision.
How? Read the previous feedback...
Best regards,
Krzysztof
^ permalink raw reply
* Re: [PATCH] irqchip/exynos-combiner: remove useless spinlock
From: Peter Griffin @ 2026-05-22 9:20 UTC (permalink / raw)
To: Marek Szyprowski
Cc: linux-arm-kernel, linux-samsung-soc, linux-rt-devel,
Thomas Gleixner, Krzysztof Kozlowski, Alim Akhtar,
Sebastian Andrzej Siewior, Clark Williams, Steven Rostedt
In-Reply-To: <20260522061012.2687122-1-m.szyprowski@samsung.com>
On Fri, 22 May 2026 at 07:14, Marek Szyprowski <m.szyprowski@samsung.com> wrote:
>
> irq_controller_lock doesn't protect anything, it must be some leftover
> from early development or copy/paste. Remove it completely.
>
> Suggested-by: Thomas Gleixner <tglx@kernel.org>
> Suggested-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
> Link: https://lore.kernel.org/all/20260520220422.3522908-1-m.szyprowski@samsung.com/
> Fixes: 96031b31a4b3 ("irqchip/exynos-combiner: Switch to raw_spinlock")
> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> ---
Reviewed-by: Peter Griffin <peter.griffin@linaro.org>
^ permalink raw reply
* Re: [PATCH 1/2] arm64: mm: Add note about overlays in PIE_EL1
From: Yeoreum Yun @ 2026-05-22 9:20 UTC (permalink / raw)
To: Kevin Brodsky
Cc: linux-arm-kernel, Catalin Marinas, Joey Gouly, Mark Brown,
Shuah Khan, Will Deacon, linux-kernel, linux-kselftest
In-Reply-To: <20260521-poe_futex-v1-1-1da286b8f9b2@arm.com>
LGTM.
Reviewed-by: Yeoreum Yun <yeoreum.yun@arm.com>
> It isn't completely obvious why user page types do not have overlays
> applied in PIE_EL1. Add a comment to that effect, to avoid
> unpleasant surprises in the future.
>
> Signed-off-by: Kevin Brodsky <kevin.brodsky@arm.com>
> ---
> arch/arm64/include/asm/pgtable-prot.h | 7 +++++++
> 1 file changed, 7 insertions(+)
>
> diff --git a/arch/arm64/include/asm/pgtable-prot.h b/arch/arm64/include/asm/pgtable-prot.h
> index 212ce1b02e15..6e2f99820909 100644
> --- a/arch/arm64/include/asm/pgtable-prot.h
> +++ b/arch/arm64/include/asm/pgtable-prot.h
> @@ -175,6 +175,13 @@ static inline bool __pure lpa2_is_enabled(void)
> PIRx_ELx_PERM_PREP(pte_pi_index(_PAGE_READONLY), PIE_R_O) | \
> PIRx_ELx_PERM_PREP(pte_pi_index(_PAGE_SHARED), PIE_RW_O))
>
> +/*
> + * Regular user page types such as _PAGE_SHARED must not have overlays applied
> + * in PIE_EL1. If POE is enabled at EL1, and in the absence of FEAT_LSUI, this
> + * would break futex atomic operations on user memory with a non-default
> + * POIndex; the privileged atomic load/store instructions would be mistakenly
> + * checked against POR_EL1.
> + */
> #define PIE_E1 ( \
> PIRx_ELx_PERM_PREP(pte_pi_index(_PAGE_GCS), PIE_NONE_O) | \
> PIRx_ELx_PERM_PREP(pte_pi_index(_PAGE_GCS_RO), PIE_NONE_O) | \
>
> --
> 2.51.2
>
>
--
Sincerely,
Yeoreum Yun
^ permalink raw reply
* Re: [PATCH v4 1/3] PCI: Allow ATS to be always on for CXL.cache capable devices
From: Yi Liu @ 2026-05-22 9:18 UTC (permalink / raw)
To: Jason Gunthorpe
Cc: Nicolin Chen, will, robin.murphy, bhelgaas, joro, praan, baolu.lu,
kevin.tian, miko.lenczewski, linux-arm-kernel, iommu,
linux-kernel, linux-pci, dan.j.williams, jonathan.cameron, vsethi,
linux-cxl, nirmoyd
In-Reply-To: <20260521130544.GE3602937@nvidia.com>
On 5/21/26 21:05, Jason Gunthorpe wrote:
> On Thu, May 21, 2026 at 03:31:46PM +0800, Yi Liu wrote:
>
>> Does this hardware behavior satisfy the security expectation you have in
>> mind? Or do you still require that both the DTE bit and the PCI ATS
>> capability be explicitly disabled when a blocking domain is in effect?
>
> If the HW rejects translated TLPs then you should be clearing the ATS
> enable bit in the device config space prior to rejecting them
>
> But it does seem secure enough as-is.
got it. thanks for the thoughts.
^ permalink raw reply
* Re: [PATCH v6 2/3] PCI: Allow ATS to be always on for pre-CXL devices
From: Yi Liu @ 2026-05-22 9:17 UTC (permalink / raw)
To: Nicolin Chen, jgg, will
Cc: robin.murphy, joro, bhelgaas, praan, baolu.lu, kevin.tian,
miko.lenczewski, linux-arm-kernel, iommu, linux-kernel, linux-pci,
dan.j.williams, jonathan.cameron, vsethi, linux-cxl, nirmoyd
In-Reply-To: <0dd7e22f44bf35a33a590e0916983f9f7fe00de3.1779392420.git.nicolinc@nvidia.com>
On 5/22/26 04:34, Nicolin Chen wrote:
> Some NVIDIA GPU/NIC devices, though they don't implement CXL config space,
> have many CXL-like properties. Call this kind "pre-CXL".
>
> Similar to CXL.cache capability, these pre-CXL devices also require the ATS
> function even when their RIDs are IOMMU bypassed, i.e. keep ATS "always on"
> v.s. "on demand" when a non-zero PASID line gets enabled in SVA use cases.
>
> Introduce pci_dev_specific_ats_required() quirk function to scan a list of
> IDs for these devices. Then, include it in pci_ats_required().
>
> Suggested-by: Jason Gunthorpe <jgg@nvidia.com>
> Reviewed-by: Nirmoy Das <nirmoyd@nvidia.com>
> Tested-by: Nirmoy Das <nirmoyd@nvidia.com>
> Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>
> Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
> Reviewed-by: Kevin Tian <kevin.tian@intel.com>
> Reviewed-by: Dave Jiang <dave.jiang@intel.com>
> Acked-by: Bjorn Helgaas <bhelgaas@google.com>
> Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
> ---
Reviewed-by: Yi Liu <yi.l.liu@intel.com>
> drivers/pci/pci.h | 9 +++++++++
> drivers/pci/ats.c | 3 ++-
> drivers/pci/quirks.c | 42 ++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 53 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
> index 4a14f88e543a2..e8ad27abb1cfe 100644
> --- a/drivers/pci/pci.h
> +++ b/drivers/pci/pci.h
> @@ -1155,6 +1155,15 @@ static inline int pci_dev_specific_reset(struct pci_dev *dev, bool probe)
> }
> #endif
>
> +#if defined(CONFIG_PCI_QUIRKS) && defined(CONFIG_PCI_ATS)
> +bool pci_dev_specific_ats_required(struct pci_dev *dev);
> +#else
> +static inline bool pci_dev_specific_ats_required(struct pci_dev *dev)
> +{
> + return false;
> +}
> +#endif
> +
> #if defined(CONFIG_PCI_QUIRKS) && defined(CONFIG_ARM64)
> int acpi_get_rc_resources(struct device *dev, const char *hid, u16 segment,
> struct resource *res);
> diff --git a/drivers/pci/ats.c b/drivers/pci/ats.c
> index 84cd06d74fc9c..96efa00d97433 100644
> --- a/drivers/pci/ats.c
> +++ b/drivers/pci/ats.c
> @@ -247,7 +247,8 @@ bool pci_ats_required(struct pci_dev *pdev)
> if (pdev->is_virtfn)
> pdev = pci_physfn(pdev);
>
> - return pci_cxl_ats_required(pdev);
> + return pci_cxl_ats_required(pdev) ||
> + pci_dev_specific_ats_required(pdev);
> }
> EXPORT_SYMBOL_GPL(pci_ats_required);
>
> diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
> index caaed1a01dc02..c0242f3e9f063 100644
> --- a/drivers/pci/quirks.c
> +++ b/drivers/pci/quirks.c
> @@ -5715,6 +5715,48 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1457, quirk_intel_e2000_no_ats);
> DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1459, quirk_intel_e2000_no_ats);
> DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x145a, quirk_intel_e2000_no_ats);
> DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x145c, quirk_intel_e2000_no_ats);
> +
> +static bool quirk_nvidia_gpu_ats_required(struct pci_dev *pdev)
> +{
> + switch (pdev->device) {
> + case 0x2e00 ... 0x2e3f: /* GB20B */
> + return true;
> + }
> + return false;
> +}
> +
> +static const struct pci_dev_ats_required {
> + u16 vendor;
> + u16 device;
> + bool (*ats_required)(struct pci_dev *dev);
> +} pci_dev_ats_required[] = {
> + /* NVIDIA GPUs */
> + { PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID, quirk_nvidia_gpu_ats_required },
> + /* NVIDIA CX10 Family NVlink-C2C */
> + { PCI_VENDOR_ID_MELLANOX, 0x2101, NULL },
> + { 0 }
> +};
> +
> +/*
> + * Some NVIDIA devices do not implement CXL config space, but present as PCIe
> + * devices that can issue CXL-like cache operations like CXL.cache. Thus, they
> + * require ATS to obtain host physical addresses, like pci_cxl_ats_required().
> + */
> +bool pci_dev_specific_ats_required(struct pci_dev *pdev)
> +{
> + const struct pci_dev_ats_required *i;
> +
> + for (i = pci_dev_ats_required; i->vendor; i++) {
> + if (i->vendor != pdev->vendor)
> + continue;
> + if (i->ats_required && i->ats_required(pdev))
> + return true;
> + if (!i->ats_required && i->device == pdev->device)
> + return true;
> + }
> +
> + return false;
> +}
> #endif /* CONFIG_PCI_ATS */
>
> /* Freescale PCIe doesn't support MSI in RC mode */
^ permalink raw reply
* Re: [PATCH v6 1/3] PCI: Add pci_ats_required() for CXL.cache capable devices
From: Yi Liu @ 2026-05-22 9:19 UTC (permalink / raw)
To: Nicolin Chen, jgg, will
Cc: robin.murphy, joro, bhelgaas, praan, baolu.lu, kevin.tian,
miko.lenczewski, linux-arm-kernel, iommu, linux-kernel, linux-pci,
dan.j.williams, jonathan.cameron, vsethi, linux-cxl, nirmoyd
In-Reply-To: <05044d2113e20d81f96677ba53605311662b6b10.1779392420.git.nicolinc@nvidia.com>
On 5/22/26 04:34, Nicolin Chen wrote:
> Controlled by IOMMU drivers, ATS can be enabled "on demand", when a given
> PASID on a device is attached to an I/O page table. This is working, even
> when a device has no translation on its RID (i.e., RID is IOMMU bypassed).
>
> However, certain PCIe devices require non-PASID ATS on their RID even when
> the RID is IOMMU bypassed. Call this "ATS always on" in IOMMU term.
>
> For example, CXL spec r4.0 notes in sec 3.2.5.13 Memory Type on CXL.cache:
> "To source requests on CXL.cache, devices need to get the Host Physical
> Address (HPA) from the Host by means of an ATS request on CXL.io."
>
> In other words, the CXL.cache capability requires ATS; otherwise, it can't
> access host physical memory.
>
> Introduce a new pci_ats_required() helper for the IOMMU driver to scan a
> PCI device and shift ATS policies between "on demand" and "always on".
>
> Add the support for CXL.cache devices first. Pre-CXL devices will be added
> in quirks.c file.
>
> Note that pci_ats_required() validates against pci_ats_supported(), so we
> ensure that untrusted devices (e.g. external ports) will not be always on.
> This maintains the existing ATS security policy regarding potential side-
> channel attacks via ATS.
>
> Cc: linux-cxl@vger.kernel.org
> Suggested-by: Vikram Sethi <vsethi@nvidia.com>
> Suggested-by: Jason Gunthorpe <jgg@nvidia.com>
> Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>
> Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
> Reviewed-by: Kevin Tian <kevin.tian@intel.com>
> Tested-by: Nirmoy Das <nirmoyd@nvidia.com>
> Acked-by: Nirmoy Das <nirmoyd@nvidia.com>
> Reviewed-by: Dave Jiang <dave.jiang@intel.com>
> Acked-by: Bjorn Helgaas <bhelgaas@google.com>
> Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
> ---
Reviewed-by: Yi Liu <yi.l.liu@intel.com>
> include/linux/pci-ats.h | 3 +++
> include/uapi/linux/pci_regs.h | 1 +
> drivers/pci/ats.c | 46 +++++++++++++++++++++++++++++++++++
> 3 files changed, 50 insertions(+)
>
> diff --git a/include/linux/pci-ats.h b/include/linux/pci-ats.h
> index 75c6c86cf09dc..f3723b6861294 100644
> --- a/include/linux/pci-ats.h
> +++ b/include/linux/pci-ats.h
> @@ -12,6 +12,7 @@ int pci_prepare_ats(struct pci_dev *dev, int ps);
> void pci_disable_ats(struct pci_dev *dev);
> int pci_ats_queue_depth(struct pci_dev *dev);
> int pci_ats_page_aligned(struct pci_dev *dev);
> +bool pci_ats_required(struct pci_dev *dev);
> #else /* CONFIG_PCI_ATS */
> static inline bool pci_ats_supported(struct pci_dev *d)
> { return false; }
> @@ -24,6 +25,8 @@ static inline int pci_ats_queue_depth(struct pci_dev *d)
> { return -ENODEV; }
> static inline int pci_ats_page_aligned(struct pci_dev *dev)
> { return 0; }
> +static inline bool pci_ats_required(struct pci_dev *dev)
> +{ return false; }
> #endif /* CONFIG_PCI_ATS */
>
> #ifdef CONFIG_PCI_PRI
> diff --git a/include/uapi/linux/pci_regs.h b/include/uapi/linux/pci_regs.h
> index 14f634ab9350d..6ac45be1008b8 100644
> --- a/include/uapi/linux/pci_regs.h
> +++ b/include/uapi/linux/pci_regs.h
> @@ -1349,6 +1349,7 @@
> /* CXL r4.0, 8.1.3: PCIe DVSEC for CXL Device */
> #define PCI_DVSEC_CXL_DEVICE 0
> #define PCI_DVSEC_CXL_CAP 0xA
> +#define PCI_DVSEC_CXL_CACHE_CAPABLE _BITUL(0)
> #define PCI_DVSEC_CXL_MEM_CAPABLE _BITUL(2)
> #define PCI_DVSEC_CXL_HDM_COUNT __GENMASK(5, 4)
> #define PCI_DVSEC_CXL_CTRL 0xC
> diff --git a/drivers/pci/ats.c b/drivers/pci/ats.c
> index ec6c8dbdc5e9c..84cd06d74fc9c 100644
> --- a/drivers/pci/ats.c
> +++ b/drivers/pci/ats.c
> @@ -205,6 +205,52 @@ int pci_ats_page_aligned(struct pci_dev *pdev)
> return 0;
> }
>
> +/*
> + * CXL r4.0, sec 3.2.5.13 Memory Type on CXL.cache notes: to source requests on
> + * CXL.cache, devices need to get the Host Physical Address (HPA) from the Host
> + * by means of an ATS request on CXL.io.
> + *
> + * In other words, CXL.cache devices cannot access host physical memory without
> + * ATS.
> + *
> + * Check Cache_Capable instead of Cache_Enable because CXL.cache may be enabled
> + * after the caller uses this to make its ATS decision.
> + */
> +static bool pci_cxl_ats_required(struct pci_dev *pdev)
> +{
> + int offset;
> + u16 cap;
> +
> + offset = pci_find_dvsec_capability(pdev, PCI_VENDOR_ID_CXL,
> + PCI_DVSEC_CXL_DEVICE);
> + if (!offset)
> + return false;
> +
> + if (pci_read_config_word(pdev, offset + PCI_DVSEC_CXL_CAP, &cap))
> + return false;
> +
> + return cap & PCI_DVSEC_CXL_CACHE_CAPABLE;
> +}
> +
> +/**
> + * pci_ats_required - Whether the PCI device requires ATS
> + * @pdev: the PCI device
> + *
> + * Returns true, if the PCI device requires ATS for basic functional operation.
> + */
> +bool pci_ats_required(struct pci_dev *pdev)
> +{
> + if (!pci_ats_supported(pdev))
> + return false;
> +
> + /* A VF inherits its PF's requirement for ATS function */
> + if (pdev->is_virtfn)
> + pdev = pci_physfn(pdev);
> +
> + return pci_cxl_ats_required(pdev);
> +}
> +EXPORT_SYMBOL_GPL(pci_ats_required);
> +
> #ifdef CONFIG_PCI_PRI
> void pci_pri_init(struct pci_dev *pdev)
> {
^ permalink raw reply
* Re: [PATCH v22 08/13] mfd: core: Add firmware-node support to MFD cells
From: Bartosz Golaszewski @ 2026-05-22 9:08 UTC (permalink / raw)
To: Lee Jones
Cc: Shivendra Pratap, Sebastian Reichel, Mark Rutland,
Lorenzo Pieralisi, Rafael J. Wysocki, Daniel Lezcano,
Christian Loehle, Ulf Hansson, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Bjorn Andersson, Konrad Dybcio, Arnd Bergmann,
Souvik Chakravarty, Andy Yan, Matthias Brugger, John Stultz,
Moritz Fischer, Sudeep Holla, linux-pm, linux-kernel,
linux-arm-msm, linux-arm-kernel, devicetree, Florian Fainelli,
Krzysztof Kozlowski, Dmitry Baryshkov, Mukesh Ojha, Andre Draszik,
Greg Kroah-Hartman, Kathiravan Thirumoorthy, Srinivas Kandagatla,
Bartosz Golaszewski
In-Reply-To: <20260521162705.GH3591266@google.com>
On Thu, May 21, 2026 at 6:27 PM Lee Jones <lee@kernel.org> wrote:
>
> On Thu, 21 May 2026, Bartosz Golaszewski wrote:
>
> > On Thu, May 21, 2026 at 3:24 PM Lee Jones <lee@kernel.org> wrote:
> > >
> > > >
> > > > I suggested it because of its flexibility. The alternative I had in
> > > > mind is something like a new field in mfd_cell:
> > > >
> > > > const char *cell_node_name;
> > > >
> > > > Which - if set - would tell MFD to look up an fwnode that's a child of
> > > > the parent device's node by name - as it may not have a compatible.
> > >
> > > Remind me why the chlid device can't look-up its own fwnode?
> > >
> >
> > Oh sure it can, but should it? I'm not sure it's logically sound to
> > have the child device reach into the parent, look up the fwnode and
> > then assign it to itself after it's already attached to the driver.
> > This should be done at the subsystem level before the device is
> > registered.
>
> Leaf drivers reach back into the parent all the time.
>
But drivers don't generally assign firmware nodes to devices they are
already bound to. This is racy as in probe() the device is already
visible to the system. There's no synchronization of device property
access - properties are assumed to be read-only for a registered
device.
Bartosz
^ permalink raw reply
* Re: [PATCH 2/2] irqchip/gic-v3-its: Use GFP_ATOMIC_RT gfp flag in allocate_vpe_l1_table()
From: Lorenzo Stoakes @ 2026-05-22 9:06 UTC (permalink / raw)
To: Marc Zyngier
Cc: Waiman Long, Thomas Gleixner, Sebastian Andrzej Siewior,
Clark Williams, Steven Rostedt, Andrew Morton, David Hildenbrand,
Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
Suren Baghdasaryan, Michal Hocko, linux-arm-kernel, linux-kernel,
linux-mm, linux-rt-devel
In-Reply-To: <861pf3x3hc.wl-maz@kernel.org>
On Fri, May 22, 2026 at 09:17:35AM +0100, Marc Zyngier wrote:
> On Wed, 20 May 2026 21:46:28 +0100,
> Waiman Long <longman@redhat.com> wrote:
> >
> > A longer term solution is to defer the allocation to a later stage of the
> > hotplug pipeline where interrupt isn't disabled.
>
> And that's what needs doing. Not papering over this in a bizarre way.
> I proposed a potential solution a few months back, but didn't get a
> chance to work on it. If you have the bandwidth, that's the way to go.
>
> But papering over this issue this way seems like a bad case of short
> term and unsustainable hack.
Yes, agreed. It really smacks of trying the fix the problem at the wrong level
of abstraction.
>
> Thanks,
>
> M.
>
> --
> Without deviation from the norm, progress is not possible.
Cheers, Lorenzo
^ permalink raw reply
* [PATCH v3 1/3] selftests/resctrl: Introduce linked list management for IMC counters
From: Yifan Wu @ 2026-05-22 9:05 UTC (permalink / raw)
To: wuyifan50, tony.luck, reinette.chatre, Dave.Martin, james.morse,
babu.moger, shuah, tan.shaopeng, fenghuay, ben.horgan, zengheng4,
linux-kernel, linux-arm-kernel, linux-kselftest, linuxarm
Cc: xiaqinxin, prime.zeng, wangyushan12, xuwei5, fanghao11, wangzhou1
In-Reply-To: <20260522090540.444554-1-wuyifan50@huawei.com>
The static array approach to managing IMC counters has fixed size
constraints and limited compatibility and scalability. Introduce
a linked list-based dynamic management infrastructure to address
these limitations. Add the core data structure definitions and
memory allocation and cleanup functions for dynamic counter
configurations.
Signed-off-by: Yifan Wu <wuyifan50@huawei.com>
---
tools/testing/selftests/resctrl/mba_test.c | 1 +
tools/testing/selftests/resctrl/mbm_test.c | 1 +
tools/testing/selftests/resctrl/resctrl.h | 2 ++
tools/testing/selftests/resctrl/resctrl_val.c | 27 +++++++++++++++++--
4 files changed, 29 insertions(+), 2 deletions(-)
diff --git a/tools/testing/selftests/resctrl/mba_test.c b/tools/testing/selftests/resctrl/mba_test.c
index 39cee9898359..4bb1a82eb195 100644
--- a/tools/testing/selftests/resctrl/mba_test.c
+++ b/tools/testing/selftests/resctrl/mba_test.c
@@ -166,6 +166,7 @@ static int check_results(void)
static void mba_test_cleanup(void)
{
+ cleanup_read_mem_bw_imc();
remove(RESULT_FILE_NAME);
}
diff --git a/tools/testing/selftests/resctrl/mbm_test.c b/tools/testing/selftests/resctrl/mbm_test.c
index 6dbbc3b76003..68c89f50a34a 100644
--- a/tools/testing/selftests/resctrl/mbm_test.c
+++ b/tools/testing/selftests/resctrl/mbm_test.c
@@ -125,6 +125,7 @@ static int mbm_measure(const struct user_params *uparams,
static void mbm_test_cleanup(void)
{
+ cleanup_read_mem_bw_imc();
remove(RESULT_FILE_NAME);
}
diff --git a/tools/testing/selftests/resctrl/resctrl.h b/tools/testing/selftests/resctrl/resctrl.h
index 175101022bf3..a7556cdae0de 100644
--- a/tools/testing/selftests/resctrl/resctrl.h
+++ b/tools/testing/selftests/resctrl/resctrl.h
@@ -24,6 +24,7 @@
#include <linux/perf_event.h>
#include <linux/compiler.h>
#include <linux/bits.h>
+#include <linux/list.h>
#include "kselftest.h"
#define MB (1024 * 1024)
@@ -183,6 +184,7 @@ void mem_flush(unsigned char *buf, size_t buf_size);
void fill_cache_read(unsigned char *buf, size_t buf_size, bool once);
ssize_t get_fill_buf_size(int cpu_no, const char *cache_type);
int initialize_read_mem_bw_imc(void);
+void cleanup_read_mem_bw_imc(void);
int measure_read_mem_bw(const struct user_params *uparams,
struct resctrl_val_param *param, pid_t bm_pid);
void initialize_mem_bw_resctrl(const struct resctrl_val_param *param,
diff --git a/tools/testing/selftests/resctrl/resctrl_val.c b/tools/testing/selftests/resctrl/resctrl_val.c
index f20d2194c35f..a72dc4ae61fe 100644
--- a/tools/testing/selftests/resctrl/resctrl_val.c
+++ b/tools/testing/selftests/resctrl/resctrl_val.c
@@ -28,6 +28,7 @@ struct membw_read_format {
};
struct imc_counter_config {
+ struct list_head entry;
__u32 type;
__u64 event;
__u64 umask;
@@ -38,6 +39,7 @@ struct imc_counter_config {
static char mbm_total_path[1024];
static int imcs;
static struct imc_counter_config imc_counters_config[MAX_IMCS];
+LIST_HEAD(imc_counters_list);
static const struct resctrl_test *current_test;
static void read_mem_bw_initialize_perf_event_attr(int i)
@@ -113,6 +115,7 @@ static int parse_imc_read_bw_events(char *imc_dir, unsigned int type,
unsigned int *count)
{
char imc_events_dir[PATH_MAX], imc_counter_cfg[PATH_MAX];
+ struct imc_counter_config *imc_counter;
unsigned int orig_count = *count;
char cas_count_cfg[1024];
struct dirent *ep;
@@ -126,13 +129,13 @@ static int parse_imc_read_bw_events(char *imc_dir, unsigned int type,
imc_dir);
if (path_len >= sizeof(imc_events_dir)) {
ksft_print_msg("Unable to create path to %sevents\n", imc_dir);
- return -1;
+ goto out;
}
dp = opendir(imc_events_dir);
if (!dp) {
ksft_perror("Unable to open PMU events directory");
- return -1;
+ goto out;
}
while ((ep = readdir(dp))) {
@@ -167,11 +170,17 @@ static int parse_imc_read_bw_events(char *imc_dir, unsigned int type,
ksft_print_msg("Maximum iMC count exceeded\n");
goto out_close;
}
+ imc_counter = calloc(1, sizeof(*imc_counter));
+ if (!imc_counter) {
+ ksft_perror("Unable to allocate memory for iMC counters");
+ goto out_close;
+ }
imc_counters_config[*count].type = type;
get_read_event_and_umask(cas_count_cfg, *count);
/* Do not fail after incrementing *count. */
*count += 1;
+ list_add(&imc_counter->entry, &imc_counters_list);
}
if (*count == orig_count) {
ksft_print_msg("Unable to find events in %s\n", imc_events_dir);
@@ -180,6 +189,10 @@ static int parse_imc_read_bw_events(char *imc_dir, unsigned int type,
ret = 0;
out_close:
closedir(dp);
+out:
+ if (ret)
+ cleanup_read_mem_bw_imc();
+
return ret;
}
@@ -303,6 +316,16 @@ int initialize_read_mem_bw_imc(void)
return 0;
}
+void cleanup_read_mem_bw_imc(void)
+{
+ struct imc_counter_config *imc_counter, *tmp;
+
+ list_for_each_entry_safe(imc_counter, tmp, &imc_counters_list, entry) {
+ list_del(&imc_counter->entry);
+ free(imc_counter);
+ }
+}
+
static void perf_close_imc_read_mem_bw(void)
{
int mc;
--
2.34.1
^ permalink raw reply related
* [PATCH v3 2/3] selftests/resctrl: Replace counter index references with pointers
From: Yifan Wu @ 2026-05-22 9:05 UTC (permalink / raw)
To: wuyifan50, tony.luck, reinette.chatre, Dave.Martin, james.morse,
babu.moger, shuah, tan.shaopeng, fenghuay, ben.horgan, zengheng4,
linux-kernel, linux-arm-kernel, linux-kselftest, linuxarm
Cc: xiaqinxin, prime.zeng, wangyushan12, xuwei5, fanghao11, wangzhou1
In-Reply-To: <20260522090540.444554-1-wuyifan50@huawei.com>
Replace direct counter number references with pointers to remove the
dependency on fixed array indexing and enable the use of different
data structures for counter management.
Signed-off-by: Yifan Wu <wuyifan50@huawei.com>
---
tools/testing/selftests/resctrl/resctrl_val.c | 62 +++++++++----------
1 file changed, 31 insertions(+), 31 deletions(-)
diff --git a/tools/testing/selftests/resctrl/resctrl_val.c b/tools/testing/selftests/resctrl/resctrl_val.c
index a72dc4ae61fe..3d2b6919717a 100644
--- a/tools/testing/selftests/resctrl/resctrl_val.c
+++ b/tools/testing/selftests/resctrl/resctrl_val.c
@@ -42,40 +42,40 @@ static struct imc_counter_config imc_counters_config[MAX_IMCS];
LIST_HEAD(imc_counters_list);
static const struct resctrl_test *current_test;
-static void read_mem_bw_initialize_perf_event_attr(int i)
+static void read_mem_bw_initialize_perf_event_attr(struct imc_counter_config *imc_counter)
{
- memset(&imc_counters_config[i].pe, 0,
+ memset(&imc_counter->pe, 0,
sizeof(struct perf_event_attr));
- imc_counters_config[i].pe.type = imc_counters_config[i].type;
- imc_counters_config[i].pe.size = sizeof(struct perf_event_attr);
- imc_counters_config[i].pe.disabled = 1;
- imc_counters_config[i].pe.inherit = 1;
- imc_counters_config[i].pe.exclude_guest = 0;
- imc_counters_config[i].pe.config =
- imc_counters_config[i].umask << 8 |
- imc_counters_config[i].event;
- imc_counters_config[i].pe.sample_type = PERF_SAMPLE_IDENTIFIER;
- imc_counters_config[i].pe.read_format =
+ imc_counter->pe.type = imc_counter->type;
+ imc_counter->pe.size = sizeof(struct perf_event_attr);
+ imc_counter->pe.disabled = 1;
+ imc_counter->pe.inherit = 1;
+ imc_counter->pe.exclude_guest = 0;
+ imc_counter->pe.config =
+ imc_counter->umask << 8 |
+ imc_counter->event;
+ imc_counter->pe.sample_type = PERF_SAMPLE_IDENTIFIER;
+ imc_counter->pe.read_format =
PERF_FORMAT_TOTAL_TIME_ENABLED | PERF_FORMAT_TOTAL_TIME_RUNNING;
}
-static void read_mem_bw_ioctl_perf_event_ioc_reset_enable(int i)
+static void read_mem_bw_ioctl_perf_event_ioc_reset_enable(struct imc_counter_config *imc_counter)
{
- ioctl(imc_counters_config[i].fd, PERF_EVENT_IOC_RESET, 0);
- ioctl(imc_counters_config[i].fd, PERF_EVENT_IOC_ENABLE, 0);
+ ioctl(imc_counter->fd, PERF_EVENT_IOC_RESET, 0);
+ ioctl(imc_counter->fd, PERF_EVENT_IOC_ENABLE, 0);
}
-static void read_mem_bw_ioctl_perf_event_ioc_disable(int i)
+static void read_mem_bw_ioctl_perf_event_ioc_disable(struct imc_counter_config *imc_counter)
{
- ioctl(imc_counters_config[i].fd, PERF_EVENT_IOC_DISABLE, 0);
+ ioctl(imc_counter->fd, PERF_EVENT_IOC_DISABLE, 0);
}
/*
* get_read_event_and_umask: Parse config into event and umask
* @cas_count_cfg: Config
- * @count: iMC number
+ * @imc_counter: iMC counter config
*/
-static void get_read_event_and_umask(char *cas_count_cfg, unsigned int count)
+static void get_read_event_and_umask(char *cas_count_cfg, struct imc_counter_config *imc_counter)
{
char *token[MAX_TOKENS];
int i = 0;
@@ -89,21 +89,21 @@ static void get_read_event_and_umask(char *cas_count_cfg, unsigned int count)
if (!token[i])
break;
if (strcmp(token[i], "event") == 0)
- imc_counters_config[count].event = strtol(token[i + 1], NULL, 16);
+ imc_counter->event = strtol(token[i + 1], NULL, 16);
if (strcmp(token[i], "umask") == 0)
- imc_counters_config[count].umask = strtol(token[i + 1], NULL, 16);
+ imc_counter->umask = strtol(token[i + 1], NULL, 16);
}
}
-static int open_perf_read_event(int i, int cpu_no)
+static int open_perf_read_event(int cpu_no, struct imc_counter_config *imc_counter)
{
- imc_counters_config[i].fd =
- perf_event_open(&imc_counters_config[i].pe, -1, cpu_no, -1,
+ imc_counter->fd =
+ perf_event_open(&imc_counter->pe, -1, cpu_no, -1,
PERF_FLAG_FD_CLOEXEC);
- if (imc_counters_config[i].fd == -1) {
+ if (imc_counter->fd == -1) {
fprintf(stderr, "Error opening leader %llx\n",
- imc_counters_config[i].pe.config);
+ imc_counter->pe.config);
return -1;
}
@@ -177,7 +177,7 @@ static int parse_imc_read_bw_events(char *imc_dir, unsigned int type,
}
imc_counters_config[*count].type = type;
- get_read_event_and_umask(cas_count_cfg, *count);
+ get_read_event_and_umask(cas_count_cfg, &imc_counters_config[*count]);
/* Do not fail after incrementing *count. */
*count += 1;
list_add(&imc_counter->entry, &imc_counters_list);
@@ -311,7 +311,7 @@ int initialize_read_mem_bw_imc(void)
/* Initialize perf_event_attr structures for all iMC's */
for (imc = 0; imc < imcs; imc++)
- read_mem_bw_initialize_perf_event_attr(imc);
+ read_mem_bw_initialize_perf_event_attr(&imc_counters_config[imc]);
return 0;
}
@@ -350,7 +350,7 @@ static int perf_open_imc_read_mem_bw(int cpu_no)
imc_counters_config[imc].fd = -1;
for (imc = 0; imc < imcs; imc++) {
- ret = open_perf_read_event(imc, cpu_no);
+ ret = open_perf_read_event(cpu_no, &imc_counters_config[imc]);
if (ret)
goto close_fds;
}
@@ -373,13 +373,13 @@ static void do_imc_read_mem_bw_test(void)
int imc;
for (imc = 0; imc < imcs; imc++)
- read_mem_bw_ioctl_perf_event_ioc_reset_enable(imc);
+ read_mem_bw_ioctl_perf_event_ioc_reset_enable(&imc_counters_config[imc]);
sleep(1);
/* Stop counters after a second to get results. */
for (imc = 0; imc < imcs; imc++)
- read_mem_bw_ioctl_perf_event_ioc_disable(imc);
+ read_mem_bw_ioctl_perf_event_ioc_disable(&imc_counters_config[imc]);
}
/*
--
2.34.1
^ permalink raw reply related
* [PATCH v3 3/3] selftests/resctrl: Enable dynamic management of IMC counters via linked list
From: Yifan Wu @ 2026-05-22 9:05 UTC (permalink / raw)
To: wuyifan50, tony.luck, reinette.chatre, Dave.Martin, james.morse,
babu.moger, shuah, tan.shaopeng, fenghuay, ben.horgan, zengheng4,
linux-kernel, linux-arm-kernel, linux-kselftest, linuxarm
Cc: xiaqinxin, prime.zeng, wangyushan12, xuwei5, fanghao11, wangzhou1
In-Reply-To: <20260522090540.444554-1-wuyifan50@huawei.com>
Remove the static array and the count and upper limit checks during
initialization, allowing the system to dynamically use all available
IMC counters detected by hardware.
Signed-off-by: Yifan Wu <wuyifan50@huawei.com>
---
tools/testing/selftests/resctrl/resctrl_val.c | 85 +++++++++----------
1 file changed, 38 insertions(+), 47 deletions(-)
diff --git a/tools/testing/selftests/resctrl/resctrl_val.c b/tools/testing/selftests/resctrl/resctrl_val.c
index 3d2b6919717a..129e8d76222a 100644
--- a/tools/testing/selftests/resctrl/resctrl_val.c
+++ b/tools/testing/selftests/resctrl/resctrl_val.c
@@ -14,7 +14,6 @@
#define READ_FILE_NAME "cas_count_read"
#define DYN_PMU_PATH "/sys/bus/event_source/devices"
#define SCALE 0.00006103515625
-#define MAX_IMCS 40
#define MAX_TOKENS 5
#define CON_MBM_LOCAL_BYTES_PATH \
@@ -37,8 +36,6 @@ struct imc_counter_config {
};
static char mbm_total_path[1024];
-static int imcs;
-static struct imc_counter_config imc_counters_config[MAX_IMCS];
LIST_HEAD(imc_counters_list);
static const struct resctrl_test *current_test;
@@ -111,12 +108,11 @@ static int open_perf_read_event(int cpu_no, struct imc_counter_config *imc_count
return 0;
}
-static int parse_imc_read_bw_events(char *imc_dir, unsigned int type,
- unsigned int *count)
+static int parse_imc_read_bw_events(char *imc_dir, unsigned int type)
{
char imc_events_dir[PATH_MAX], imc_counter_cfg[PATH_MAX];
struct imc_counter_config *imc_counter;
- unsigned int orig_count = *count;
+ bool found_event = false;
char cas_count_cfg[1024];
struct dirent *ep;
int path_len;
@@ -166,23 +162,18 @@ static int parse_imc_read_bw_events(char *imc_dir, unsigned int type,
ksft_perror("Could not get iMC cas count read");
goto out_close;
}
- if (*count >= MAX_IMCS) {
- ksft_print_msg("Maximum iMC count exceeded\n");
- goto out_close;
- }
imc_counter = calloc(1, sizeof(*imc_counter));
if (!imc_counter) {
ksft_perror("Unable to allocate memory for iMC counters");
goto out_close;
}
- imc_counters_config[*count].type = type;
- get_read_event_and_umask(cas_count_cfg, &imc_counters_config[*count]);
- /* Do not fail after incrementing *count. */
- *count += 1;
+ imc_counter->type = type;
+ get_read_event_and_umask(cas_count_cfg, imc_counter);
list_add(&imc_counter->entry, &imc_counters_list);
+ found_event = true;
}
- if (*count == orig_count) {
+ if (!found_event) {
ksft_print_msg("Unable to find events in %s\n", imc_events_dir);
goto out_close;
}
@@ -197,7 +188,7 @@ static int parse_imc_read_bw_events(char *imc_dir, unsigned int type,
}
/* Get type and config of an iMC counter's read event. */
-static int read_from_imc_dir(char *imc_dir, unsigned int *count)
+static int read_from_imc_dir(char *imc_dir)
{
char imc_counter_type[PATH_MAX];
unsigned int type;
@@ -225,7 +216,7 @@ static int read_from_imc_dir(char *imc_dir, unsigned int *count)
ksft_perror("Could not get iMC type");
return -1;
}
- ret = parse_imc_read_bw_events(imc_dir, type, count);
+ ret = parse_imc_read_bw_events(imc_dir, type);
if (ret) {
ksft_print_msg("Unable to parse bandwidth event and umask\n");
return ret;
@@ -242,14 +233,13 @@ static int read_from_imc_dir(char *imc_dir, unsigned int *count)
* counter's event and umask for the memory read events that will be
* measured.
*
- * Enumerate all these details into an array of structures.
+ * Enumerate all these details into a linked list of structures.
*
* Return: >= 0 on success. < 0 on failure.
*/
-static int num_of_imcs(void)
+static int enumerate_imcs(void)
{
char imc_dir[512], *temp;
- unsigned int count = 0;
struct dirent *ep;
int ret;
DIR *dp;
@@ -278,7 +268,7 @@ static int num_of_imcs(void)
if (temp[0] >= '0' && temp[0] <= '9') {
sprintf(imc_dir, "%s/%s/", DYN_PMU_PATH,
ep->d_name);
- ret = read_from_imc_dir(imc_dir, &count);
+ ret = read_from_imc_dir(imc_dir);
if (ret) {
closedir(dp);
@@ -287,7 +277,7 @@ static int num_of_imcs(void)
}
}
closedir(dp);
- if (count == 0) {
+ if (list_empty(&imc_counters_list)) {
ksft_print_msg("Unable to find iMC counters\n");
return -1;
@@ -298,20 +288,22 @@ static int num_of_imcs(void)
return -1;
}
- return count;
+ return 0;
}
int initialize_read_mem_bw_imc(void)
{
- int imc;
+ struct imc_counter_config *imc_counter;
+ int ret;
- imcs = num_of_imcs();
- if (imcs <= 0)
- return imcs;
+ ret = enumerate_imcs();
+ if (ret < 0)
+ return ret;
/* Initialize perf_event_attr structures for all iMC's */
- for (imc = 0; imc < imcs; imc++)
- read_mem_bw_initialize_perf_event_attr(&imc_counters_config[imc]);
+ list_for_each_entry(imc_counter, &imc_counters_list, entry) {
+ read_mem_bw_initialize_perf_event_attr(imc_counter);
+ }
return 0;
}
@@ -328,11 +320,11 @@ void cleanup_read_mem_bw_imc(void)
static void perf_close_imc_read_mem_bw(void)
{
- int mc;
+ struct imc_counter_config *imc_counter;
- for (mc = 0; mc < imcs; mc++) {
- if (imc_counters_config[mc].fd != -1)
- close(imc_counters_config[mc].fd);
+ list_for_each_entry(imc_counter, &imc_counters_list, entry) {
+ if (imc_counter->fd != -1)
+ close(imc_counter->fd);
}
}
@@ -344,13 +336,14 @@ static void perf_close_imc_read_mem_bw(void)
*/
static int perf_open_imc_read_mem_bw(int cpu_no)
{
- int imc, ret;
+ struct imc_counter_config *imc_counter;
+ int ret;
- for (imc = 0; imc < imcs; imc++)
- imc_counters_config[imc].fd = -1;
+ list_for_each_entry(imc_counter, &imc_counters_list, entry)
+ imc_counter->fd = -1;
- for (imc = 0; imc < imcs; imc++) {
- ret = open_perf_read_event(cpu_no, &imc_counters_config[imc]);
+ list_for_each_entry(imc_counter, &imc_counters_list, entry) {
+ ret = open_perf_read_event(cpu_no, imc_counter);
if (ret)
goto close_fds;
}
@@ -370,16 +363,16 @@ static int perf_open_imc_read_mem_bw(int cpu_no)
*/
static void do_imc_read_mem_bw_test(void)
{
- int imc;
+ struct imc_counter_config *imc_counter;
- for (imc = 0; imc < imcs; imc++)
- read_mem_bw_ioctl_perf_event_ioc_reset_enable(&imc_counters_config[imc]);
+ list_for_each_entry(imc_counter, &imc_counters_list, entry)
+ read_mem_bw_ioctl_perf_event_ioc_reset_enable(imc_counter);
sleep(1);
/* Stop counters after a second to get results. */
- for (imc = 0; imc < imcs; imc++)
- read_mem_bw_ioctl_perf_event_ioc_disable(&imc_counters_config[imc]);
+ list_for_each_entry(imc_counter, &imc_counters_list, entry)
+ read_mem_bw_ioctl_perf_event_ioc_disable(imc_counter);
}
/*
@@ -394,17 +387,15 @@ static void do_imc_read_mem_bw_test(void)
static int get_read_mem_bw_imc(float *bw_imc)
{
float reads = 0, of_mul_read = 1;
- int imc;
+ struct imc_counter_config *r;
/*
* Log read event values from all iMC counters into
* struct imc_counter_config.
* Take overflow into consideration before calculating total bandwidth.
*/
- for (imc = 0; imc < imcs; imc++) {
+ list_for_each_entry(r, &imc_counters_list, entry) {
struct membw_read_format measurement;
- struct imc_counter_config *r =
- &imc_counters_config[imc];
if (read(r->fd, &measurement, sizeof(measurement)) == -1) {
ksft_perror("Couldn't get read bandwidth through iMC");
--
2.34.1
^ 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