* Re: [PATCH v7 11/30] drm/display: bridge_connector: Wire up HDMI 2.0 scrambler callbacks
From: Maxime Ripard @ 2026-06-12 8:52 UTC (permalink / raw)
To: Cristian Ciocaltea
Cc: Maarten Lankhorst, Thomas Zimmermann, David Airlie, Simona Vetter,
Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
Jonas Karlman, Jernej Skrabec, Luca Ceresoli, Sandy Huang,
Heiko Stübner, Andy Yan, Daniel Stone, Dave Stevenson,
Maíra Canal, Raspberry Pi Kernel Maintenance, kernel,
dri-devel, linux-kernel, linux-arm-kernel, linux-rockchip
In-Reply-To: <20260602-dw-hdmi-qp-scramb-v7-11-445eb54ee1ed@collabora.com>
[-- Attachment #1: Type: text/plain, Size: 4179 bytes --]
On Tue, Jun 02, 2026 at 01:44:11AM +0300, Cristian Ciocaltea wrote:
> Connect the bridge connector's .scrambler_{enable|disable} callbacks to
> the underlying bridge's .hdmi_scrambler_{enable|disable} funcs when
> DRM_BRIDGE_OP_HDMI_SCRAMBLER is advertised.
>
> This completes the bridge connector plumbing so that the SCDC
> scrambling helpers can control source-side scrambling through the
> bridge chain.
>
> Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
> ---
> drivers/gpu/drm/display/drm_bridge_connector.c | 41 +++++++++++++++++++++++++-
> 1 file changed, 40 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/display/drm_bridge_connector.c b/drivers/gpu/drm/display/drm_bridge_connector.c
> index 9d21b1b57b0d..d048ab49eade 100644
> --- a/drivers/gpu/drm/display/drm_bridge_connector.c
> +++ b/drivers/gpu/drm/display/drm_bridge_connector.c
> @@ -555,6 +555,32 @@ static int drm_bridge_connector_write_spd_infoframe(struct drm_connector *connec
> return bridge->funcs->hdmi_write_spd_infoframe(bridge, buffer, len);
> }
>
> +static int drm_bridge_connector_scrambler_enable(struct drm_connector *connector)
> +{
> + struct drm_bridge_connector *bridge_connector =
> + to_drm_bridge_connector(connector);
> + struct drm_bridge *bridge;
> +
> + bridge = bridge_connector->bridge_hdmi;
> + if (!bridge)
> + return -EINVAL;
> +
> + return bridge->funcs->hdmi_scrambler_enable(bridge);
> +}
> +
> +static int drm_bridge_connector_scrambler_disable(struct drm_connector *connector)
> +{
> + struct drm_bridge_connector *bridge_connector =
> + to_drm_bridge_connector(connector);
> + struct drm_bridge *bridge;
> +
> + bridge = bridge_connector->bridge_hdmi;
> + if (!bridge)
> + return -EINVAL;
> +
> + return bridge->funcs->hdmi_scrambler_disable(bridge);
> +}
> +
> static const struct drm_edid *
> drm_bridge_connector_read_edid(struct drm_connector *connector)
> {
> @@ -580,7 +606,7 @@ static const struct drm_connector_hdmi_funcs drm_bridge_connector_hdmi_funcs = {
> .clear_infoframe = drm_bridge_connector_clear_hdmi_infoframe,
> .write_infoframe = drm_bridge_connector_write_hdmi_infoframe,
> },
> - /* audio, hdr_drm and spd are set dynamically during init */
> + /* scrambler, audio, hdr_drm and spd are set dynamically during init */
> };
>
> static const struct drm_connector_infoframe_funcs drm_bridge_connector_hdmi_audio_infoframe = {
> @@ -886,6 +912,11 @@ struct drm_connector *drm_bridge_connector_init(struct drm_device *drm,
> !bridge->funcs->hdmi_clear_spd_infoframe))
> return ERR_PTR(-EINVAL);
>
> + if (bridge->ops & DRM_BRIDGE_OP_HDMI_SCRAMBLER &&
> + (!bridge->funcs->hdmi_scrambler_enable ||
> + !bridge->funcs->hdmi_scrambler_disable))
> + return ERR_PTR(-EINVAL);
> +
> bridge_connector->bridge_hdmi = drm_bridge_get(bridge);
>
> if (bridge->supported_formats)
> @@ -990,6 +1021,14 @@ struct drm_connector *drm_bridge_connector_init(struct drm_device *drm,
> bridge_connector->hdmi_funcs.spd =
> drm_bridge_connector_hdmi_spd_infoframe;
>
> + if (bridge_connector->bridge_hdmi->ops & DRM_BRIDGE_OP_HDMI_SCRAMBLER) {
> + bridge_connector->hdmi_funcs.scrambler_enable =
> + drm_bridge_connector_scrambler_enable;
> + bridge_connector->hdmi_funcs.scrambler_disable =
> + drm_bridge_connector_scrambler_disable;
> + connector->hdmi.scrambler_supported = true;
> + }
> +
I think we're taking this backwards. The scrambler support isn't
optional: either the controller supports HDMI < 2.0, and then it doesn't
exist, or it supports >= 2.0 and then it's mandatory.
You're considering it optional here, when it's never actually optional
(unlike YUV420 for example)
I still think we should list, somehow, the capabilities of the
controller to the helpers, like max tmds rate supported, formats, etc.
We've so far put everything as an argument to drmm_connector_hdmi_init
but it becomes a bit overloaded, and I wonder if introducing a callback
wouldn't solve this, kind of like what we have for planes and formats.
Maxime
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 273 bytes --]
^ permalink raw reply
* Re: [GIT PULL] KVM/arm64 updates for 7.2
From: Paolo Bonzini @ 2026-06-12 8:52 UTC (permalink / raw)
To: Marc Zyngier
Cc: Anshuman Khandual, Catalin Marinas, Eric Auger, Fuad Tabba,
Hyunwoo Kim, Jackie Liu, Joey Gouly, Mark Rutland, Oliver Upton,
Sascha Bischoff, Vincent Donnefort, Wei-Lin Chang, Will Deacon,
Zenghui Yu, Steffen Eiden, Suzuki K Poulose, Zenghui Yu, kvmarm,
kvm, linux-arm-kernel
In-Reply-To: <20260612084835.2992552-1-maz@kernel.org>
On Fri, Jun 12, 2026 at 10:48 AM Marc Zyngier <maz@kernel.org> wrote:
>
> Paolo,
>
> This is a bit of an odd merge window on the KVM/arm64 front. There is
> absolutely no new feature in the pull request. It is purely fixes,
> because it is simply becoming too hard to review new stuff when so
> many AI-fuelled fixes hit the list. And even then, I've arbitrarily
> tagged the branch today, knowing that there is quite a backlog of
> fixes that I will send very shortly, probably before -rc1.
No problem. Since I usually wait for the arch code to be merged before
sending my PRs, you have almost a week to send them and have them
included in the very first PRs.
Pulled these for now, thanks.
Paolo
> So here it is: only fixes and very minor improvements, all over the
> place. Details in the tag below.
>
> Please pull,
>
> M.
>
> The following changes since commit 5200f5f493f79f14bbdc349e402a40dfb32f23c8:
>
> Linux 7.1-rc4 (2026-05-17 13:59:58 -0700)
>
> are available in the Git repository at:
>
> git://git.kernel.org/pub/scm/linux/kernel/git/kvmarm/kvmarm.git tags/kvmarm-7.2
>
> for you to fetch changes up to 1ee27dacbe5dc4def481794d899d67b0d4570094:
>
> Merge branch kvm-arm64/nv-mmu-7.2 into kvmarm-master/next (2026-06-12 09:29:34 +0100)
>
> ----------------------------------------------------------------
> KVM/arm64 updates for 7.2
>
> * New features:
>
> - None. Zilch. Nada. Que dalle.
>
> * Fixes and other improvements:
>
> - Significant cleanup of the vgic-v5 PPI support which was merged in
> 7.1. This makes the code more maintainable, and squashes a couple
> of bugs in the meantime.
>
> - Set of fixes for the handling of the MMU in an NV context,
> particularly VNCR-triggered faults. S1POE support is fixed
> as well.
>
> - Large set of pKVM fixes, mostly addressing recurring issues
> around hypervisor tracking of donated pages in obscure cases
> where the donation could fail and leave things in a bizarre
> state.
>
> - Fixes for the so-called "lazy vgic init", which resulted in
> sleeping operations in non-preemptible sections. This turned
> out to be far more invasive than initially expected...
>
> - Reduce the overhead of L1/L2 context switch by not touching
> the FP registers.
>
> - Fix the way non-implemented page sizes are dealt with when
> a guest insist on using them for S2 translation.
>
> - The usual set of low-impact fixes and cleanups all over the map.
>
> ----------------------------------------------------------------
> Fuad Tabba (5):
> KVM: arm64: Guard against NULL vcpu on VHE hyp panic path
> KVM: arm64: Fix __deactivate_fgt macro parameter typo
> KVM: arm64: Seed pkvm_ownership_selftest vcpu memcache
> KVM: arm64: Pre-check vcpu memcache for host->guest share
> KVM: arm64: Pre-check vcpu memcache for host->guest donate
>
> Hyunwoo Kim (2):
> KVM: arm64: Clear __hyp_running_vcpu when flushing the pKVM hyp vCPU
> KVM: arm64: Bound used_lrs when flushing the pKVM hyp vCPU
>
> Jackie Liu (1):
> KVM: arm64: vgic-its: Make ABI commit helpers return void
>
> Marc Zyngier (29):
> KVM: arm64: nv: Track L2 to L1 exception emulation
> KVM: arm64: nv: Don't save/restore FP register during a nested ERET or exception
> KVM: arm64: timer: Repaint kvm_timer_{should,irq_can}_fire() to kvm_timer_{pending,enabled}()
> KVM: arm64: Simplify userspace notification of interrupt state
> KVM: arm64: timer: Kill the per-timer irq level cache
> KVM: arm64: pmu: Kill the PMU interrupt level cache
> KVM: arm64: vgic-v2: Force vgic init on injection outside the run loop
> KVM: arm64: vgic-v2: Don't init the vgic on in-kernel interrupt injection
> KVM: arm64: vgic-v5: Add for_each_visible_v5_ppi() iterator
> KVM: arm64: vgic-v5: Move PPI caps into kvm_vgic_global_state
> KVM: arm64: vgic-v5: Remove use of __assign_bit() with a constant
> KVM: arm64: vgic-v5: Drop pointless ARM64_HAS_GICV5_CPUIF check
> KVM: arm64: vgic: Constify struct irq_ops usage
> KVM: arm64: vgic: Consolidate vgic_allocate_private_irqs_locked()
> KVM: arm64: vgic-v5: Drop defensive checks from vgic_v5_ppi_queue_irq_unlock()
> KVM: arm64: vgic: Rationalise per-CPU irq accessor
> KVM: arm64: vgic-v5: Limit support to 64 PPIs
> KVM: arm64: Key CPTR_EL2.E0POE propagation on FEAT_S1POE
> KVM: arm64: Wire AT S1E1A in the system instruction handling table
> arm64: cpufeature: Expose ID_AA64ISAR2_EL1.ATS1A to KVM
> KVM: arm64: nv: Avoid dereferencing NULL VNCR pseudo-TLB
> KVM: arm64: nv: Hold kvm->mmu_lock while initialising vcpu->arch.vncr_tlb
> Merge branch kvm-arm64/no-lazy-vgic-init into kvmarm-master/next
> Merge branch kvm-arm64/nv-fp-elision into kvmarm-master/next
> Merge branch kvm-arm64/nv-granule-sizes into kvmarm-master/next
> Merge branch kvm-arm64/pkvm-fixes-7.2 into kvmarm-master/next
> Merge branch kvm-arm64/vgic-v5-PPI-fixes into kvmarm-master/next
> Merge branch kvm-arm64/misc-7.2 into kvmarm-master/next
> Merge branch kvm-arm64/nv-mmu-7.2 into kvmarm-master/next
>
> Oliver Upton (5):
> KVM: arm64: Don't leak PFN when kvm_translate_vncr() races MMU notifier
> KVM: arm64: nv: Fully update VNCR fixmap state in kvm_translate_vncr()
> KVM: arm64: nv: Inject SEA TTW when desc update can't write to GPA
> KVM: arm64: Restart instruction upon race in __kvm_at_s12()
> KVM: arm64: nv: Restart stage-1 walk if stage-2 desc update fails
>
> Sascha Bischoff (9):
> KVM: arm64: vgic-v5: Add missing trap handing for NV triage
> KVM: arm64: vgic-v5: Atomically assign bits to PPI DVI bitmap
> KVM: arm64: selftests: Add missing GIC CDEN to no-vgic-v5 selftest
> KVM: arm64: selftests: Cleanup unused vars in GICv5 PPI selftest
> KVM: arm64: selftests: Improve error handling for GICv5 PPI selftest
> Documentation: KVM: Fix typos in VGICv5 documentation
> Documentation: KVM: Clarify that PMU_V3_IRQ IntID requirements for GICv5
> irqchip/gic-v5: Immediately exec priority drop following activate
> KVM: arm64: Fix arch timer interrupts for GICv3-on-GICv5 guests
>
> Vincent Donnefort (4):
> KVM: arm64: Reset page order in pKVM hyp_pool
> KVM: arm64: Fix __pkvm_init_vm error path
> KVM: arm64: Add fail-safe for refcounted pages in __pkvm_hyp_donate_host
> KVM: arm64: Set a Linux errno on SMCCC error in kvm_call_hyp_nvhe()
>
> Wei-Lin Chang (5):
> KVM: arm64: nv: Rename vtcr_to_walk_info() to setup_s2_walk()
> KVM: arm64: Factor out TG0/1 decoding of VTCR and TCR
> KVM: arm64: nv: Use literal granule size in TLBI range calculation
> KVM: arm64: Fallback to a supported value for unsupported guest TGx
> KVM: arm64: Fix block mapping validity check in stage-1 walker
>
> Will Deacon (1):
> KVM: arm64: Don't populate TPIDR_EL2 in finalise_el2()
>
> Zenghui Yu (Huawei) (1):
> KVM: arm64: Remove @arch from __load_stage2()
>
> tabba@google.com (4):
> KVM: arm64: Flush HCR_EL2.VSE to deliver SErrors to pKVM guests
> KVM: arm64: Free hyp-share tracking node when share hypercall fails
> KVM: arm64: Avoid host/hyp share desync on unshare hypercall failure
> KVM: arm64: Roll back partial shares on kvm_share_hyp() failure
>
> Documentation/virt/kvm/devices/arm-vgic-v5.rst | 6 +-
> Documentation/virt/kvm/devices/vcpu.rst | 7 +-
> arch/arm64/include/asm/kvm_host.h | 8 +-
> arch/arm64/include/asm/kvm_hyp.h | 1 +
> arch/arm64/include/asm/kvm_mmu.h | 3 +-
> arch/arm64/kernel/cpufeature.c | 1 +
> arch/arm64/kernel/hyp-stub.S | 4 +-
> arch/arm64/kvm/arch_timer.c | 137 +++++++--------
> arch/arm64/kvm/arm.c | 41 +++--
> arch/arm64/kvm/at.c | 146 +++++++++++----
> arch/arm64/kvm/emulate-nested.c | 12 ++
> arch/arm64/kvm/fpsimd.c | 26 +++
> arch/arm64/kvm/hyp/include/hyp/switch.h | 2 +-
> arch/arm64/kvm/hyp/include/nvhe/mem_protect.h | 3 +-
> arch/arm64/kvm/hyp/nvhe/hyp-main.c | 21 ++-
> arch/arm64/kvm/hyp/nvhe/mem_protect.c | 37 ++--
> arch/arm64/kvm/hyp/nvhe/page_alloc.c | 21 ++-
> arch/arm64/kvm/hyp/nvhe/pkvm.c | 4 +-
> arch/arm64/kvm/hyp/nvhe/switch.c | 2 +-
> arch/arm64/kvm/hyp/nvhe/tlb.c | 4 +-
> arch/arm64/kvm/hyp/vgic-v5-sr.c | 82 ++-------
> arch/arm64/kvm/hyp/vhe/switch.c | 2 +-
> arch/arm64/kvm/hyp/vhe/tlb.c | 4 +-
> arch/arm64/kvm/mmu.c | 39 ++++-
> arch/arm64/kvm/nested.c | 234 ++++++++++++++++---------
> arch/arm64/kvm/pmu-emul.c | 31 +---
> arch/arm64/kvm/sys_regs.c | 20 +--
> arch/arm64/kvm/vgic/vgic-init.c | 45 ++---
> arch/arm64/kvm/vgic/vgic-irqfd.c | 6 +
> arch/arm64/kvm/vgic/vgic-its.c | 21 +--
> arch/arm64/kvm/vgic/vgic-kvm-device.c | 9 +-
> arch/arm64/kvm/vgic/vgic-v5.c | 51 ++----
> arch/arm64/kvm/vgic/vgic.c | 33 ++--
> arch/arm64/kvm/vgic/vgic.h | 3 +
> drivers/irqchip/irq-gic-v5.c | 13 +-
> include/kvm/arm_arch_timer.h | 7 +-
> include/kvm/arm_pmu.h | 5 +-
> include/kvm/arm_vgic.h | 19 +-
> tools/testing/selftests/kvm/arm64/no-vgic.c | 1 +
> tools/testing/selftests/kvm/arm64/vgic_v5.c | 10 +-
> 40 files changed, 651 insertions(+), 470 deletions(-)
>
^ permalink raw reply
* Re: [PATCH v2 07/16] usb: hub: Power on connected M.2 E-key connectors
From: Chen-Yu Tsai @ 2026-06-12 8:55 UTC (permalink / raw)
To: Bartosz Golaszewski
Cc: Alan Stern, linux-acpi, driver-core, linux-pm, linux-usb,
devicetree, linux-mediatek, linux-arm-kernel, linux-kernel,
Manivannan Sadhasivam, Greg Kroah-Hartman, Andy Shevchenko,
Daniel Scally, Heikki Krogerus, Sakari Ailus, Rafael J. Wysocki,
Danilo Krummrich, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Matthias Brugger, AngeloGioacchino Del Regno
In-Reply-To: <CAMRc=Mc3DqGb2MsvM4tjcqFuRraAO+EftO1UrtNFvR5dMRXmVA@mail.gmail.com>
On Thu, Jun 11, 2026 at 6:11 PM Bartosz Golaszewski <brgl@kernel.org> wrote:
>
> On Wed, 10 Jun 2026 10:40:41 +0200, Chen-Yu Tsai <wenst@chromium.org> said:
> > The new M.2 E-key connector can have a USB connection. For the USB device
> > on this connector to work, its power must be enabled and the W_DISABLE2#
> > signal deasserted. The connector driver handles this and provides a
> > toggle over the power sequencing API.
> >
> > This feature currently only supports a directly connected (no mux in
> > between) M.2 E-key connector. Existing USB connector types are not
> > covered. The USB A connector was recently added to the onboard devices
> > driver. USB B connectors have historically been managed by the USB
> > gadget or dual-role device controller drivers. USB C connectors are
> > handled by TCPM drivers.
> >
> > The power sequencing API does not know whether a power sequence provider
> > is not needed or not available yet, so we only request it for connectors
> > that we know need it, which at this time is just the E-key connector.
> >
> > On the USB side, the port firmware node (if present) is tied to the
> > usb_port device. This device is used to acquire the power sequencing
> > descriptor. This allows the provider to tell the different ports on one
> > hub apart.
> >
> > This feature is not implemented in the onboard USB devices driver. The
> > power sequencing API expects the consumer device to make the request,
> > but there is no device node to instantiate a platform device to tie
> > the driver to. The connector is not a child node of the USB host or
> > hub, and the graph connection is from a USB port to the connector.
> > And the connector itself already has a driver.
> >
> > Power sequencing is not directly enabled in the connector driver as
> > that would completely decouple the timing of it from the USB subsystem.
> > It would not be possible for the USB subsystem to toggle the power
> > for a power cycle or to disable the port.
> >
> > This change depends on another change to make the power sequencing
> > framework bool instead of tristate. The USB core and hub driver are
> > bool, so if the power sequencing framework is built as a module, the
> > kernel will fail to link.
> >
>
> That bit needs to go away I suppose?
Yeah, instead we need
config USB
depends on POWER_SEQUENCING && !POWER_SEQUENCING
But I ran into a dozen or so drivers that have "select USB", mostly
input devices:
config TOUCHSCREEN_USB_COMPOSITE
tristate "USB Touchscreen Driver"
depends on USB_ARCH_HAS_HCD
select USB
Kconfig complains about unmet dependencies.
> I see Andy has some suggestions but in general I like this approach much better
> than adding the pwrseq_get_index() function. Thanks!
Thanks!
ChenYu
^ permalink raw reply
* [PATCH] net: macb: add TX stall timeout callback to recover from lost TSTART write
From: Andrea della Porta @ 2026-06-12 9:01 UTC (permalink / raw)
To: netdev, Theo Lebrun, Andrea della Porta, Nicolas Ferre,
Claudiu Beznea, Andrew Lunn, David S . Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, linux-kernel, linux-arm-kernel,
linux-rpi-kernel
Cc: Lukasz Raczylo, Steffen Jaeckel
From: Lukasz Raczylo <lukasz@raczylo.com>
The MACB found in the Raspberry Pi RP1 suffers from sporadic stalls on
the TX queue.
While the exact root cause is not yet fully understood, it is likely
related to a hardware issue where a TSTART write to the NCR register
is missed, preventing the transmission from being kicked off.
Implement a timeout callback to handle TX queue stalls, triggering the
existing restart mechanism to recover.
Link: https://lore.kernel.org/all/20260514215459.36109-1-lukasz@raczylo.com/
Fixes: dc110d1b23564 ("net: cadence: macb: Add support for Raspberry Pi RP1 ethernet controller")
Signed-off-by: Lukasz Raczylo <lukasz@raczylo.com>
Co-developed-by: Steffen Jaeckel <sjaeckel@suse.de>
Signed-off-by: Steffen Jaeckel <sjaeckel@suse.de>
Co-developed-by: Andrea della Porta <andrea.porta@suse.com>
Signed-off-by: Andrea della Porta <andrea.porta@suse.com>
---
drivers/net/ethernet/cadence/macb_main.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c
index a12aa21244e83..615da65d5d68d 100644
--- a/drivers/net/ethernet/cadence/macb_main.c
+++ b/drivers/net/ethernet/cadence/macb_main.c
@@ -4522,6 +4522,16 @@ static int macb_setup_tc(struct net_device *dev, enum tc_setup_type type,
}
}
+static void macb_tx_timeout(struct net_device *dev, unsigned int q)
+{
+ struct macb *bp = netdev_priv(dev);
+
+ if (net_ratelimit())
+ netdev_err(dev, "TX stall detected, re-kicking TSTART\n");
+ dev->stats.tx_errors++;
+ macb_tx_restart(&bp->queues[q]);
+}
+
static const struct net_device_ops macb_netdev_ops = {
.ndo_open = macb_open,
.ndo_stop = macb_close,
@@ -4540,6 +4550,7 @@ static const struct net_device_ops macb_netdev_ops = {
.ndo_hwtstamp_set = macb_hwtstamp_set,
.ndo_hwtstamp_get = macb_hwtstamp_get,
.ndo_setup_tc = macb_setup_tc,
+ .ndo_tx_timeout = macb_tx_timeout,
};
/* Configure peripheral capabilities according to device tree
--
2.35.3
^ permalink raw reply related
* Re: [PATCH v2 08/16] Revert "dt-bindings: usb: mediatek,mtk-xhci: Add port for SuperSpeed EP"
From: Krzysztof Kozlowski @ 2026-06-12 8:59 UTC (permalink / raw)
To: Chen-Yu Tsai
Cc: Bartosz Golaszewski, Greg Kroah-Hartman, Andy Shevchenko,
Daniel Scally, Heikki Krogerus, Sakari Ailus, Rafael J. Wysocki,
Danilo Krummrich, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Matthias Brugger, AngeloGioacchino Del Regno, Alan Stern,
linux-acpi, driver-core, linux-pm, linux-usb, devicetree,
linux-mediatek, linux-arm-kernel, linux-kernel,
Manivannan Sadhasivam
In-Reply-To: <20260610084053.2059858-9-wenst@chromium.org>
On Wed, Jun 10, 2026 at 04:40:42PM +0800, Chen-Yu Tsai wrote:
> This reverts commit 454a1e3cd36c113341d7b71e8e691c6e47ab4a8a.
>
> mtk-xhci handles both USB 2.0 High Speed (HS) and USB 3.x SuperSpeed
> (SS) host connections. And there are USB 2.0 only mtk-xhci blocks.
> The SSUSB controller handles the device or gadget mode. Saying that
> SSUSB handles the HS portion is wrong.
>
> Fixes: 454a1e3cd36c ("dt-bindings: usb: mediatek,mtk-xhci: Add port for SuperSpeed EP")
> Cc: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
> Signed-off-by: Chen-Yu Tsai <wenst@chromium.org>
> ---
> Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.yaml | 4 ----
> 1 file changed, 4 deletions(-)
Please squash both commits. Reverting just for sake of revert is
pointless. We want wrong binding to be corrected, not to be reverted.
You revert something if there is nothing to fix afterwards, IOW.
Best regards,
Krzysztof
^ permalink raw reply
* Re: [PATCH net-next v7 0/2] Add Frame Preemption MAC Merge support for ICSSG
From: Simon Horman @ 2026-06-12 9:01 UTC (permalink / raw)
To: Meghana Malladi
Cc: elfring, haokexin, vadim.fedorenko, devnexen, jacob.e.keller,
arnd, basharath, afd, parvathi, vladimir.oltean, rogerq,
danishanwar, pabeni, kuba, edumazet, davem, andrew+netdev,
linux-arm-kernel, netdev, linux-kernel, srk, Vignesh Raghavendra
In-Reply-To: <20260610052511.781752-1-m-malladi@ti.com>
On Wed, Jun 10, 2026 at 10:55:09AM +0530, Meghana Malladi wrote:
> This patch series adds QoS support to the ICSSG PRUETH driver.
> The first patch implements mqprio qdisc handling and TC offload hooks
> so userspace can request TC mappings and queue counts.
>
> It also integrates a driver-side mechanism to program the firmware
> with the IET/FPE preemption mask and to kick the firmware verify state
> machine when frame preemption is enabled. The second patch adds ethtool
> perations for the MAC Merge (Frame Preemption) sublayer, exposing .get_mm,
> .set_mm and .get_mm_stats so admins can view and change MAC Merge
> parameters and retrieve preemption statistics.
>
> v6: https://lore.kernel.org/all/20260525182700.3135858-1-m-malladi@ti.com/
>
> MD Danish Anwar (2):
> net: ti: icssg-prueth: Add Frame Preemption MAC Merge support
> net: ti: icssg-prueth: Add ethtool ops for Frame Preemption MAC Merge
Hi Meghana and MD,
There is AI-generated review of this patch-set available on both
https://sashiko.dev and https://netdev-ai.bots.linux.dev/sashiko/
I would appreciate it if you could look over that with a view
to addressing any issues that directly affect this patch-set.
...
^ permalink raw reply
* Re: [PATCH v2 10/16] power: sequencing: pcie-m2: support matching on remote "port" node
From: Chen-Yu Tsai @ 2026-06-12 9:12 UTC (permalink / raw)
To: Andy Shevchenko
Cc: Bartosz Golaszewski, Greg Kroah-Hartman, Daniel Scally,
Heikki Krogerus, Sakari Ailus, Rafael J. Wysocki,
Danilo Krummrich, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Matthias Brugger, AngeloGioacchino Del Regno, Alan Stern,
linux-acpi, driver-core, linux-pm, linux-usb, devicetree,
linux-mediatek, linux-arm-kernel, linux-kernel,
Manivannan Sadhasivam
In-Reply-To: <ail1sAxgh5Xtkj2y@ashevche-desk.local>
On Wed, Jun 10, 2026 at 11:33 PM Andy Shevchenko
<andriy.shevchenko@linux.intel.com> wrote:
>
> On Wed, Jun 10, 2026 at 04:40:44PM +0800, Chen-Yu Tsai wrote:
> > A USB hub can have multiple ports, and this driver needs to
> > differentiate which port is being matched to. The USB hub driver now
> > associates the "port" node with the usb_port device, so here we can
> > use the remote "port" node to check for a match. Then fall back to
> > the remote device node for the other connection types.
>
> ...
>
> > + if (remote_port && remote_port == dev_of_node(dev))
> > + return PWRSEQ_MATCH_OK;
> > if (remote && (remote == dev_of_node(dev)))
> > return PWRSEQ_MATCH_OK;
>
> We have device_match_of_node() IIRC the name of that API.
Ack. Will also replace the existing instance.
^ permalink raw reply
* Re: [PATCH net-next v2] net: airoha: Add TCP LRO support
From: Lorenzo Bianconi @ 2026-06-12 9:15 UTC (permalink / raw)
To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni
Cc: Alexander Lobakin, linux-arm-kernel, linux-mediatek, netdev,
Madhur Agrawal
In-Reply-To: <20260610-airoha-eth-lro-v2-1-54be99b9a2d5@kernel.org>
[-- Attachment #1: Type: text/plain, Size: 13242 bytes --]
> Add hardware TCP Large Receive Offload (LRO) support to the airoha_eth
> driver, leveraging the EN7581/AN7583 SoC's 8 dedicated LRO hardware queues
> mapped to RX queues 24–31. LRO hw offloading does not support
> Scatter-Gather (SG) so it is required to increase the page_pool allocation
> order to 2 for RX queues 24–31 (LRO queues).
> Since HW LRO is configured per-QDMA and shared across all devices using
> it, LRO is mutually exclusive with multiple active devices on the same
> QDMA block. Call netdev_update_features() on sibling devices in
> ndo_open/ndo_stop so that NETIF_F_LRO availability is re-evaluated when
> the QDMA user count changes.
commenting on sashiko's report:
https://sashiko.dev/#/patchset/20260610-airoha-eth-lro-v2-1-54be99b9a2d5%40kernel.org
>
[...]
> +static int airoha_qdma_lro_rx_process(struct sk_buff *skb,
> + struct airoha_qdma_desc *desc)
> +{
> + u32 desc_ctrl = le32_to_cpu(READ_ONCE(desc->ctrl));
> + u32 len, th_off, tcp_ack_seq, agg_count, data_off;
> + struct skb_shared_info *shinfo = skb_shinfo(skb);
> + u32 msg1 = le32_to_cpu(READ_ONCE(desc->msg1));
> + u32 msg2 = le32_to_cpu(READ_ONCE(desc->msg2));
> + u32 msg3 = le32_to_cpu(READ_ONCE(desc->msg3));
> + u16 tcp_win, l2_len;
> + struct tcphdr *th;
> + bool ipv4, ipv6;
> +
> + agg_count = FIELD_GET(QDMA_ETH_RXMSG_AGG_COUNT_MASK, msg2);
> + if (agg_count <= 1)
> + return 0;
> +
> + ipv4 = FIELD_GET(QDMA_ETH_RXMSG_IP4_MASK, msg1);
> + ipv6 = FIELD_GET(QDMA_ETH_RXMSG_IP6_MASK, msg1);
> + if (!ipv4 && !ipv6)
> + return -EOPNOTSUPP;
> +
> + l2_len = FIELD_GET(QDMA_ETH_RXMSG_L2_LEN_MASK, msg2);
> + len = FIELD_GET(QDMA_DESC_LEN_MASK, desc_ctrl);
> + if (ipv4) {
> + struct iphdr *iph, _iph;
> +
> + iph = skb_header_pointer(skb, l2_len, sizeof(*iph), &_iph);
> + if (!iph)
> + return -EINVAL;
> +
> + if (iph->protocol != IPPROTO_TCP)
> + return -EOPNOTSUPP;
> +
> + if (iph->ihl < 5)
> + return -EINVAL;
> +
> + th_off = l2_len + (iph->ihl << 2);
> + if (!pskb_may_pull(skb, th_off))
> + return -EINVAL;
> +
> + iph = (struct iphdr *)(skb->data + l2_len);
> + iph->tot_len = cpu_to_be16(len - l2_len);
> + iph->check = 0;
> + iph->check = ip_fast_csum((void *)iph, iph->ihl);
> + } else {
> + struct ipv6hdr *ip6h;
> +
> + th_off = l2_len + sizeof(*ip6h);
> + if (!pskb_may_pull(skb, th_off))
> + return -EINVAL;
> +
> + ip6h = (struct ipv6hdr *)(skb->data + l2_len);
> + if (ip6h->nexthdr != NEXTHDR_TCP)
> + return -EOPNOTSUPP;
> +
> + ip6h->payload_len = cpu_to_be16(len - th_off);
> + }
> +
> + tcp_win = FIELD_GET(QDMA_ETH_RXMSG_TCP_WIN_MASK, msg3);
> + tcp_ack_seq = le32_to_cpu(READ_ONCE(desc->data));
> +
> + if (!pskb_may_pull(skb, th_off + sizeof(*th)))
> + return -EINVAL;
> +
> + th = (struct tcphdr *)(skb->data + th_off);
- Does this code validate that the TCP header length is at least 5?
- ack, I will add it in the next revision.
> + data_off = th_off + (th->doff << 2);
> + if (len <= data_off)
> + return -EINVAL;
> +
> + th->ack_seq = cpu_to_be32(tcp_ack_seq);
> + th->window = cpu_to_be16(tcp_win);
> +
> + /* Check tcp timestamp option */
> + if (th->doff == (sizeof(*th) + TCPOLEN_TSTAMP_ALIGNED) / 4) {
> + u32 topt;
> +
> + if (!pskb_may_pull(skb, data_off))
> + return -EINVAL;
> +
> + th = (struct tcphdr *)(skb->data + th_off);
> + topt = get_unaligned_be32(th + 1);
> + if (topt == ((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) |
> + (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP)) {
> + u8 *ptr = (u8 *)th + sizeof(*th) + 2 * sizeof(__be32);
> + __le32 tcp_ts_reply = READ_ONCE(desc->tcp_ts_reply);
> +
> + put_unaligned_be32(le32_to_cpu(tcp_ts_reply), ptr);
> + }
> + }
> +
> + shinfo->gso_type = ipv4 ? SKB_GSO_TCPV4 : SKB_GSO_TCPV6;
> + shinfo->gso_size = (len - data_off) / agg_count;
> + shinfo->gso_segs = agg_count;
- Could this gso_size calculation corrupt TCP sequence numbers during
forwarding?
- The TSO in the egress NIC will perform segmentation when the device is
routing the LRO packet to the destination so the TCP sequence numbers
will be recalculated. I agree gso_size is just an estimation of the real
MSS on the first n-1 packets and we can have a suboptimal MSS size on
egress segmented traffic, but the hw does not provide this info.
- Does this LRO processing need to initialize CHECKSUM_PARTIAL metadata?
- ack, I will work on it
> +
> + return 0;
> +}
> +
> static int airoha_qdma_rx_process(struct airoha_queue *q, int budget)
> {
> enum dma_data_direction dir = page_pool_get_dma_dir(q->page_pool);
[...]
>
> +static void airoha_update_netdev_features(struct airoha_gdm_dev *dev)
> +{
> + struct airoha_eth *eth = dev->eth;
> + int i, j;
> +
> + for (i = 0; i < ARRAY_SIZE(eth->ports); i++) {
> + struct airoha_gdm_port *port = eth->ports[i];
> +
> + if (!port)
> + continue;
> +
> + for (j = 0; j < ARRAY_SIZE(port->devs); j++) {
> + struct airoha_gdm_dev *iter_dev = port->devs[j];
> + struct net_device *netdev;
> +
> + if (!iter_dev || iter_dev == dev)
> + continue;
> +
> + if (iter_dev->qdma != dev->qdma)
> + continue;
> +
> + netdev = netdev_from_priv(iter_dev);
> + if (netdev->reg_state != NETREG_REGISTERED)
> + continue;
> +
> + netdev_update_features(netdev);
> + }
> + }
> +}
> +
> static int airoha_dev_open(struct net_device *netdev)
> {
> int err, len = ETH_HLEN + netdev->mtu + ETH_FCS_LEN;
> @@ -1778,6 +1970,18 @@ static int airoha_dev_open(struct net_device *netdev)
> struct airoha_gdm_port *port = dev->port;
> u32 cur_len, pse_port = FE_PSE_PORT_PPE1;
> struct airoha_qdma *qdma = dev->qdma;
> + int qdma_id = qdma - &qdma->eth->qdma[0];
> +
> + /* HW LRO is configured on the QDMA and it is shared between
> + * all the devices using it. Refuse to open a second device on
> + * the same QDMA if LRO is enabled on any device sharing it.
> + */
> + if (atomic_read(&qdma->users) &&
> + airoha_fe_lro_is_enabled(qdma->eth, qdma_id)) {
> + netdev_warn(netdev, "required to disable LRO on QDMA%d\n",
> + qdma_id);
> + return -EBUSY;
> + }
- Can a sibling interface that is DOWN bypass this LRO mutual exclusion check?
- AFAIU the kernel does not run the ndo_set_features() when the device is
down, just set the requested feature. When we bring up eth1, ndo_open()
callback will return an error.
Regards,
Lorenzo
>
> netif_tx_start_all_queues(netdev);
> err = airoha_set_vip_for_gdm_port(dev, true);
> @@ -1817,6 +2021,8 @@ static int airoha_dev_open(struct net_device *netdev)
> airoha_set_gdm_port_fwd_cfg(qdma->eth, REG_GDM_FWD_CFG(port->id),
> pse_port);
>
> + airoha_update_netdev_features(dev);
> +
> return 0;
> }
>
> @@ -1876,6 +2082,8 @@ static int airoha_dev_stop(struct net_device *netdev)
> }
> }
>
> + airoha_update_netdev_features(dev);
> +
> return 0;
> }
>
> @@ -2154,6 +2362,56 @@ int airoha_get_fe_port(struct airoha_gdm_dev *dev)
> }
> }
>
> +static netdev_features_t airoha_dev_fix_features(struct net_device *netdev,
> + netdev_features_t features)
> +{
> + struct airoha_gdm_dev *dev = netdev_priv(netdev);
> + struct airoha_qdma *qdma = dev->qdma;
> +
> + if (atomic_read(&qdma->users) > 1)
> + features &= ~NETIF_F_LRO;
> +
> + return features;
> +}
> +
> +static int airoha_dev_set_features(struct net_device *netdev,
> + netdev_features_t features)
> +{
> + netdev_features_t diff = netdev->features ^ features;
> + struct airoha_gdm_dev *dev = netdev_priv(netdev);
> + struct airoha_qdma *qdma = dev->qdma;
> + struct airoha_eth *eth = qdma->eth;
> + int qdma_id = qdma - ð->qdma[0];
> +
> + if (!(diff & NETIF_F_LRO))
> + return 0;
> +
> + if (features & NETIF_F_LRO) {
> + int i, lro_queue_index = 0;
> +
> + for (i = 0; i < ARRAY_SIZE(qdma->q_rx); i++) {
> + struct airoha_queue *q = &qdma->q_rx[i];
> + u32 size;
> +
> + if (!q->ndesc)
> + continue;
> +
> + if (!airoha_qdma_is_lro_queue(q))
> + continue;
> +
> + size = SKB_WITH_OVERHEAD(AIROHA_RX_LEN(q->buf_size));
> + size = min_t(u32, size, CDM_LRO_AGG_SIZE_MASK);
> + airoha_fe_lro_init_rx_queue(eth, qdma_id,
> + lro_queue_index, i, size);
> + lro_queue_index++;
> + }
> + } else {
> + airoha_fe_lro_disable(eth, qdma_id);
> + }
> +
> + return 0;
> +}
> +
> static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb,
> struct net_device *netdev)
> {
> @@ -3082,6 +3340,8 @@ static const struct net_device_ops airoha_netdev_ops = {
> .ndo_stop = airoha_dev_stop,
> .ndo_change_mtu = airoha_dev_change_mtu,
> .ndo_select_queue = airoha_dev_select_queue,
> + .ndo_fix_features = airoha_dev_fix_features,
> + .ndo_set_features = airoha_dev_set_features,
> .ndo_start_xmit = airoha_dev_xmit,
> .ndo_get_stats64 = airoha_dev_get_stats64,
> .ndo_set_mac_address = airoha_dev_set_macaddr,
> @@ -3169,11 +3429,9 @@ static int airoha_alloc_gdm_device(struct airoha_eth *eth,
> netdev->ethtool_ops = &airoha_ethtool_ops;
> netdev->max_mtu = AIROHA_MAX_MTU;
> netdev->watchdog_timeo = 5 * HZ;
> - netdev->hw_features = NETIF_F_IP_CSUM | NETIF_F_RXCSUM | NETIF_F_TSO6 |
> - NETIF_F_IPV6_CSUM | NETIF_F_SG | NETIF_F_TSO |
> - NETIF_F_HW_TC;
> - netdev->features |= netdev->hw_features;
> - netdev->vlan_features = netdev->hw_features;
> + netdev->hw_features = AIROHA_HW_FEATURES | NETIF_F_LRO;
> + netdev->features |= AIROHA_HW_FEATURES;
> + netdev->vlan_features = AIROHA_HW_FEATURES;
> SET_NETDEV_DEV(netdev, eth->dev);
>
> /* reserve hw queues for HTB offloading */
> diff --git a/drivers/net/ethernet/airoha/airoha_eth.h b/drivers/net/ethernet/airoha/airoha_eth.h
> index 8f42973f9cf5..e78ef751f244 100644
> --- a/drivers/net/ethernet/airoha/airoha_eth.h
> +++ b/drivers/net/ethernet/airoha/airoha_eth.h
> @@ -44,6 +44,18 @@
> (_n) == 15 ? 128 : \
> (_n) == 0 ? 1024 : 16)
>
> +#define AIROHA_LRO_PAGE_ORDER order_base_2(SZ_16K / PAGE_SIZE)
> +#define AIROHA_MAX_NUM_LRO_QUEUES 8
> +#define AIROHA_RXQ_LRO_EN_MASK GENMASK(31, 24)
> +#define AIROHA_RXQ_LRO_MAX_AGG_COUNT 64
> +#define AIROHA_RXQ_LRO_MAX_AGG_TIME 100
> +#define AIROHA_RXQ_LRO_MAX_AGE_TIME 2000
> +
> +#define AIROHA_HW_FEATURES \
> + (NETIF_F_IP_CSUM | NETIF_F_RXCSUM | \
> + NETIF_F_TSO6 | NETIF_F_IPV6_CSUM | \
> + NETIF_F_SG | NETIF_F_TSO | NETIF_F_HW_TC)
> +
> #define PSE_RSV_PAGES 128
> #define PSE_QUEUE_RSV_PAGES 64
>
> @@ -672,6 +684,18 @@ static inline bool airoha_is_7583(struct airoha_eth *eth)
> return eth->soc->version == 0x7583;
> }
>
> +static inline bool airoha_qdma_is_lro_queue(struct airoha_queue *q)
> +{
> + struct airoha_qdma *qdma = q->qdma;
> + int qid = q - &qdma->q_rx[0];
> +
> + /* EN7581 SoC supports at most 8 LRO rx queues */
> + BUILD_BUG_ON(hweight32(AIROHA_RXQ_LRO_EN_MASK) >
> + AIROHA_MAX_NUM_LRO_QUEUES);
> +
> + return !!(AIROHA_RXQ_LRO_EN_MASK & BIT(qid));
> +}
> +
> int airoha_get_fe_port(struct airoha_gdm_dev *dev);
> bool airoha_is_valid_gdm_dev(struct airoha_eth *eth,
> struct airoha_gdm_dev *dev);
> diff --git a/drivers/net/ethernet/airoha/airoha_regs.h b/drivers/net/ethernet/airoha/airoha_regs.h
> index 436f3c8779c1..dfc786583774 100644
> --- a/drivers/net/ethernet/airoha/airoha_regs.h
> +++ b/drivers/net/ethernet/airoha/airoha_regs.h
> @@ -122,6 +122,20 @@
> #define CDM_CRSN_QSEL_REASON_MASK(_n) \
> GENMASK(4 + (((_n) % 4) << 3), (((_n) % 4) << 3))
>
> +#define REG_CDM_LRO_RXQ(_n, _m) (CDM_BASE(_n) + 0x78 + ((_m) & 0x4))
> +#define LRO_RXQ_MASK(_n) GENMASK(4 + (((_n) & 0x3) << 3), ((_n) & 0x3) << 3)
> +
> +#define REG_CDM_LRO_EN(_n) (CDM_BASE(_n) + 0x80)
> +#define LRO_RXQ_EN_MASK GENMASK(7, 0)
> +
> +#define REG_CDM_LRO_LIMIT(_n) (CDM_BASE(_n) + 0x84)
> +#define CDM_LRO_AGG_NUM_MASK GENMASK(23, 16)
> +#define CDM_LRO_AGG_SIZE_MASK GENMASK(15, 0)
> +
> +#define REG_CDM_LRO_AGE_TIME(_n) (CDM_BASE(_n) + 0x88)
> +#define CDM_LRO_AGE_TIME_MASK GENMASK(31, 16)
> +#define CDM_LRO_AGG_TIME_MASK GENMASK(15, 0)
> +
> #define REG_GDM_FWD_CFG(_n) GDM_BASE(_n)
> #define GDM_PAD_EN_MASK BIT(28)
> #define GDM_DROP_CRC_ERR_MASK BIT(23)
> @@ -883,9 +897,15 @@
> #define QDMA_ETH_RXMSG_SPORT_MASK GENMASK(25, 21)
> #define QDMA_ETH_RXMSG_CRSN_MASK GENMASK(20, 16)
> #define QDMA_ETH_RXMSG_PPE_ENTRY_MASK GENMASK(15, 0)
> +/* RX MSG2 */
> +#define QDMA_ETH_RXMSG_AGG_COUNT_MASK GENMASK(31, 24)
> +#define QDMA_ETH_RXMSG_L2_LEN_MASK GENMASK(6, 0)
> +/* RX MSG3 */
> +#define QDMA_ETH_RXMSG_AGG_LEN_MASK GENMASK(31, 16)
> +#define QDMA_ETH_RXMSG_TCP_WIN_MASK GENMASK(15, 0)
>
> struct airoha_qdma_desc {
> - __le32 rsv;
> + __le32 tcp_ts_reply;
> __le32 ctrl;
> __le32 addr;
> __le32 data;
>
> ---
> base-commit: 660a9e399ab02c0cb86d277ed6b0c9d10c350fdd
> change-id: 20260520-airoha-eth-lro-a5d1c3631811
>
> Best regards,
> --
> Lorenzo Bianconi <lorenzo@kernel.org>
>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply
* Re: [PATCH v2 11/16] power: sequencing: pcie-m2: Add usb and sdio targets for E-key connector
From: Chen-Yu Tsai @ 2026-06-12 9:17 UTC (permalink / raw)
To: Andy Shevchenko
Cc: Bartosz Golaszewski, Greg Kroah-Hartman, Daniel Scally,
Heikki Krogerus, Sakari Ailus, Rafael J. Wysocki,
Danilo Krummrich, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Matthias Brugger, AngeloGioacchino Del Regno, Alan Stern,
linux-acpi, driver-core, linux-pm, linux-usb, devicetree,
linux-mediatek, linux-arm-kernel, linux-kernel,
Manivannan Sadhasivam
In-Reply-To: <ail2VcubjT7HNGUC@ashevche-desk.local>
On Wed, Jun 10, 2026 at 11:36 PM Andy Shevchenko
<andriy.shevchenko@linux.intel.com> wrote:
>
> On Wed, Jun 10, 2026 at 04:40:45PM +0800, Chen-Yu Tsai wrote:
> > The M.2 E-key connector allows either PCIe or SDIO for WiFi and USB or
> > UART for BT. Currently the driver only supports PCIe and UART.
> >
> > Add power sequencing targets for SDIO and USB. To avoid adding a
> > complicated dependency tree, rename the existing power sequencing units
> > "pcie" and "uart" to "wifi" and "bt". The existing target names are left
> > untouched. The new "sdio" and "usb" targets just point to the renamed
> > "wifi" and "bt" units.
>
> Why can we do that? No breakage? Only internal names? No ABI affected?
> Please, clarify all this in the commit message.
Will do.
In short, the target names (which are not modified) are used by the
consumer, while the unit names are internal only.
ChenYu
^ permalink raw reply
* Re: [PATCH bpf-next v2 8/8] selftests/bpf: add tests to validate KASAN on JIT programs
From: Alexis Lothoré @ 2026-06-12 9:19 UTC (permalink / raw)
To: bot+bpf-ci, alexis.lothore, ast, daniel, andrii, martin.lau,
eddyz87, memxor, song, yonghong.song, jolsa, john.fastabend, tglx,
mingo, bp, dave.hansen, x86, hpa, shuah, mcoquelin.stm32,
alexandre.torgue, ihor.solodrai
Cc: ebpf, bastien.curutchet, thomas.petazzoni, bpf, linux-kernel,
linux-kselftest, linux-stm32, linux-arm-kernel, martin.lau, clm
In-Reply-To: <8642178be3be8efc7f19ac4a9aa37e699f2baa82cab200909b99997068c6ae7b@mail.kernel.org>
On Thu Jun 4, 2026 at 11:45 PM CEST, bot+bpf-ci wrote:
[...]
> The Sashiko AI review on the RFC v1 8/8 posting raised a concern here that
> does not seem to have been addressed in v2:
>
> https://lore.kernel.org/bpf/20260425065049.BEC63C2BCB0@smtp.kernel.org
>
> The original question was:
>
> KASAN operates in single-shot mode by default. After the first subtest
> triggers a report, will subsequent reports be suppressed, causing the
> remaining subtests to fail? Also, since BPF CI runs with panic_on_warn=1,
> will the first KASAN splat invoke check_panic_on_warn() and immediately
> panic the CI runner?
>
> KASAN runs in single-shot mode by default. mm/kasan/report.c suppresses
> reports after the first one unless kasan_multi_shot is set.
>
> This loop runs roughly 50 subtests, and each one expects a fresh KASAN
> report emitted via the JIT-inserted __asan_load/__asan_store calls that go
> through kasan_report().
>
> Under default single-shot KASAN, would the subtests after the first one see
> no report and fail the positive assertions?
>
> Separately, BPF CI runs with panic_on_warn=1 (config.ppc64el still sets
> panic_on_warn=1). Would the first KASAN splat reach check_panic_on_warn()
> and panic the runner?
>
> Nothing in v2 appears to enable kasan_multi_shot or guard against
> panic_on_warn. Was this intended to be handled somewhere?
Hoping to silence this one on the next revision: CI has been updated
separately to enable kasan_multi_shot, and so all subtests in v2
properly triggered the reports individually. The commit is lacking
documentation about this need though.
--
Alexis Lothoré, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply
* Re: [PATCH v2 1/2] soc: aspeed: add BMC-side PCIe BMC device driver
From: Grégoire Layet @ 2026-06-12 9:21 UTC (permalink / raw)
To: Andrew Jeffery
Cc: joel, andrew, jacky_chou, yh_chung, ninad, linux-aspeed,
linux-arm-kernel, linux-kernel, anirudhsriniv
In-Reply-To: <CAFi2wKYzUDY5Gis9GaHdqeYdv-orHB+gWfLXkJBgbxfbnRgorA@mail.gmail.com>
Hello Andrew,
Anirudh Srinivasan and I have found that IPMI over KCS using the
PCI worked with the stock ASPEED bmc driver (the bmc driver in the V1)
but not with the trimmed-down version in the V2. I have apparently removed
a bit too much from the V2 , but that's not what I want to focus on.
This brings back the question of where we should put the registers
configuration,
considering that two different functionalities depend on it.
> It is also possible to put the SCU initialisation on the
> 8250_aspeed_vuart driver
> directly. This could be activated with a specific flag added to VUART nodes
> ('pcie2vuart' for example) on the DeviceTree.
Similarly to this idea, we could include have the necessary configuration in the
'kcs_bmc_aspeed' driver. This could be activated using a similar flag
,such as 'pci2lpc'
or 'pci2kcs' directly. However, this would result in a lot of code
duplication for most
of the configuration.
The issue for me is that, two drivers configuring the same registers
is not a good idea.
I don't know how to do this the proper way.
I wanted to add this information because it could influence the move to a
bmc_device driver that configures both VUART and KCS, over PCI.
This would be similar to the V2 bmc driver, and I fix the KCS bug.
Thanks,
Grégoire
^ permalink raw reply
* [PATCH v2 3/3] drivers/perf: hisi: Add new function for HiSilicon MN PMU driver
From: Yushan Wang @ 2026-06-12 9:32 UTC (permalink / raw)
To: will, mark.rutland, robin.murphy, linux-arm-kernel, linux-kernel
Cc: fanghao11, linuxarm, liuyonglong, prime.zeng, wangzhou1,
wangyushan12
In-Reply-To: <20260612093207.1242000-1-wangyushan12@huawei.com>
From: Yifan Wu <wuyifan50@huawei.com>
MN (Miscellaneous Node) is a hybrid node in ARM CHI. The MN PMU driver
using the HiSilicon uncore PMU framework.
On HiSilicon HIP13 platform, cycle event is supported on MN PMU. The
cycle event is exposed directly in driver and some variables shall be
added suffix to distinguish the version.
Signed-off-by: Yifan Wu <wuyifan50@huawei.com>
Signed-off-by: Yushan Wang <wangyushan12@huawei.com>
---
drivers/perf/hisilicon/hisi_uncore_mn_pmu.c | 61 +++++++++++++++++++--
1 file changed, 55 insertions(+), 6 deletions(-)
diff --git a/drivers/perf/hisilicon/hisi_uncore_mn_pmu.c b/drivers/perf/hisilicon/hisi_uncore_mn_pmu.c
index 4df4eebe243e..cdd5a1591408 100644
--- a/drivers/perf/hisilicon/hisi_uncore_mn_pmu.c
+++ b/drivers/perf/hisilicon/hisi_uncore_mn_pmu.c
@@ -192,7 +192,7 @@ static const struct attribute_group hisi_mn_pmu_format_group = {
.attrs = hisi_mn_pmu_format_attr,
};
-static struct attribute *hisi_mn_pmu_events_attr[] = {
+static struct attribute *hisi_mn_pmu_events_attr_v1[] = {
HISI_PMU_EVENT_ATTR(req_eobarrier_num, 0x00),
HISI_PMU_EVENT_ATTR(req_ecbarrier_num, 0x01),
HISI_PMU_EVENT_ATTR(req_dvmop_num, 0x02),
@@ -219,14 +219,55 @@ static struct attribute *hisi_mn_pmu_events_attr[] = {
NULL
};
-static const struct attribute_group hisi_mn_pmu_events_group = {
+static const struct attribute_group hisi_mn_pmu_events_group_v1 = {
.name = "events",
- .attrs = hisi_mn_pmu_events_attr,
+ .attrs = hisi_mn_pmu_events_attr_v1,
};
-static const struct attribute_group *hisi_mn_pmu_attr_groups[] = {
+static const struct attribute_group *hisi_mn_pmu_attr_groups_v1[] = {
&hisi_mn_pmu_format_group,
- &hisi_mn_pmu_events_group,
+ &hisi_mn_pmu_events_group_v1,
+ &hisi_pmu_cpumask_attr_group,
+ &hisi_pmu_identifier_group,
+ NULL
+};
+
+static struct attribute *hisi_mn_pmu_events_attr_v2[] = {
+ HISI_PMU_EVENT_ATTR(req_eobarrier_num, 0x00),
+ HISI_PMU_EVENT_ATTR(req_ecbarrier_num, 0x01),
+ HISI_PMU_EVENT_ATTR(req_dvmop_num, 0x02),
+ HISI_PMU_EVENT_ATTR(req_dvmsync_num, 0x03),
+ HISI_PMU_EVENT_ATTR(req_retry_num, 0x04),
+ HISI_PMU_EVENT_ATTR(req_writenosnp_num, 0x05),
+ HISI_PMU_EVENT_ATTR(req_readnosnp_num, 0x06),
+ HISI_PMU_EVENT_ATTR(snp_dvm_num, 0x07),
+ HISI_PMU_EVENT_ATTR(snp_dvmsync_num, 0x08),
+ HISI_PMU_EVENT_ATTR(l3t_req_dvm_num, 0x09),
+ HISI_PMU_EVENT_ATTR(l3t_req_dvmsync_num, 0x0A),
+ HISI_PMU_EVENT_ATTR(mn_req_dvm_num, 0x0B),
+ HISI_PMU_EVENT_ATTR(mn_req_dvmsync_num, 0x0C),
+ HISI_PMU_EVENT_ATTR(pa_req_dvm_num, 0x0D),
+ HISI_PMU_EVENT_ATTR(pa_req_dvmsync_num, 0x0E),
+ HISI_PMU_EVENT_ATTR(cycles, 0x0F),
+ HISI_PMU_EVENT_ATTR(snp_dvm_latency, 0x80),
+ HISI_PMU_EVENT_ATTR(snp_dvmsync_latency, 0x81),
+ HISI_PMU_EVENT_ATTR(l3t_req_dvm_latency, 0x82),
+ HISI_PMU_EVENT_ATTR(l3t_req_dvmsync_latency, 0x83),
+ HISI_PMU_EVENT_ATTR(mn_req_dvm_latency, 0x84),
+ HISI_PMU_EVENT_ATTR(mn_req_dvmsync_latency, 0x85),
+ HISI_PMU_EVENT_ATTR(pa_req_dvm_latency, 0x86),
+ HISI_PMU_EVENT_ATTR(pa_req_dvmsync_latency, 0x87),
+ NULL
+};
+
+static const struct attribute_group hisi_mn_pmu_events_group_v2 = {
+ .name = "events",
+ .attrs = hisi_mn_pmu_events_attr_v2,
+};
+
+static const struct attribute_group *hisi_mn_pmu_attr_groups_v2[] = {
+ &hisi_mn_pmu_format_group,
+ &hisi_mn_pmu_events_group_v2,
&hisi_pmu_cpumask_attr_group,
&hisi_pmu_identifier_group,
NULL
@@ -351,7 +392,14 @@ static struct hisi_mn_pmu_regs hisi_mn_v1_pmu_regs = {
};
static const struct hisi_pmu_dev_info hisi_mn_v1 = {
- .attr_groups = hisi_mn_pmu_attr_groups,
+ .attr_groups = hisi_mn_pmu_attr_groups_v1,
+ .counter_bits = 48,
+ .check_event = HISI_MN_EVTYPE_MASK,
+ .private = &hisi_mn_v1_pmu_regs,
+};
+
+static const struct hisi_pmu_dev_info hisi_mn_v2 = {
+ .attr_groups = hisi_mn_pmu_attr_groups_v2,
.counter_bits = 48,
.check_event = HISI_MN_EVTYPE_MASK,
.private = &hisi_mn_v1_pmu_regs,
@@ -359,6 +407,7 @@ static const struct hisi_pmu_dev_info hisi_mn_v1 = {
static const struct acpi_device_id hisi_mn_pmu_acpi_match[] = {
{ "HISI0222", (kernel_ulong_t) &hisi_mn_v1 },
+ { "HISI0224", (kernel_ulong_t) &hisi_mn_v2 },
{ }
};
MODULE_DEVICE_TABLE(acpi, hisi_mn_pmu_acpi_match);
--
2.33.0
^ permalink raw reply related
* [PATCH v2 2/3] drivers/perf: hisi: Support uncore ITS PMU
From: Yushan Wang @ 2026-06-12 9:32 UTC (permalink / raw)
To: will, mark.rutland, robin.murphy, linux-arm-kernel, linux-kernel
Cc: fanghao11, linuxarm, liuyonglong, prime.zeng, wangzhou1,
wangyushan12
In-Reply-To: <20260612093207.1242000-1-wangyushan12@huawei.com>
Support uncore ITS PMU, which provides the capability of counting
the number of interrupts routed to ITS by interrupt catagories, and the
latency. It also supports collecting statistics of micro-ops of ITS.
The driver adapts to HiSilicon uncore PMU framework. It does not support
overflow interruption, which is the same as NoC PMU, so a few dummy
functions or handling interrupts are left empty.
Signed-off-by: Yushan Wang <wangyushan12@huawei.com>
---
Documentation/admin-guide/perf/hisi-pmu.rst | 12 +
drivers/perf/hisilicon/Makefile | 2 +-
drivers/perf/hisilicon/hisi_uncore_its_pmu.c | 375 +++++++++++++++++++
3 files changed, 388 insertions(+), 1 deletion(-)
create mode 100644 drivers/perf/hisilicon/hisi_uncore_its_pmu.c
diff --git a/Documentation/admin-guide/perf/hisi-pmu.rst b/Documentation/admin-guide/perf/hisi-pmu.rst
index d56b2d690709..b2b79be998f9 100644
--- a/Documentation/admin-guide/perf/hisi-pmu.rst
+++ b/Documentation/admin-guide/perf/hisi-pmu.rst
@@ -128,6 +128,18 @@ channel with this option. The current supported channels are as follows:
7. tt_en: NoC PMU supports counting only transactions that have tracetag set
if this option is set. See the 2nd list for more information about tracetag.
+8. int_id: ITS PMU supports filtering by interrupt id, which is defined by
+hardware. Interrupt id takes up to 32 bits, and can be divided into 2 parts:
+
+- Upper 16 bits: DeviceID if counting LPI, PEID if counting SGI/PPI.
+- Lower 16 bits: EventID if counting LPI, IntID if counting SGI/PPI.
+
+int_id is a global configuration for each PMU instance, if multiple different
+int_id's are specified, the last came in will be effective.
+
+9. int_en: A one-bit flag to tell if int_id is used to filter the statistics. It
+allows filtering 0 DeviceID and EventID.
+
For HiSilicon uncore PMU v3 whose identifier is 0x40, some uncore PMUs are
further divided into parts for finer granularity of tracing, each part has its
own dedicated PMU, and all such PMUs together cover the monitoring job of events
diff --git a/drivers/perf/hisilicon/Makefile b/drivers/perf/hisilicon/Makefile
index 186be3d02238..5f28cfdb8a72 100644
--- a/drivers/perf/hisilicon/Makefile
+++ b/drivers/perf/hisilicon/Makefile
@@ -2,7 +2,7 @@
obj-$(CONFIG_HISI_PMU) += hisi_uncore_pmu.o hisi_uncore_l3c_pmu.o \
hisi_uncore_hha_pmu.o hisi_uncore_ddrc_pmu.o hisi_uncore_sllc_pmu.o \
hisi_uncore_pa_pmu.o hisi_uncore_cpa_pmu.o hisi_uncore_uc_pmu.o \
- hisi_uncore_noc_pmu.o hisi_uncore_mn_pmu.o
+ hisi_uncore_noc_pmu.o hisi_uncore_mn_pmu.o hisi_uncore_its_pmu.o
obj-$(CONFIG_HISI_PCIE_PMU) += hisi_pcie_pmu.o
obj-$(CONFIG_HNS3_PMU) += hns3_pmu.o
diff --git a/drivers/perf/hisilicon/hisi_uncore_its_pmu.c b/drivers/perf/hisilicon/hisi_uncore_its_pmu.c
new file mode 100644
index 000000000000..3d1316ee12ef
--- /dev/null
+++ b/drivers/perf/hisilicon/hisi_uncore_its_pmu.c
@@ -0,0 +1,375 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Driver for HiSilicon Uncore ITS PMU device
+ *
+ * Copyright (c) 2026 HiSilicon Technologies Co., Ltd.
+ * Author: Yushan Wang <wangyushan12@huawei.com>
+ */
+#include <linux/bitops.h>
+#include <linux/cpuhotplug.h>
+#include <linux/device.h>
+#include <linux/io.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/property.h>
+#include <linux/sysfs.h>
+
+#include "hisi_uncore_pmu.h"
+
+#define ITS_PMU_VERSION 0x21000
+#define ITS_PMU_GLOBAL_CTRL 0x21004
+#define ITS_PMU_GLOBAL_CTRL_PMU_EN BIT(0)
+#define ITS_PMU_COUNTER_CTRL 0x21008
+#define ITS_PMU_EVENT_CTRL 0x2100c
+#define ITS_PMU_COUNTER0 0x21010
+
+#define ITS_PMU_INT_ID_MASK 0x20008
+#define ITS_PMU_INT_ID_CTRL 0x20084
+
+#define ITS_PMU_NR_COUNTERS 4
+
+#define ITS_PMU_EVENT_CNTRn(cntr0, n) ((cntr0) + 8 * (n))
+#define ITS_PMU_CNTR_CTRL_MASK(n) GENMASK(8 * ((n) + 1) - 1, 8 * (n))
+#define ITS_PMU_CNTR_EVENT_CFG(n, e) ((e) << ((n) * 8))
+#define ITS_PMU_EVENT_CTRL_TYPE GENMASK(12, 0)
+
+HISI_PMU_EVENT_ATTR_EXTRACTOR(int_id, config1, 31, 0);
+HISI_PMU_EVENT_ATTR_EXTRACTOR(int_en, config1, 32, 32);
+
+/* Dynamic CPU hotplug state used by this PMU driver */
+static enum cpuhp_state hisi_its_pmu_cpuhp_state;
+
+struct hisi_its_pmu_regs {
+ u32 version;
+ u32 pmu_ctrl;
+ u32 event_ctrl0;
+ u32 event_cntr0;
+ u32 cntr_ctrl;
+};
+
+static void hisi_its_pmu_write_evtype(struct hisi_pmu *its_pmu, int idx, u32 type)
+{
+ struct hisi_its_pmu_regs *reg_info = its_pmu->dev_info->private;
+ u32 reg;
+
+ reg = readl(its_pmu->base + reg_info->event_ctrl0);
+ reg &= ~ITS_PMU_CNTR_CTRL_MASK(idx);
+ reg |= ITS_PMU_CNTR_EVENT_CFG(idx, type);
+ writel(reg, its_pmu->base + reg_info->event_ctrl0);
+}
+
+static u64 hisi_its_pmu_read_counter(struct hisi_pmu *its_pmu,
+ struct hw_perf_event *hwc)
+{
+ struct hisi_its_pmu_regs *reg_info = its_pmu->dev_info->private;
+
+ return readq(its_pmu->base + ITS_PMU_EVENT_CNTRn(reg_info->event_cntr0, hwc->idx));
+}
+
+static void hisi_its_pmu_write_counter(struct hisi_pmu *its_pmu,
+ struct hw_perf_event *hwc, u64 val)
+{
+ struct hisi_its_pmu_regs *reg_info = its_pmu->dev_info->private;
+
+ writeq(val, its_pmu->base + ITS_PMU_EVENT_CNTRn(reg_info->event_cntr0, hwc->idx));
+}
+
+static void hisi_its_pmu_enable_counter(struct hisi_pmu *its_pmu,
+ struct hw_perf_event *hwc)
+{
+ struct hisi_its_pmu_regs *reg_info = its_pmu->dev_info->private;
+ u32 reg;
+
+ reg = readl(its_pmu->base + reg_info->cntr_ctrl);
+ reg |= BIT(hwc->idx);
+ writel(reg, its_pmu->base + reg_info->cntr_ctrl);
+}
+
+static void hisi_its_pmu_disable_counter(struct hisi_pmu *its_pmu,
+ struct hw_perf_event *hwc)
+{
+ struct hisi_its_pmu_regs *reg_info = its_pmu->dev_info->private;
+ u32 reg;
+
+ reg = readl(its_pmu->base + reg_info->cntr_ctrl);
+ reg &= ~BIT(hwc->idx);
+ writel(reg, its_pmu->base + reg_info->cntr_ctrl);
+}
+
+static void hisi_its_pmu_enable_counter_int(struct hisi_pmu *its_pmu,
+ struct hw_perf_event *hwc)
+{
+ /* We don't support interrupt, so a stub here. */
+}
+
+static void hisi_its_pmu_disable_counter_int(struct hisi_pmu *its_pmu,
+ struct hw_perf_event *hwc)
+{
+}
+
+static void hisi_its_pmu_start_counters(struct hisi_pmu *its_pmu)
+{
+ struct hisi_its_pmu_regs *reg_info = its_pmu->dev_info->private;
+ u32 reg;
+
+ reg = readl(its_pmu->base + reg_info->pmu_ctrl);
+ reg |= ITS_PMU_GLOBAL_CTRL_PMU_EN;
+ writel(reg, its_pmu->base + reg_info->pmu_ctrl);
+}
+
+static void hisi_its_pmu_stop_counters(struct hisi_pmu *its_pmu)
+{
+ struct hisi_its_pmu_regs *reg_info = its_pmu->dev_info->private;
+ u32 reg;
+
+ reg = readl(its_pmu->base + reg_info->pmu_ctrl);
+ reg &= ~ITS_PMU_GLOBAL_CTRL_PMU_EN;
+ writel(reg, its_pmu->base + reg_info->pmu_ctrl);
+}
+
+static void hisi_its_pmu_enable_filter(struct perf_event *event)
+{
+ struct hisi_pmu *its_pmu = to_hisi_pmu(event->pmu);
+ u32 int_id = hisi_get_int_id(event);
+ u32 int_en = hisi_get_int_en(event);
+
+ /*
+ * Don't touch global filtering config if user doesn't
+ * explicitly specify it.
+ */
+ if (int_en) {
+ writel(int_id, its_pmu->base + ITS_PMU_INT_ID_CTRL);
+ /* Write 0 to this register to enable filtering with int_id. */
+ writel(0, its_pmu->base + ITS_PMU_INT_ID_MASK);
+ } else {
+ writel(-1U, its_pmu->base + ITS_PMU_INT_ID_MASK);
+ }
+}
+
+static void hisi_its_pmu_disable_filter(struct perf_event *event)
+{
+ struct hisi_pmu *its_pmu = to_hisi_pmu(event->pmu);
+ u32 int_en = hisi_get_int_en(event);
+
+ /* Don't touch global filtering config if this is not the last counter. */
+ if (bitmap_weight(its_pmu->pmu_events.used_mask, its_pmu->num_counters) > 1)
+ return;
+
+ if (int_en) {
+ writel(0, its_pmu->base + ITS_PMU_INT_ID_CTRL);
+ writel(-1U, its_pmu->base + ITS_PMU_INT_ID_MASK);
+ }
+}
+
+static const struct hisi_uncore_ops hisi_uncore_its_ops = {
+ .write_evtype = hisi_its_pmu_write_evtype,
+ .get_event_idx = hisi_uncore_pmu_get_event_idx,
+ .read_counter = hisi_its_pmu_read_counter,
+ .write_counter = hisi_its_pmu_write_counter,
+ .enable_counter = hisi_its_pmu_enable_counter,
+ .disable_counter = hisi_its_pmu_disable_counter,
+ .enable_counter_int = hisi_its_pmu_enable_counter_int,
+ .disable_counter_int = hisi_its_pmu_disable_counter_int,
+ .start_counters = hisi_its_pmu_start_counters,
+ .stop_counters = hisi_its_pmu_stop_counters,
+ .enable_filter = hisi_its_pmu_enable_filter,
+ .disable_filter = hisi_its_pmu_disable_filter,
+};
+
+static struct attribute *hisi_its_pmu_format_attrs[] = {
+ HISI_PMU_FORMAT_ATTR(event, "config:0-7"),
+ HISI_PMU_FORMAT_ATTR(int_id, "config1:0-31"),
+ HISI_PMU_FORMAT_ATTR(int_en, "config1:32-32"),
+ NULL
+};
+
+static const struct attribute_group hisi_its_pmu_format_group = {
+ .name = "format",
+ .attrs = hisi_its_pmu_format_attrs,
+};
+
+static struct attribute *hisi_its_pmu_events_attrs[] = {
+ HISI_PMU_EVENT_ATTR(lpi_num, 0xc0),
+ HISI_PMU_EVENT_ATTR(lpi_time, 0x80),
+ HISI_PMU_EVENT_ATTR(sgi_num, 0xc1),
+ HISI_PMU_EVENT_ATTR(sgi_time, 0x81),
+ HISI_PMU_EVENT_ATTR(ppi_num, 0xc2),
+ HISI_PMU_EVENT_ATTR(ppi_time, 0x82),
+ HISI_PMU_EVENT_ATTR(sl3_lpi_num, 0xc3),
+ HISI_PMU_EVENT_ATTR(sl3_sgi_num, 0xc4),
+ HISI_PMU_EVENT_ATTR(sl3_ppi_num, 0xc5),
+ HISI_PMU_EVENT_ATTR(sl0_ddr_read, 0xc9),
+ HISI_PMU_EVENT_ATTR(sl0_ddr_time, 0x89),
+ HISI_PMU_EVENT_ATTR(sl1_ddr_read, 0xca),
+ HISI_PMU_EVENT_ATTR(sl1_ddr_time, 0x8a),
+ HISI_PMU_EVENT_ATTR(sl2_ddr_read, 0xcb),
+ HISI_PMU_EVENT_ATTR(sl2_ddr_time, 0x8b),
+ HISI_PMU_EVENT_ATTR(cycles, 0xcc),
+ NULL
+};
+
+static const struct attribute_group hisi_its_pmu_events_group = {
+ .name = "events",
+ .attrs = hisi_its_pmu_events_attrs,
+};
+
+static const struct attribute_group *hisi_its_pmu_attr_groups[] = {
+ &hisi_its_pmu_format_group,
+ &hisi_its_pmu_events_group,
+ &hisi_pmu_cpumask_attr_group,
+ &hisi_pmu_identifier_group,
+ NULL
+};
+
+static int hisi_its_pmu_dev_init(struct platform_device *pdev, struct hisi_pmu *its_pmu)
+{
+ struct hisi_its_pmu_regs *reg_info;
+
+ hisi_uncore_pmu_init_topology(its_pmu, &pdev->dev);
+
+ if (its_pmu->topo.scl_id < 0)
+ return dev_err_probe(&pdev->dev, -EINVAL, "failed to get scl-id\n");
+
+ if (its_pmu->topo.index_id < 0)
+ return dev_err_probe(&pdev->dev, -EINVAL, "failed to get idx-id\n");
+
+ its_pmu->base = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(its_pmu->base))
+ return dev_err_probe(&pdev->dev, PTR_ERR(its_pmu->base),
+ "fail to remap io memory\n");
+
+ its_pmu->dev_info = device_get_match_data(&pdev->dev);
+ if (!its_pmu->dev_info)
+ return -ENODEV;
+
+ its_pmu->pmu_events.attr_groups = its_pmu->dev_info->attr_groups;
+ its_pmu->counter_bits = its_pmu->dev_info->counter_bits;
+ its_pmu->check_event = its_pmu->dev_info->check_event;
+ its_pmu->num_counters = ITS_PMU_NR_COUNTERS;
+ its_pmu->ops = &hisi_uncore_its_ops;
+ its_pmu->dev = &pdev->dev;
+ its_pmu->on_cpu = -1;
+
+ reg_info = its_pmu->dev_info->private;
+ its_pmu->identifier = readl(its_pmu->base + reg_info->version);
+
+ return 0;
+}
+
+static void hisi_its_pmu_remove_cpuhp_instance(void *hotplug_node)
+{
+ cpuhp_state_remove_instance_nocalls(hisi_its_pmu_cpuhp_state, hotplug_node);
+}
+
+static void hisi_its_pmu_unregister_pmu(void *pmu)
+{
+ perf_pmu_unregister(pmu);
+}
+
+static int hisi_its_pmu_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct hisi_pmu *its_pmu;
+ char *name;
+ int ret;
+
+ its_pmu = devm_kzalloc(dev, sizeof(*its_pmu), GFP_KERNEL);
+ if (!its_pmu)
+ return -ENOMEM;
+
+ /*
+ * HiSilicon Uncore PMU framework needs to get common hisi_pmu device
+ * from device's drvdata.
+ */
+ platform_set_drvdata(pdev, its_pmu);
+
+ ret = hisi_its_pmu_dev_init(pdev, its_pmu);
+ if (ret)
+ return ret;
+
+ ret = cpuhp_state_add_instance(hisi_its_pmu_cpuhp_state, &its_pmu->node);
+ if (ret)
+ return dev_err_probe(dev, ret, "Fail to register cpuhp instance\n");
+
+ ret = devm_add_action_or_reset(dev, hisi_its_pmu_remove_cpuhp_instance,
+ &its_pmu->node);
+ if (ret)
+ return ret;
+
+ hisi_pmu_init(its_pmu, THIS_MODULE);
+
+ name = devm_kasprintf(dev, GFP_KERNEL, "hisi_scl%d_its%d",
+ its_pmu->topo.scl_id, its_pmu->topo.index_id);
+ if (!name)
+ return -ENOMEM;
+
+ ret = perf_pmu_register(&its_pmu->pmu, name, -1);
+ if (ret)
+ return dev_err_probe(dev, ret, "Fail to register PMU\n");
+
+ return devm_add_action_or_reset(dev, hisi_its_pmu_unregister_pmu,
+ &its_pmu->pmu);
+}
+
+static struct hisi_its_pmu_regs hisi_its_v1_pmu_regs = {
+ .version = ITS_PMU_VERSION,
+ .pmu_ctrl = ITS_PMU_GLOBAL_CTRL,
+ .event_ctrl0 = ITS_PMU_EVENT_CTRL,
+ .event_cntr0 = ITS_PMU_COUNTER0,
+ .cntr_ctrl = ITS_PMU_COUNTER_CTRL,
+};
+
+static const struct hisi_pmu_dev_info hisi_its_v1 = {
+ .attr_groups = hisi_its_pmu_attr_groups,
+ .counter_bits = 48,
+ .check_event = ITS_PMU_EVENT_CTRL_TYPE,
+ .private = &hisi_its_v1_pmu_regs,
+};
+
+static const struct acpi_device_id hisi_its_pmu_ids[] = {
+ { "HISI0591", (kernel_ulong_t) &hisi_its_v1 },
+ { }
+};
+MODULE_DEVICE_TABLE(acpi, hisi_its_pmu_ids);
+
+static struct platform_driver hisi_its_pmu_driver = {
+ .driver = {
+ .name = "hisi_its_pmu",
+ .acpi_match_table = hisi_its_pmu_ids,
+ .suppress_bind_attrs = true,
+ },
+ .probe = hisi_its_pmu_probe,
+};
+
+static int __init hisi_its_pmu_module_init(void)
+{
+ int ret = cpuhp_setup_state_multi(CPUHP_AP_ONLINE_DYN,
+ "perf/hisi/its:online",
+ hisi_uncore_pmu_online_cpu,
+ hisi_uncore_pmu_offline_cpu);
+ if (ret < 0) {
+ pr_err("hisi_its_pmu: Fail to setup cpuhp callbacks, ret = %d\n", ret);
+ return ret;
+ }
+ hisi_its_pmu_cpuhp_state = ret;
+
+ ret = platform_driver_register(&hisi_its_pmu_driver);
+ if (ret)
+ cpuhp_remove_multi_state(hisi_its_pmu_cpuhp_state);
+
+ return ret;
+}
+module_init(hisi_its_pmu_module_init);
+
+static void __exit hisi_its_pmu_module_exit(void)
+{
+ platform_driver_unregister(&hisi_its_pmu_driver);
+ cpuhp_remove_multi_state(hisi_its_pmu_cpuhp_state);
+}
+module_exit(hisi_its_pmu_module_exit);
+
+MODULE_IMPORT_NS("HISI_PMU");
+MODULE_DESCRIPTION("HiSilicon SoC Uncore ITS PMU driver");
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Yushan Wang <wangyushan12@huawei.com>");
--
2.33.0
^ permalink raw reply related
* [PATCH v2 0/3] drivers/perf: hisi: Updates for HiSilicon uncore PMUs
From: Yushan Wang @ 2026-06-12 9:32 UTC (permalink / raw)
To: will, mark.rutland, robin.murphy, linux-arm-kernel, linux-kernel
Cc: fanghao11, linuxarm, liuyonglong, prime.zeng, wangzhou1,
wangyushan12
This patchset added support of ITS PMU, and new version of MN PMU.
ITS PMU supports counting number and latency of interrupts by
catagory, and statistics of micro-ops of ITS.
The new version of MN PMU added cycles event, to be used for MN
metric computing.
Changes:
v2:
- Added int_en filter to tell if int_id is used, enabling filtering
interrupt with 0 int_id per Sashiko.
- Changed event format width to align with register width per Sashiko.
Link to v1: https://lore.kernel.org/all/20260423152959.1458563-1-wangyushan12@huawei.com/
Link to Sashiko review report: https://sashiko.dev/#/patchset/20260423152959.1458563-1-wangyushan12%40huawei.com
Yifan Wu (1):
drivers/perf: hisi: Add new function for HiSilicon MN PMU driver
Yushan Wang (2):
drivers/perf: hisi: Replace counter number with defined macro
drivers/perf: hisi: Support uncore ITS PMU
Documentation/admin-guide/perf/hisi-pmu.rst | 12 +
drivers/perf/hisilicon/Makefile | 2 +-
drivers/perf/hisilicon/hisi_uncore_its_pmu.c | 375 +++++++++++++++++++
drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c | 2 +-
drivers/perf/hisilicon/hisi_uncore_mn_pmu.c | 61 ++-
5 files changed, 444 insertions(+), 8 deletions(-)
create mode 100644 drivers/perf/hisilicon/hisi_uncore_its_pmu.c
--
2.33.0
^ permalink raw reply
* [PATCH v2 1/3] drivers/perf: hisi: Replace counter number with defined macro
From: Yushan Wang @ 2026-06-12 9:32 UTC (permalink / raw)
To: will, mark.rutland, robin.murphy, linux-arm-kernel, linux-kernel
Cc: fanghao11, linuxarm, liuyonglong, prime.zeng, wangzhou1,
wangyushan12
In-Reply-To: <20260612093207.1242000-1-wangyushan12@huawei.com>
The inline number means counter numbers of the PMU. Replace it with
already define macro for better readability.
Signed-off-by: Yushan Wang <wangyushan12@huawei.com>
---
drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c b/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
index f963e4f9e552..59e6dff4032f 100644
--- a/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
+++ b/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
@@ -362,7 +362,7 @@ static int hisi_l3c_pmu_check_filter(struct perf_event *event)
*/
static u32 hisi_l3c_pmu_get_counter_offset(int cntr_idx)
{
- return L3C_CNTR0_LOWER + L3C_HW_IDX(cntr_idx) * 8;
+ return L3C_CNTR0_LOWER + L3C_HW_IDX(cntr_idx) * L3C_NR_COUNTERS;
}
static u64 hisi_l3c_pmu_read_counter(struct hisi_pmu *l3c_pmu,
--
2.33.0
^ permalink raw reply related
* Re: [PATCH v2 0/3] drivers/perf: hisi: Updates for HiSilicon uncore PMUs
From: Yushan Wang @ 2026-06-12 9:35 UTC (permalink / raw)
To: will, mark.rutland, robin.murphy, linux-arm-kernel, linux-kernel
Cc: fanghao11, linuxarm, liuyonglong, prime.zeng, wangzhou1
In-Reply-To: <20260612093207.1242000-1-wangyushan12@huawei.com>
There are some issues with patch 1, please ignore this, sorry.
On 6/12/2026 5:32 PM, Yushan Wang wrote:
> This patchset added support of ITS PMU, and new version of MN PMU.
>
> ITS PMU supports counting number and latency of interrupts by
> catagory, and statistics of micro-ops of ITS.
>
> The new version of MN PMU added cycles event, to be used for MN
> metric computing.
>
> Changes:
> v2:
> - Added int_en filter to tell if int_id is used, enabling filtering
> interrupt with 0 int_id per Sashiko.
> - Changed event format width to align with register width per Sashiko.
> Link to v1: https://lore.kernel.org/all/20260423152959.1458563-1-wangyushan12@huawei.com/
> Link to Sashiko review report: https://sashiko.dev/#/patchset/20260423152959.1458563-1-wangyushan12%40huawei.com
>
> Yifan Wu (1):
> drivers/perf: hisi: Add new function for HiSilicon MN PMU driver
>
> Yushan Wang (2):
> drivers/perf: hisi: Replace counter number with defined macro
> drivers/perf: hisi: Support uncore ITS PMU
>
> Documentation/admin-guide/perf/hisi-pmu.rst | 12 +
> drivers/perf/hisilicon/Makefile | 2 +-
> drivers/perf/hisilicon/hisi_uncore_its_pmu.c | 375 +++++++++++++++++++
> drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c | 2 +-
> drivers/perf/hisilicon/hisi_uncore_mn_pmu.c | 61 ++-
> 5 files changed, 444 insertions(+), 8 deletions(-)
> create mode 100644 drivers/perf/hisilicon/hisi_uncore_its_pmu.c
>
^ permalink raw reply
* [PATCH v2] net: airoha: Fix error handling in airoha_ppe_flush_sram_entries()
From: Wayen.Yan @ 2026-06-12 9:37 UTC (permalink / raw)
To: netdev; +Cc: lorenzo, linux-arm-kernel, linux-mediatek
In airoha_ppe_flush_sram_entries(), the outer "err" variable was never
updated when the inner loop variable shadowed it, causing the function
to always return 0 even when airoha_ppe_foe_commit_sram_entry() fails.
Drop the outer "err" variable and return directly on error, propagating
the error code from airoha_ppe_foe_commit_sram_entry() correctly.
Fixes: 620d7b91aadb ("net: airoha: ppe: Flush PPE SRAM table during PPE setup")
Link: https://lore.kernel.org/netdev/6a2b40e4.4dd82583.3a5c46.e52f@mx.google.com/
Signed-off-by: Wayen.Yan <win847@gmail.com>
---
drivers/net/ethernet/airoha/airoha_ppe.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/airoha/airoha_ppe.c b/drivers/net/ethernet/airoha/airoha_ppe.c
index 5c9dff6..a124f15 100644
--- a/drivers/net/ethernet/airoha/airoha_ppe.c
+++ b/drivers/net/ethernet/airoha/airoha_ppe.c
@@ -1330,7 +1330,7 @@ static int airoha_ppe_flush_sram_entries(struct airoha_ppe *ppe)
{
u32 sram_num_entries = airoha_ppe_get_total_sram_num_entries(ppe);
struct airoha_foe_entry *hwe = ppe->foe;
- int i, err = 0;
+ int i;
for (i = 0; i < sram_num_entries; i++) {
int err;
@@ -1338,10 +1338,10 @@ static int airoha_ppe_flush_sram_entries(struct airoha_ppe *ppe)
memset(&hwe[i], 0, sizeof(*hwe));
err = airoha_ppe_foe_commit_sram_entry(ppe, i);
if (err)
- break;
+ return err;
}
- return err;
+ return 0;
}
static struct airoha_npu *airoha_ppe_npu_get(struct airoha_eth *eth)
--
2.51.0
^ permalink raw reply related
* [PATCH v2 0/2] drivers/perf: hisi: Updates for HiSilicon uncore PMUs
From: Yushan Wang @ 2026-06-12 9:38 UTC (permalink / raw)
To: will, mark.rutland, robin.murphy, linux-arm-kernel, linux-kernel
Cc: fanghao11, linuxarm, liuyonglong, prime.zeng, wangzhou1,
wangyushan12
This patchset added support of ITS PMU, and new version of MN PMU.
ITS PMU supports counting number and latency of interrupts by
category, and statistics of micro-ops of ITS.
The new version of MN PMU added cycles event, to be used for MN
metric computing.
Changes:
v2:
- Added int_en filter to tell if int_id is used, enabling filtering
interrupt with 0 int_id per Sashiko.
- Changed event format width to align with register width per Sashiko.
Link to v1: https://lore.kernel.org/all/20260423152959.1458563-1-wangyushan12@huawei.com/
Link to Sashiko review report: https://sashiko.dev/#/patchset/20260423152959.1458563-1-wangyushan12%40huawei.com
Yifan Wu (1):
drivers/perf: hisi: Add new function for HiSilicon MN PMU driver
Yushan Wang (1):
drivers/perf: hisi: Support uncore ITS PMU
Documentation/admin-guide/perf/hisi-pmu.rst | 12 +
drivers/perf/hisilicon/Makefile | 2 +-
drivers/perf/hisilicon/hisi_uncore_its_pmu.c | 375 +++++++++++++++++++
drivers/perf/hisilicon/hisi_uncore_mn_pmu.c | 61 ++-
4 files changed, 443 insertions(+), 7 deletions(-)
create mode 100644 drivers/perf/hisilicon/hisi_uncore_its_pmu.c
--
2.33.0
^ permalink raw reply
* [PATCH v2 1/2] drivers/perf: hisi: Support uncore ITS PMU
From: Yushan Wang @ 2026-06-12 9:38 UTC (permalink / raw)
To: will, mark.rutland, robin.murphy, linux-arm-kernel, linux-kernel
Cc: fanghao11, linuxarm, liuyonglong, prime.zeng, wangzhou1,
wangyushan12
In-Reply-To: <20260612093812.1249049-1-wangyushan12@huawei.com>
Support uncore ITS PMU, which provides the capability of counting
the number of interrupts routed to ITS by interrupt catagories, and the
latency. It also supports collecting statistics of micro-ops of ITS.
The driver adapts to HiSilicon uncore PMU framework. It does not support
overflow interruption, which is the same as NoC PMU, so a few dummy
functions or handling interrupts are left empty.
Signed-off-by: Yushan Wang <wangyushan12@huawei.com>
---
Documentation/admin-guide/perf/hisi-pmu.rst | 12 +
drivers/perf/hisilicon/Makefile | 2 +-
drivers/perf/hisilicon/hisi_uncore_its_pmu.c | 375 +++++++++++++++++++
3 files changed, 388 insertions(+), 1 deletion(-)
create mode 100644 drivers/perf/hisilicon/hisi_uncore_its_pmu.c
diff --git a/Documentation/admin-guide/perf/hisi-pmu.rst b/Documentation/admin-guide/perf/hisi-pmu.rst
index d56b2d690709..b2b79be998f9 100644
--- a/Documentation/admin-guide/perf/hisi-pmu.rst
+++ b/Documentation/admin-guide/perf/hisi-pmu.rst
@@ -128,6 +128,18 @@ channel with this option. The current supported channels are as follows:
7. tt_en: NoC PMU supports counting only transactions that have tracetag set
if this option is set. See the 2nd list for more information about tracetag.
+8. int_id: ITS PMU supports filtering by interrupt id, which is defined by
+hardware. Interrupt id takes up to 32 bits, and can be divided into 2 parts:
+
+- Upper 16 bits: DeviceID if counting LPI, PEID if counting SGI/PPI.
+- Lower 16 bits: EventID if counting LPI, IntID if counting SGI/PPI.
+
+int_id is a global configuration for each PMU instance, if multiple different
+int_id's are specified, the last came in will be effective.
+
+9. int_en: A one-bit flag to tell if int_id is used to filter the statistics. It
+allows filtering 0 DeviceID and EventID.
+
For HiSilicon uncore PMU v3 whose identifier is 0x40, some uncore PMUs are
further divided into parts for finer granularity of tracing, each part has its
own dedicated PMU, and all such PMUs together cover the monitoring job of events
diff --git a/drivers/perf/hisilicon/Makefile b/drivers/perf/hisilicon/Makefile
index 186be3d02238..5f28cfdb8a72 100644
--- a/drivers/perf/hisilicon/Makefile
+++ b/drivers/perf/hisilicon/Makefile
@@ -2,7 +2,7 @@
obj-$(CONFIG_HISI_PMU) += hisi_uncore_pmu.o hisi_uncore_l3c_pmu.o \
hisi_uncore_hha_pmu.o hisi_uncore_ddrc_pmu.o hisi_uncore_sllc_pmu.o \
hisi_uncore_pa_pmu.o hisi_uncore_cpa_pmu.o hisi_uncore_uc_pmu.o \
- hisi_uncore_noc_pmu.o hisi_uncore_mn_pmu.o
+ hisi_uncore_noc_pmu.o hisi_uncore_mn_pmu.o hisi_uncore_its_pmu.o
obj-$(CONFIG_HISI_PCIE_PMU) += hisi_pcie_pmu.o
obj-$(CONFIG_HNS3_PMU) += hns3_pmu.o
diff --git a/drivers/perf/hisilicon/hisi_uncore_its_pmu.c b/drivers/perf/hisilicon/hisi_uncore_its_pmu.c
new file mode 100644
index 000000000000..3d1316ee12ef
--- /dev/null
+++ b/drivers/perf/hisilicon/hisi_uncore_its_pmu.c
@@ -0,0 +1,375 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Driver for HiSilicon Uncore ITS PMU device
+ *
+ * Copyright (c) 2026 HiSilicon Technologies Co., Ltd.
+ * Author: Yushan Wang <wangyushan12@huawei.com>
+ */
+#include <linux/bitops.h>
+#include <linux/cpuhotplug.h>
+#include <linux/device.h>
+#include <linux/io.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/property.h>
+#include <linux/sysfs.h>
+
+#include "hisi_uncore_pmu.h"
+
+#define ITS_PMU_VERSION 0x21000
+#define ITS_PMU_GLOBAL_CTRL 0x21004
+#define ITS_PMU_GLOBAL_CTRL_PMU_EN BIT(0)
+#define ITS_PMU_COUNTER_CTRL 0x21008
+#define ITS_PMU_EVENT_CTRL 0x2100c
+#define ITS_PMU_COUNTER0 0x21010
+
+#define ITS_PMU_INT_ID_MASK 0x20008
+#define ITS_PMU_INT_ID_CTRL 0x20084
+
+#define ITS_PMU_NR_COUNTERS 4
+
+#define ITS_PMU_EVENT_CNTRn(cntr0, n) ((cntr0) + 8 * (n))
+#define ITS_PMU_CNTR_CTRL_MASK(n) GENMASK(8 * ((n) + 1) - 1, 8 * (n))
+#define ITS_PMU_CNTR_EVENT_CFG(n, e) ((e) << ((n) * 8))
+#define ITS_PMU_EVENT_CTRL_TYPE GENMASK(12, 0)
+
+HISI_PMU_EVENT_ATTR_EXTRACTOR(int_id, config1, 31, 0);
+HISI_PMU_EVENT_ATTR_EXTRACTOR(int_en, config1, 32, 32);
+
+/* Dynamic CPU hotplug state used by this PMU driver */
+static enum cpuhp_state hisi_its_pmu_cpuhp_state;
+
+struct hisi_its_pmu_regs {
+ u32 version;
+ u32 pmu_ctrl;
+ u32 event_ctrl0;
+ u32 event_cntr0;
+ u32 cntr_ctrl;
+};
+
+static void hisi_its_pmu_write_evtype(struct hisi_pmu *its_pmu, int idx, u32 type)
+{
+ struct hisi_its_pmu_regs *reg_info = its_pmu->dev_info->private;
+ u32 reg;
+
+ reg = readl(its_pmu->base + reg_info->event_ctrl0);
+ reg &= ~ITS_PMU_CNTR_CTRL_MASK(idx);
+ reg |= ITS_PMU_CNTR_EVENT_CFG(idx, type);
+ writel(reg, its_pmu->base + reg_info->event_ctrl0);
+}
+
+static u64 hisi_its_pmu_read_counter(struct hisi_pmu *its_pmu,
+ struct hw_perf_event *hwc)
+{
+ struct hisi_its_pmu_regs *reg_info = its_pmu->dev_info->private;
+
+ return readq(its_pmu->base + ITS_PMU_EVENT_CNTRn(reg_info->event_cntr0, hwc->idx));
+}
+
+static void hisi_its_pmu_write_counter(struct hisi_pmu *its_pmu,
+ struct hw_perf_event *hwc, u64 val)
+{
+ struct hisi_its_pmu_regs *reg_info = its_pmu->dev_info->private;
+
+ writeq(val, its_pmu->base + ITS_PMU_EVENT_CNTRn(reg_info->event_cntr0, hwc->idx));
+}
+
+static void hisi_its_pmu_enable_counter(struct hisi_pmu *its_pmu,
+ struct hw_perf_event *hwc)
+{
+ struct hisi_its_pmu_regs *reg_info = its_pmu->dev_info->private;
+ u32 reg;
+
+ reg = readl(its_pmu->base + reg_info->cntr_ctrl);
+ reg |= BIT(hwc->idx);
+ writel(reg, its_pmu->base + reg_info->cntr_ctrl);
+}
+
+static void hisi_its_pmu_disable_counter(struct hisi_pmu *its_pmu,
+ struct hw_perf_event *hwc)
+{
+ struct hisi_its_pmu_regs *reg_info = its_pmu->dev_info->private;
+ u32 reg;
+
+ reg = readl(its_pmu->base + reg_info->cntr_ctrl);
+ reg &= ~BIT(hwc->idx);
+ writel(reg, its_pmu->base + reg_info->cntr_ctrl);
+}
+
+static void hisi_its_pmu_enable_counter_int(struct hisi_pmu *its_pmu,
+ struct hw_perf_event *hwc)
+{
+ /* We don't support interrupt, so a stub here. */
+}
+
+static void hisi_its_pmu_disable_counter_int(struct hisi_pmu *its_pmu,
+ struct hw_perf_event *hwc)
+{
+}
+
+static void hisi_its_pmu_start_counters(struct hisi_pmu *its_pmu)
+{
+ struct hisi_its_pmu_regs *reg_info = its_pmu->dev_info->private;
+ u32 reg;
+
+ reg = readl(its_pmu->base + reg_info->pmu_ctrl);
+ reg |= ITS_PMU_GLOBAL_CTRL_PMU_EN;
+ writel(reg, its_pmu->base + reg_info->pmu_ctrl);
+}
+
+static void hisi_its_pmu_stop_counters(struct hisi_pmu *its_pmu)
+{
+ struct hisi_its_pmu_regs *reg_info = its_pmu->dev_info->private;
+ u32 reg;
+
+ reg = readl(its_pmu->base + reg_info->pmu_ctrl);
+ reg &= ~ITS_PMU_GLOBAL_CTRL_PMU_EN;
+ writel(reg, its_pmu->base + reg_info->pmu_ctrl);
+}
+
+static void hisi_its_pmu_enable_filter(struct perf_event *event)
+{
+ struct hisi_pmu *its_pmu = to_hisi_pmu(event->pmu);
+ u32 int_id = hisi_get_int_id(event);
+ u32 int_en = hisi_get_int_en(event);
+
+ /*
+ * Don't touch global filtering config if user doesn't
+ * explicitly specify it.
+ */
+ if (int_en) {
+ writel(int_id, its_pmu->base + ITS_PMU_INT_ID_CTRL);
+ /* Write 0 to this register to enable filtering with int_id. */
+ writel(0, its_pmu->base + ITS_PMU_INT_ID_MASK);
+ } else {
+ writel(-1U, its_pmu->base + ITS_PMU_INT_ID_MASK);
+ }
+}
+
+static void hisi_its_pmu_disable_filter(struct perf_event *event)
+{
+ struct hisi_pmu *its_pmu = to_hisi_pmu(event->pmu);
+ u32 int_en = hisi_get_int_en(event);
+
+ /* Don't touch global filtering config if this is not the last counter. */
+ if (bitmap_weight(its_pmu->pmu_events.used_mask, its_pmu->num_counters) > 1)
+ return;
+
+ if (int_en) {
+ writel(0, its_pmu->base + ITS_PMU_INT_ID_CTRL);
+ writel(-1U, its_pmu->base + ITS_PMU_INT_ID_MASK);
+ }
+}
+
+static const struct hisi_uncore_ops hisi_uncore_its_ops = {
+ .write_evtype = hisi_its_pmu_write_evtype,
+ .get_event_idx = hisi_uncore_pmu_get_event_idx,
+ .read_counter = hisi_its_pmu_read_counter,
+ .write_counter = hisi_its_pmu_write_counter,
+ .enable_counter = hisi_its_pmu_enable_counter,
+ .disable_counter = hisi_its_pmu_disable_counter,
+ .enable_counter_int = hisi_its_pmu_enable_counter_int,
+ .disable_counter_int = hisi_its_pmu_disable_counter_int,
+ .start_counters = hisi_its_pmu_start_counters,
+ .stop_counters = hisi_its_pmu_stop_counters,
+ .enable_filter = hisi_its_pmu_enable_filter,
+ .disable_filter = hisi_its_pmu_disable_filter,
+};
+
+static struct attribute *hisi_its_pmu_format_attrs[] = {
+ HISI_PMU_FORMAT_ATTR(event, "config:0-7"),
+ HISI_PMU_FORMAT_ATTR(int_id, "config1:0-31"),
+ HISI_PMU_FORMAT_ATTR(int_en, "config1:32-32"),
+ NULL
+};
+
+static const struct attribute_group hisi_its_pmu_format_group = {
+ .name = "format",
+ .attrs = hisi_its_pmu_format_attrs,
+};
+
+static struct attribute *hisi_its_pmu_events_attrs[] = {
+ HISI_PMU_EVENT_ATTR(lpi_num, 0xc0),
+ HISI_PMU_EVENT_ATTR(lpi_time, 0x80),
+ HISI_PMU_EVENT_ATTR(sgi_num, 0xc1),
+ HISI_PMU_EVENT_ATTR(sgi_time, 0x81),
+ HISI_PMU_EVENT_ATTR(ppi_num, 0xc2),
+ HISI_PMU_EVENT_ATTR(ppi_time, 0x82),
+ HISI_PMU_EVENT_ATTR(sl3_lpi_num, 0xc3),
+ HISI_PMU_EVENT_ATTR(sl3_sgi_num, 0xc4),
+ HISI_PMU_EVENT_ATTR(sl3_ppi_num, 0xc5),
+ HISI_PMU_EVENT_ATTR(sl0_ddr_read, 0xc9),
+ HISI_PMU_EVENT_ATTR(sl0_ddr_time, 0x89),
+ HISI_PMU_EVENT_ATTR(sl1_ddr_read, 0xca),
+ HISI_PMU_EVENT_ATTR(sl1_ddr_time, 0x8a),
+ HISI_PMU_EVENT_ATTR(sl2_ddr_read, 0xcb),
+ HISI_PMU_EVENT_ATTR(sl2_ddr_time, 0x8b),
+ HISI_PMU_EVENT_ATTR(cycles, 0xcc),
+ NULL
+};
+
+static const struct attribute_group hisi_its_pmu_events_group = {
+ .name = "events",
+ .attrs = hisi_its_pmu_events_attrs,
+};
+
+static const struct attribute_group *hisi_its_pmu_attr_groups[] = {
+ &hisi_its_pmu_format_group,
+ &hisi_its_pmu_events_group,
+ &hisi_pmu_cpumask_attr_group,
+ &hisi_pmu_identifier_group,
+ NULL
+};
+
+static int hisi_its_pmu_dev_init(struct platform_device *pdev, struct hisi_pmu *its_pmu)
+{
+ struct hisi_its_pmu_regs *reg_info;
+
+ hisi_uncore_pmu_init_topology(its_pmu, &pdev->dev);
+
+ if (its_pmu->topo.scl_id < 0)
+ return dev_err_probe(&pdev->dev, -EINVAL, "failed to get scl-id\n");
+
+ if (its_pmu->topo.index_id < 0)
+ return dev_err_probe(&pdev->dev, -EINVAL, "failed to get idx-id\n");
+
+ its_pmu->base = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(its_pmu->base))
+ return dev_err_probe(&pdev->dev, PTR_ERR(its_pmu->base),
+ "fail to remap io memory\n");
+
+ its_pmu->dev_info = device_get_match_data(&pdev->dev);
+ if (!its_pmu->dev_info)
+ return -ENODEV;
+
+ its_pmu->pmu_events.attr_groups = its_pmu->dev_info->attr_groups;
+ its_pmu->counter_bits = its_pmu->dev_info->counter_bits;
+ its_pmu->check_event = its_pmu->dev_info->check_event;
+ its_pmu->num_counters = ITS_PMU_NR_COUNTERS;
+ its_pmu->ops = &hisi_uncore_its_ops;
+ its_pmu->dev = &pdev->dev;
+ its_pmu->on_cpu = -1;
+
+ reg_info = its_pmu->dev_info->private;
+ its_pmu->identifier = readl(its_pmu->base + reg_info->version);
+
+ return 0;
+}
+
+static void hisi_its_pmu_remove_cpuhp_instance(void *hotplug_node)
+{
+ cpuhp_state_remove_instance_nocalls(hisi_its_pmu_cpuhp_state, hotplug_node);
+}
+
+static void hisi_its_pmu_unregister_pmu(void *pmu)
+{
+ perf_pmu_unregister(pmu);
+}
+
+static int hisi_its_pmu_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct hisi_pmu *its_pmu;
+ char *name;
+ int ret;
+
+ its_pmu = devm_kzalloc(dev, sizeof(*its_pmu), GFP_KERNEL);
+ if (!its_pmu)
+ return -ENOMEM;
+
+ /*
+ * HiSilicon Uncore PMU framework needs to get common hisi_pmu device
+ * from device's drvdata.
+ */
+ platform_set_drvdata(pdev, its_pmu);
+
+ ret = hisi_its_pmu_dev_init(pdev, its_pmu);
+ if (ret)
+ return ret;
+
+ ret = cpuhp_state_add_instance(hisi_its_pmu_cpuhp_state, &its_pmu->node);
+ if (ret)
+ return dev_err_probe(dev, ret, "Fail to register cpuhp instance\n");
+
+ ret = devm_add_action_or_reset(dev, hisi_its_pmu_remove_cpuhp_instance,
+ &its_pmu->node);
+ if (ret)
+ return ret;
+
+ hisi_pmu_init(its_pmu, THIS_MODULE);
+
+ name = devm_kasprintf(dev, GFP_KERNEL, "hisi_scl%d_its%d",
+ its_pmu->topo.scl_id, its_pmu->topo.index_id);
+ if (!name)
+ return -ENOMEM;
+
+ ret = perf_pmu_register(&its_pmu->pmu, name, -1);
+ if (ret)
+ return dev_err_probe(dev, ret, "Fail to register PMU\n");
+
+ return devm_add_action_or_reset(dev, hisi_its_pmu_unregister_pmu,
+ &its_pmu->pmu);
+}
+
+static struct hisi_its_pmu_regs hisi_its_v1_pmu_regs = {
+ .version = ITS_PMU_VERSION,
+ .pmu_ctrl = ITS_PMU_GLOBAL_CTRL,
+ .event_ctrl0 = ITS_PMU_EVENT_CTRL,
+ .event_cntr0 = ITS_PMU_COUNTER0,
+ .cntr_ctrl = ITS_PMU_COUNTER_CTRL,
+};
+
+static const struct hisi_pmu_dev_info hisi_its_v1 = {
+ .attr_groups = hisi_its_pmu_attr_groups,
+ .counter_bits = 48,
+ .check_event = ITS_PMU_EVENT_CTRL_TYPE,
+ .private = &hisi_its_v1_pmu_regs,
+};
+
+static const struct acpi_device_id hisi_its_pmu_ids[] = {
+ { "HISI0591", (kernel_ulong_t) &hisi_its_v1 },
+ { }
+};
+MODULE_DEVICE_TABLE(acpi, hisi_its_pmu_ids);
+
+static struct platform_driver hisi_its_pmu_driver = {
+ .driver = {
+ .name = "hisi_its_pmu",
+ .acpi_match_table = hisi_its_pmu_ids,
+ .suppress_bind_attrs = true,
+ },
+ .probe = hisi_its_pmu_probe,
+};
+
+static int __init hisi_its_pmu_module_init(void)
+{
+ int ret = cpuhp_setup_state_multi(CPUHP_AP_ONLINE_DYN,
+ "perf/hisi/its:online",
+ hisi_uncore_pmu_online_cpu,
+ hisi_uncore_pmu_offline_cpu);
+ if (ret < 0) {
+ pr_err("hisi_its_pmu: Fail to setup cpuhp callbacks, ret = %d\n", ret);
+ return ret;
+ }
+ hisi_its_pmu_cpuhp_state = ret;
+
+ ret = platform_driver_register(&hisi_its_pmu_driver);
+ if (ret)
+ cpuhp_remove_multi_state(hisi_its_pmu_cpuhp_state);
+
+ return ret;
+}
+module_init(hisi_its_pmu_module_init);
+
+static void __exit hisi_its_pmu_module_exit(void)
+{
+ platform_driver_unregister(&hisi_its_pmu_driver);
+ cpuhp_remove_multi_state(hisi_its_pmu_cpuhp_state);
+}
+module_exit(hisi_its_pmu_module_exit);
+
+MODULE_IMPORT_NS("HISI_PMU");
+MODULE_DESCRIPTION("HiSilicon SoC Uncore ITS PMU driver");
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Yushan Wang <wangyushan12@huawei.com>");
--
2.33.0
^ permalink raw reply related
* [PATCH v2 2/2] drivers/perf: hisi: Add new function for HiSilicon MN PMU driver
From: Yushan Wang @ 2026-06-12 9:38 UTC (permalink / raw)
To: will, mark.rutland, robin.murphy, linux-arm-kernel, linux-kernel
Cc: fanghao11, linuxarm, liuyonglong, prime.zeng, wangzhou1,
wangyushan12
In-Reply-To: <20260612093812.1249049-1-wangyushan12@huawei.com>
From: Yifan Wu <wuyifan50@huawei.com>
MN (Miscellaneous Node) is a hybrid node in ARM CHI. The MN PMU driver
using the HiSilicon uncore PMU framework.
On HiSilicon HIP13 platform, cycle event is supported on MN PMU. The
cycle event is exposed directly in driver and some variables shall be
added suffix to distinguish the version.
Signed-off-by: Yifan Wu <wuyifan50@huawei.com>
Signed-off-by: Yushan Wang <wangyushan12@huawei.com>
---
drivers/perf/hisilicon/hisi_uncore_mn_pmu.c | 61 +++++++++++++++++++--
1 file changed, 55 insertions(+), 6 deletions(-)
diff --git a/drivers/perf/hisilicon/hisi_uncore_mn_pmu.c b/drivers/perf/hisilicon/hisi_uncore_mn_pmu.c
index 4df4eebe243e..cdd5a1591408 100644
--- a/drivers/perf/hisilicon/hisi_uncore_mn_pmu.c
+++ b/drivers/perf/hisilicon/hisi_uncore_mn_pmu.c
@@ -192,7 +192,7 @@ static const struct attribute_group hisi_mn_pmu_format_group = {
.attrs = hisi_mn_pmu_format_attr,
};
-static struct attribute *hisi_mn_pmu_events_attr[] = {
+static struct attribute *hisi_mn_pmu_events_attr_v1[] = {
HISI_PMU_EVENT_ATTR(req_eobarrier_num, 0x00),
HISI_PMU_EVENT_ATTR(req_ecbarrier_num, 0x01),
HISI_PMU_EVENT_ATTR(req_dvmop_num, 0x02),
@@ -219,14 +219,55 @@ static struct attribute *hisi_mn_pmu_events_attr[] = {
NULL
};
-static const struct attribute_group hisi_mn_pmu_events_group = {
+static const struct attribute_group hisi_mn_pmu_events_group_v1 = {
.name = "events",
- .attrs = hisi_mn_pmu_events_attr,
+ .attrs = hisi_mn_pmu_events_attr_v1,
};
-static const struct attribute_group *hisi_mn_pmu_attr_groups[] = {
+static const struct attribute_group *hisi_mn_pmu_attr_groups_v1[] = {
&hisi_mn_pmu_format_group,
- &hisi_mn_pmu_events_group,
+ &hisi_mn_pmu_events_group_v1,
+ &hisi_pmu_cpumask_attr_group,
+ &hisi_pmu_identifier_group,
+ NULL
+};
+
+static struct attribute *hisi_mn_pmu_events_attr_v2[] = {
+ HISI_PMU_EVENT_ATTR(req_eobarrier_num, 0x00),
+ HISI_PMU_EVENT_ATTR(req_ecbarrier_num, 0x01),
+ HISI_PMU_EVENT_ATTR(req_dvmop_num, 0x02),
+ HISI_PMU_EVENT_ATTR(req_dvmsync_num, 0x03),
+ HISI_PMU_EVENT_ATTR(req_retry_num, 0x04),
+ HISI_PMU_EVENT_ATTR(req_writenosnp_num, 0x05),
+ HISI_PMU_EVENT_ATTR(req_readnosnp_num, 0x06),
+ HISI_PMU_EVENT_ATTR(snp_dvm_num, 0x07),
+ HISI_PMU_EVENT_ATTR(snp_dvmsync_num, 0x08),
+ HISI_PMU_EVENT_ATTR(l3t_req_dvm_num, 0x09),
+ HISI_PMU_EVENT_ATTR(l3t_req_dvmsync_num, 0x0A),
+ HISI_PMU_EVENT_ATTR(mn_req_dvm_num, 0x0B),
+ HISI_PMU_EVENT_ATTR(mn_req_dvmsync_num, 0x0C),
+ HISI_PMU_EVENT_ATTR(pa_req_dvm_num, 0x0D),
+ HISI_PMU_EVENT_ATTR(pa_req_dvmsync_num, 0x0E),
+ HISI_PMU_EVENT_ATTR(cycles, 0x0F),
+ HISI_PMU_EVENT_ATTR(snp_dvm_latency, 0x80),
+ HISI_PMU_EVENT_ATTR(snp_dvmsync_latency, 0x81),
+ HISI_PMU_EVENT_ATTR(l3t_req_dvm_latency, 0x82),
+ HISI_PMU_EVENT_ATTR(l3t_req_dvmsync_latency, 0x83),
+ HISI_PMU_EVENT_ATTR(mn_req_dvm_latency, 0x84),
+ HISI_PMU_EVENT_ATTR(mn_req_dvmsync_latency, 0x85),
+ HISI_PMU_EVENT_ATTR(pa_req_dvm_latency, 0x86),
+ HISI_PMU_EVENT_ATTR(pa_req_dvmsync_latency, 0x87),
+ NULL
+};
+
+static const struct attribute_group hisi_mn_pmu_events_group_v2 = {
+ .name = "events",
+ .attrs = hisi_mn_pmu_events_attr_v2,
+};
+
+static const struct attribute_group *hisi_mn_pmu_attr_groups_v2[] = {
+ &hisi_mn_pmu_format_group,
+ &hisi_mn_pmu_events_group_v2,
&hisi_pmu_cpumask_attr_group,
&hisi_pmu_identifier_group,
NULL
@@ -351,7 +392,14 @@ static struct hisi_mn_pmu_regs hisi_mn_v1_pmu_regs = {
};
static const struct hisi_pmu_dev_info hisi_mn_v1 = {
- .attr_groups = hisi_mn_pmu_attr_groups,
+ .attr_groups = hisi_mn_pmu_attr_groups_v1,
+ .counter_bits = 48,
+ .check_event = HISI_MN_EVTYPE_MASK,
+ .private = &hisi_mn_v1_pmu_regs,
+};
+
+static const struct hisi_pmu_dev_info hisi_mn_v2 = {
+ .attr_groups = hisi_mn_pmu_attr_groups_v2,
.counter_bits = 48,
.check_event = HISI_MN_EVTYPE_MASK,
.private = &hisi_mn_v1_pmu_regs,
@@ -359,6 +407,7 @@ static const struct hisi_pmu_dev_info hisi_mn_v1 = {
static const struct acpi_device_id hisi_mn_pmu_acpi_match[] = {
{ "HISI0222", (kernel_ulong_t) &hisi_mn_v1 },
+ { "HISI0224", (kernel_ulong_t) &hisi_mn_v2 },
{ }
};
MODULE_DEVICE_TABLE(acpi, hisi_mn_pmu_acpi_match);
--
2.33.0
^ permalink raw reply related
* Re: [PATCH] ARM: multi_v7_defconfig: Enable dma-buf heaps
From: Arnd Bergmann @ 2026-06-12 9:41 UTC (permalink / raw)
To: Maxime Ripard
Cc: Krzysztof Kozlowski, Alexandre Belloni, Linus Walleij,
Drew Fustini, linux-arm-kernel, soc, Andrew Davis
In-Reply-To: <20260612-indigo-sparrow-of-action-d2bcbe@houat>
On Fri, Jun 12, 2026, at 10:33, Maxime Ripard wrote:
> On Wed, May 27, 2026 at 10:50:02AM +0200, Arnd Bergmann wrote:
>> On Wed, May 27, 2026, at 10:41, Maxime Ripard wrote:
>>
>> I'd like to wait until we have resolved the build regression
>> from the earlier patch[1][2]. I don't have a strong opinion on how
>> to resolve it, but at least for now Christoph is asking to have
>> your change reverted.
>
> I believe it's now fixed, even though not through a revert, and is on
> its way to Linus:
> https://lore.kernel.org/dri-devel/c7a9dbb0-a5c8-4e67-904e-1a52b3de9bb4@linux.intel.com/
>
> arch/arm doesn't select ARCH_HAS_MEM_ENCRYPT afaik, so this patch can be
> applied as is I think?
Yes, I've added it to the soc/defconfig branch already, though
the automatic notification apparently did not trigger.
Arnd
^ permalink raw reply
* Re: [PATCH] net: macb: add TX stall timeout callback to recover from lost TSTART write
From: Théo Lebrun @ 2026-06-12 9:45 UTC (permalink / raw)
To: Andrea della Porta, netdev, Nicolas Ferre, Claudiu Beznea,
Andrew Lunn, David S . Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, linux-kernel, linux-arm-kernel, linux-rpi-kernel
Cc: Lukasz Raczylo, Steffen Jaeckel
In-Reply-To: <771b8faeaee1fce4a84a5ba2661d60b35a65a6d5.1781253818.git.andrea.porta@suse.com>
Hello Andrea,
On Fri Jun 12, 2026 at 11:01 AM CEST, Andrea della Porta wrote:
> From: Lukasz Raczylo <lukasz@raczylo.com>
>
> The MACB found in the Raspberry Pi RP1 suffers from sporadic stalls on
> the TX queue.
> While the exact root cause is not yet fully understood, it is likely
> related to a hardware issue where a TSTART write to the NCR register
> is missed, preventing the transmission from being kicked off.
>
> Implement a timeout callback to handle TX queue stalls, triggering the
> existing restart mechanism to recover.
>
> Link: https://lore.kernel.org/all/20260514215459.36109-1-lukasz@raczylo.com/
> Fixes: dc110d1b23564 ("net: cadence: macb: Add support for Raspberry Pi RP1 ethernet controller")
> Signed-off-by: Lukasz Raczylo <lukasz@raczylo.com>
> Co-developed-by: Steffen Jaeckel <sjaeckel@suse.de>
> Signed-off-by: Steffen Jaeckel <sjaeckel@suse.de>
> Co-developed-by: Andrea della Porta <andrea.porta@suse.com>
> Signed-off-by: Andrea della Porta <andrea.porta@suse.com>
> ---
> drivers/net/ethernet/cadence/macb_main.c | 11 +++++++++++
> 1 file changed, 11 insertions(+)
>
> diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c
> index a12aa21244e83..615da65d5d68d 100644
> --- a/drivers/net/ethernet/cadence/macb_main.c
> +++ b/drivers/net/ethernet/cadence/macb_main.c
> @@ -4522,6 +4522,16 @@ static int macb_setup_tc(struct net_device *dev, enum tc_setup_type type,
> }
> }
>
> +static void macb_tx_timeout(struct net_device *dev, unsigned int q)
> +{
> + struct macb *bp = netdev_priv(dev);
> +
> + if (net_ratelimit())
> + netdev_err(dev, "TX stall detected, re-kicking TSTART\n");
Is this standard? It looks odd.
> + dev->stats.tx_errors++;
I am surprised by this. `tx_errors` would ideally be one per packet that
didn't get sent. Here we increment it once per queue that stalled.
I have a series to address stats issue (and use netdev_stat_ops API).
It is a follow-up to this:
https://lore.kernel.org/netdev/20260428-macb-drop-tx-v2-0-647f5199d8df@bootlin.com/
Also this is per-device shared data and we access it without
synchronisation.
Let's drop this increment.
> + macb_tx_restart(&bp->queues[q]);
> +}
Regards,
--
Théo Lebrun, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply
* Re: [PATCH v2] net: airoha: Fix error handling in airoha_ppe_flush_sram_entries()
From: Lorenzo Bianconi @ 2026-06-12 9:48 UTC (permalink / raw)
To: Wayen.Yan; +Cc: netdev, linux-arm-kernel, linux-mediatek
In-Reply-To: <6a2bd37a.4034e349.1b41bb.1caf@mx.google.com>
[-- Attachment #1: Type: text/plain, Size: 1694 bytes --]
> In airoha_ppe_flush_sram_entries(), the outer "err" variable was never
> updated when the inner loop variable shadowed it, causing the function
> to always return 0 even when airoha_ppe_foe_commit_sram_entry() fails.
>
> Drop the outer "err" variable and return directly on error, propagating
> the error code from airoha_ppe_foe_commit_sram_entry() correctly.
>
> Fixes: 620d7b91aadb ("net: airoha: ppe: Flush PPE SRAM table during PPE setup")
> Link: https://lore.kernel.org/netdev/6a2b40e4.4dd82583.3a5c46.e52f@mx.google.com/
> Signed-off-by: Wayen.Yan <win847@gmail.com>
Acked-by: Lorenzo Bianconi <lorenzo@kernel.org>
> ---
> drivers/net/ethernet/airoha/airoha_ppe.c | 6 +++---
> 1 file changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/net/ethernet/airoha/airoha_ppe.c b/drivers/net/ethernet/airoha/airoha_ppe.c
> index 5c9dff6..a124f15 100644
> --- a/drivers/net/ethernet/airoha/airoha_ppe.c
> +++ b/drivers/net/ethernet/airoha/airoha_ppe.c
> @@ -1330,7 +1330,7 @@ static int airoha_ppe_flush_sram_entries(struct airoha_ppe *ppe)
> {
> u32 sram_num_entries = airoha_ppe_get_total_sram_num_entries(ppe);
> struct airoha_foe_entry *hwe = ppe->foe;
> - int i, err = 0;
> + int i;
>
> for (i = 0; i < sram_num_entries; i++) {
> int err;
> @@ -1338,10 +1338,10 @@ static int airoha_ppe_flush_sram_entries(struct airoha_ppe *ppe)
> memset(&hwe[i], 0, sizeof(*hwe));
> err = airoha_ppe_foe_commit_sram_entry(ppe, i);
> if (err)
> - break;
> + return err;
> }
>
> - return err;
> + return 0;
> }
>
> static struct airoha_npu *airoha_ppe_npu_get(struct airoha_eth *eth)
> --
> 2.51.0
>
>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply
* [PATCH] v2 Documentation: arch: fix brackets
From: Manuel Ebner @ 2026-06-12 9:54 UTC (permalink / raw)
To: Vineet Gupta, Jonathan Corbet, Shuah Khan, Krzysztof Kozlowski,
Peter Griffin, Alim Akhtar, Catalin Marinas, Will Deacon,
Madhavan Srinivasan, Michael Ellerman, Nicholas Piggin,
Christophe Leroy, open list:SYNOPSYS ARC ARCHITECTURE,
open list:DOCUMENTATION, open list,
moderated list:ARM/SAMSUNG S3C, S5P AND EXYNOS ARM ARCHITECTURES,
open list:ARM/SAMSUNG S3C, S5P AND EXYNOS ARM ARCHITECTURES,
open list:LINUX FOR POWERPC (32-BIT AND 64-BIT)
Cc: Manuel Ebner, Randy Dunlap
Add missing and remove needless parentheses, brackets and curly braces.
Fix typos.
Signed-off-by: Manuel Ebner <manuelebner@mailbox.org>
Reviewed-by: Randy Dunlap <rdunlap@infradead.org>
---
[v1] -> [v2]
"(i.e cache geometries)" -> "(e.g., cache geometries)"
"Excer[t" -> "Excerpt"
add Reviewed-by: Randy Dunlap
fixed my own typos.
---
Documentation/arch/arc/arc.rst | 2 +-
.../arm/samsung/clksrc-change-registers.awk | 2 +-
Documentation/arch/arm/vlocks.rst | 4 ++--
.../arch/arm64/memory-tagging-extension.rst | 2 +-
Documentation/arch/powerpc/vas-api.rst | 2 +-
Documentation/arch/sparc/oradax/dax-hv-api.txt | 18 +++++++++---------
Documentation/arch/sparc/oradax/oracle-dax.rst | 2 +-
Documentation/arch/x86/x86_64/fsgs.rst | 4 ++--
8 files changed, 18 insertions(+), 18 deletions(-)
diff --git a/Documentation/arch/arc/arc.rst b/Documentation/arch/arc/arc.rst
index 6c4d978f3f4e..5923dee37a98 100644
--- a/Documentation/arch/arc/arc.rst
+++ b/Documentation/arch/arc/arc.rst
@@ -36,7 +36,7 @@ Important note on ARC processors configurability
ARC processors are highly configurable and several configurable options
are supported in Linux. Some options are transparent to software
-(i.e cache geometries, some can be detected at runtime and configured
+(e.g., cache geometries), some can be detected at runtime and configured
and used accordingly, while some need to be explicitly selected or configured
in the kernel's configuration utility (AKA "make menuconfig").
diff --git a/Documentation/arch/arm/samsung/clksrc-change-registers.awk b/Documentation/arch/arm/samsung/clksrc-change-registers.awk
index 7be1b8aa7cd9..48464397088c 100755
--- a/Documentation/arch/arm/samsung/clksrc-change-registers.awk
+++ b/Documentation/arch/arm/samsung/clksrc-change-registers.awk
@@ -163,4 +163,4 @@ BEGIN {
}
}
-// && ! /clksrc_clk.*=.*{/ { print $0 }
+// && ! /clksrc_clk.*=.*{/ { print $0 }}
diff --git a/Documentation/arch/arm/vlocks.rst b/Documentation/arch/arm/vlocks.rst
index 737aa8661a21..b0ac33263086 100644
--- a/Documentation/arch/arm/vlocks.rst
+++ b/Documentation/arch/arm/vlocks.rst
@@ -102,10 +102,10 @@ Features and limitations
if (I_won) {
/* we won the town election, let's go for the state */
my_state = states[(this_cpu >> 8) & 0xf];
- I_won = vlock_lock(my_state, this_cpu & 0xf));
+ I_won = vlock_lock(my_state, this_cpu & 0xf);
if (I_won) {
/* and so on */
- I_won = vlock_lock(the_whole_country, this_cpu & 0xf];
+ I_won = vlock_lock(the_whole_country, this_cpu & 0xf);
if (I_won) {
/* ... */
}
diff --git a/Documentation/arch/arm64/memory-tagging-extension.rst b/Documentation/arch/arm64/memory-tagging-extension.rst
index 679725030731..e6fe428f0e2a 100644
--- a/Documentation/arch/arm64/memory-tagging-extension.rst
+++ b/Documentation/arch/arm64/memory-tagging-extension.rst
@@ -222,7 +222,7 @@ programs should not retry in case of a non-zero system call return.
address ABI control and MTE configuration of a process as per the
``prctl()`` options described in
Documentation/arch/arm64/tagged-address-abi.rst and above. The corresponding
-``regset`` is 1 element of 8 bytes (``sizeof(long))``).
+``regset`` is 1 element of 8 bytes (``sizeof(long)``).
Core dump support
-----------------
diff --git a/Documentation/arch/powerpc/vas-api.rst b/Documentation/arch/powerpc/vas-api.rst
index a9625a2fa0c6..1d0d055356e3 100644
--- a/Documentation/arch/powerpc/vas-api.rst
+++ b/Documentation/arch/powerpc/vas-api.rst
@@ -293,7 +293,7 @@ Simple example
//Format CRB request with compression or
//uncompression
// Refer tests for vas_copy/vas_paste
- vas_copy((&crb, 0, 1);
+ vas_copy(&crb, 0, 1);
vas_paste(addr, 0, 1);
// Poll on csb.flags with timeout
// csb address is listed in CRB
diff --git a/Documentation/arch/sparc/oradax/dax-hv-api.txt b/Documentation/arch/sparc/oradax/dax-hv-api.txt
index ef1a4c2bf08b..49be62a9ce86 100644
--- a/Documentation/arch/sparc/oradax/dax-hv-api.txt
+++ b/Documentation/arch/sparc/oradax/dax-hv-api.txt
@@ -457,7 +457,7 @@ bits set, and terminate at a CCB that has the Conditional bit set, but not the P
Offset Size Field Description
Bits Field Description
[15:14] Secondary Input Element Size (see Section 36.2.1.1.4,
- “Secondary Input Element Size”
+ “Secondary Input Element Size”)
[13:10] Output Format (see Section 36.2.1.1.6, “Output Format”)
[9] Padding Direction selector: A value of 1 causes padding bytes
to be added to the left side of output elements. A value of 0
@@ -656,7 +656,7 @@ Offset Size Field Description
[18:16] Secondary Input Starting Offset (see Section 36.2.1.1.5, “Input
Element Offsets”)
[15:14] Secondary Input Element Size (see Section 36.2.1.1.4,
- “Secondary Input Element Size”
+ “Secondary Input Element Size”)
[13:10] Output Format (see Section 36.2.1.1.6, “Output Format”)
[9:5] Operand size for first scan criteria value. In a scan value
operation, this is one of two potential exact match values.
@@ -793,13 +793,13 @@ Offset Size Field Description
[18:16] Secondary Input Starting Offset (see Section 36.2.1.1.5, “Input
Element Offsets”)
[15:14] Secondary Input Element Size (see Section 36.2.1.1.4,
- “Secondary Input Element Size”
+ “Secondary Input Element Size”)
[13:10] Output Format (see Section 36.2.1.1.6, “Output Format”)
[9] Reserved
[8:0] Test value used for comparison against the most significant bits
in the input values, when using 2 or 3 byte input elements.
-8 8 Completion (same fields as Section 36.2.1.2, “Extract command”
-16 8 Primary Input (same fields as Section 36.2.1.2, “Extract command”
+8 8 Completion (same fields as Section 36.2.1.2, “Extract command”)
+16 8 Primary Input (same fields as Section 36.2.1.2, “Extract command”)
24 8 Data Access Control (same fields as Section 36.2.1.2, “Extract command”,
except Primary Input Length Format may not use the 0x0 value)
32 8 Secondary Input, if used by Primary Input Format. Same fields as Primary
@@ -880,7 +880,7 @@ Offset Size Field Description
[18:16] Secondary Input Starting Offset (see Section 36.2.1.1.5, “Input
Element Offsets”)
[15:14] Secondary Input Element Size (see Section 36.2.1.1.4,
- “Secondary Input Element Size”
+ “Secondary Input Element Size”)
524
@@ -895,8 +895,8 @@ Offset Size Field Description
causes padding bytes to be added to the right side of output
elements.
[8:0] Reserved
- 8 8 Completion (same fields as Section 36.2.1.2, “Extract command”
- 16 8 Primary Input (same fields as Section 36.2.1.2, “Extract command”
+ 8 8 Completion (same fields as Section 36.2.1.2, “Extract command”)
+ 16 8 Primary Input (same fields as Section 36.2.1.2, “Extract command”)
24 8 Data Access Control (same fields as Section 36.2.1.2, “Extract command”)
32 8 Secondary Bit Vector Input. Same fields as Primary Input.
40 8 Reserved
@@ -949,7 +949,7 @@ Offset Size Field Description
[31] If set, this CCB functions as a Sync command. If clear, this
CCB functions as a No-op command.
[30:0] Reserved
- 8 8 Completion (same fields as Section 36.2.1.2, “Extract command”
+ 8 8 Completion (same fields as Section 36.2.1.2, “Extract command”)
16 46 Reserved
36.2.2. CCB Completion Area
diff --git a/Documentation/arch/sparc/oradax/oracle-dax.rst b/Documentation/arch/sparc/oradax/oracle-dax.rst
index d1e14d572918..a5d53f240dc8 100644
--- a/Documentation/arch/sparc/oradax/oracle-dax.rst
+++ b/Documentation/arch/sparc/oradax/oracle-dax.rst
@@ -438,7 +438,7 @@ that in user land::
The output bitmap is ready for consumption immediately after the
completion status indicates success.
-Excer[t from UltraSPARC Virtual Machine Specification
+Excerpt from UltraSPARC Virtual Machine Specification
=====================================================
.. include:: dax-hv-api.txt
diff --git a/Documentation/arch/x86/x86_64/fsgs.rst b/Documentation/arch/x86/x86_64/fsgs.rst
index 6bda4d16d3f7..f8d483a7fb06 100644
--- a/Documentation/arch/x86/x86_64/fsgs.rst
+++ b/Documentation/arch/x86/x86_64/fsgs.rst
@@ -182,8 +182,8 @@ address spaces via an attribute based mechanism in Clang 2.6 and newer
versions:
==================================== =====================================
- __attribute__((address_space(256)) Variable is addressed relative to GS
- __attribute__((address_space(257)) Variable is addressed relative to FS
+ __attribute__(address_space(256)) Variable is addressed relative to GS
+ __attribute__(address_space(257)) Variable is addressed relative to FS
==================================== =====================================
FS/GS based addressing with inline assembly
--
2.54.0
^ permalink raw reply related
* [PATCH v2 2/3] perf: marvell: Add CN20K LLC-TAD PMU support
From: Geetha sowjanya @ 2026-06-12 9:57 UTC (permalink / raw)
To: linux-perf-users, linux-kernel, linux-arm-kernel, devicetree
Cc: mark.rutland, will, krzk+dt, gakula
In-Reply-To: <20260612095746.19679-1-gakula@marvell.com>
Add support for the LLC Tag-and-Data (TAD) PMU present in
Marvell CN20K SoCs.
The CN20K TAD PMU is based on the CN10K design but differs in the
layout of PFC/PRF register offsets relative to each TAD base, and
introduces additional events. These offsets are selected by the driver
based on the compatible string and are not described via DT properties.
Because of this, "marvell,cn10k-tad-pmu" cannot be used as a fallback
for CN20K, as it would result in incorrect register programming.
Add support for "marvell,cn20k-tad-pmu" by:
- Introducing a TAD_PMU_V3 profile with CN20K-specific register bases
- Extending the event map for new CN20K events
- Matching the PMU via OF and ACPI (MRVL000F)
Signed-off-by: Geetha sowjanya <gakula@marvell.com>
---
Changelog (since v1)
--------------------
- Hide V3-only events on CN10K via sysfs is_visible and reject them in
event_init.
- Use CN20K-specific MPAM PRF bits (MATCH_MPAMNS, partid << 10) for V3;
software partid is limited to nine bits so this does not collide with
the fixed bit at 25.
- Reset hwc->prev_count when starting counters so reads match cleared HW.
drivers/perf/marvell_cn10k_tad_pmu.c | 54 ++++++++++++++++++++++++++--
1 file changed, 52 insertions(+), 2 deletions(-)
diff --git a/drivers/perf/marvell_cn10k_tad_pmu.c b/drivers/perf/marvell_cn10k_tad_pmu.c
index af706b890bf1..e43598a52859 100644
--- a/drivers/perf/marvell_cn10k_tad_pmu.c
+++ b/drivers/perf/marvell_cn10k_tad_pmu.c
@@ -17,11 +17,14 @@
#define TAD_PRF_OFFSET 0x900
#define TAD_PFC_OFFSET 0x800
+#define TAD_PRF_NS_OFFSET 0x30900
+#define TAD_PFC_NS_OFFSET 0x30800
#define TAD_PFC(base, counter) ((base) | ((u64)(counter) << 3))
#define TAD_PRF(base, counter) ((base) | ((u64)(counter) << 3))
#define TAD_PRF_CNTSEL_MASK 0xFF
#define TAD_PRF_MATCH_PARTID BIT(8)
#define TAD_PRF_PARTID_NS BIT(10)
+#define TAD_PRF_MATCH_MPAMNS BIT(25)
/*
* config1: bits 0..8 MPAM partition id (including 0); bit 9 requests
* filtering for MPAM-capable events. All-zero config1 means no filter.
@@ -38,6 +41,7 @@ struct tad_region {
enum mrvl_tad_pmu_version {
TAD_PMU_V1 = 1,
TAD_PMU_V2,
+ TAD_PMU_V3,
};
struct tad_pmu_data {
@@ -85,8 +89,15 @@ static void tad_pmu_start_counter(struct tad_pmu *pmu,
if (use_mpam && event_idx > 0x19 && event_idx < 0x21) {
partid_filter = TAD_PRF_MATCH_PARTID | TAD_PRF_PARTID_NS |
((u64)partid << 11);
+
+ if (pdata->id == TAD_PMU_V3)
+ partid_filter = TAD_PRF_MATCH_PARTID | TAD_PRF_MATCH_MPAMNS |
+ ((u64)partid << 10);
}
+ /* CN10K support events 0:24*/
+ if (pdata->id == TAD_PMU_V1 && event_idx >= 0x25)
+ return;
for (i = 0; i < pmu->region_cnt; i++) {
reg_val = event_idx & 0xFF;
@@ -159,6 +170,7 @@ static void tad_pmu_event_counter_start(struct perf_event *event, int flags)
struct hw_perf_event *hwc = &event->hw;
hwc->state = 0;
+ local64_set(&hwc->prev_count, 0);
tad_pmu->ops->start_counter(tad_pmu, event);
}
@@ -216,6 +228,8 @@ static int tad_pmu_event_init(struct perf_event *event)
if (cfg1)
return -EINVAL;
} else {
+ if (pdata->id == TAD_PMU_V1 && event_idx >= 0x25)
+ return -EINVAL;
if ((cfg1 & GENMASK(8, 0)) && !(cfg1 & TAD_PARTID_FILTER_EN))
return -EINVAL;
if (cfg1 & TAD_PARTID_FILTER_EN) {
@@ -242,6 +256,22 @@ static ssize_t tad_pmu_event_show(struct device *dev,
return sysfs_emit(page, "event=0x%02llx\n", pmu_attr->id);
}
+static umode_t tad_pmu_event_attr_is_visible(struct kobject *kobj,
+ struct attribute *attr, int unused)
+{
+ struct pmu *pmu = dev_get_drvdata(kobj_to_dev(kobj));
+ struct tad_pmu *t = to_tad_pmu(pmu);
+ struct device_attribute *da = container_of(attr, struct device_attribute,
+ attr);
+ struct perf_pmu_events_attr *e = container_of(da, struct perf_pmu_events_attr,
+ attr);
+ u64 id = e->id;
+
+ if (t->pdata->id != TAD_PMU_V3 && id >= 0x25)
+ return 0;
+ return attr->mode;
+}
+
#define TAD_PMU_EVENT_ATTR(name, config) \
PMU_EVENT_ATTR_ID(name, tad_pmu_event_show, config)
@@ -283,12 +313,25 @@ static struct attribute *tad_pmu_event_attrs[] = {
TAD_PMU_EVENT_ATTR(tad_dat_rd_byp, 0x22),
TAD_PMU_EVENT_ATTR(tad_ifb_occ, 0x23),
TAD_PMU_EVENT_ATTR(tad_req_occ, 0x24),
+ TAD_PMU_EVENT_ATTR(tad_req_msh_out_dtg_evict, 0x25),
+ TAD_PMU_EVENT_ATTR(tad_req_msh_out_ltg_evict, 0x26),
+ TAD_PMU_EVENT_ATTR(tad_rsp_msh_out_mpam, 0x28),
+ TAD_PMU_EVENT_ATTR(tad_replays, 0x29),
+ TAD_PMU_EVENT_ATTR(tad_req_byp0, 0x2a),
+ TAD_PMU_EVENT_ATTR(tad_req_byp1, 0x2b),
+ TAD_PMU_EVENT_ATTR(tad_txreq_byp, 0x2c),
+ TAD_PMU_EVENT_ATTR(tad_time_in_dslp, 0x2d),
+ TAD_PMU_EVENT_ATTR(tad_time_elapsed, 0x2e),
+ TAD_PMU_EVENT_ATTR(tad_req_msh_out_dss_rd_128mrg, 0x2f),
+ TAD_PMU_EVENT_ATTR(tad_req_msh_out_dss_wr_128mrg, 0x30),
+ TAD_PMU_EVENT_ATTR(tad_tot_cycle, 0xff),
NULL
};
static const struct attribute_group tad_pmu_events_attr_group = {
.name = "events",
.attrs = tad_pmu_event_attrs,
+ .is_visible = tad_pmu_event_attr_is_visible,
};
static struct attribute *ody_tad_pmu_event_attrs[] = {
@@ -474,7 +517,7 @@ static int tad_pmu_probe(struct platform_device *pdev)
.read = tad_pmu_event_counter_read,
};
- if (version == TAD_PMU_V1) {
+ if (version == TAD_PMU_V1 || version == TAD_PMU_V3) {
tad_pmu->pmu.attr_groups = tad_pmu_attr_groups;
tad_pmu->ops = &tad_pmu_ops;
} else {
@@ -517,6 +560,11 @@ static const struct tad_pmu_data tad_pmu_data = {
.tad_pfc_offset = TAD_PFC_OFFSET,
};
+static const struct tad_pmu_data tad_pmu_cn20k_data = {
+ .id = TAD_PMU_V3,
+ .tad_prf_offset = TAD_PRF_NS_OFFSET,
+ .tad_pfc_offset = TAD_PFC_NS_OFFSET,
+};
#endif
#ifdef CONFIG_ACPI
@@ -530,6 +578,7 @@ static const struct tad_pmu_data tad_pmu_v2_data = {
#ifdef CONFIG_OF
static const struct of_device_id tad_pmu_of_match[] = {
{ .compatible = "marvell,cn10k-tad-pmu", .data = &tad_pmu_data },
+ { .compatible = "marvell,cn20k-tad-pmu", .data = &tad_pmu_cn20k_data },
{},
};
#endif
@@ -538,6 +587,7 @@ static const struct of_device_id tad_pmu_of_match[] = {
static const struct acpi_device_id tad_pmu_acpi_match[] = {
{"MRVL000B", (kernel_ulong_t)&tad_pmu_data},
{"MRVL000D", (kernel_ulong_t)&tad_pmu_v2_data},
+ {"MRVL000F", (kernel_ulong_t)&tad_pmu_cn20k_data},
{},
};
MODULE_DEVICE_TABLE(acpi, tad_pmu_acpi_match);
@@ -599,6 +649,6 @@ static void __exit tad_pmu_exit(void)
module_init(tad_pmu_init);
module_exit(tad_pmu_exit);
-MODULE_DESCRIPTION("Marvell CN10K LLC-TAD perf driver");
+MODULE_DESCRIPTION("Marvell CN10K/CN20K LLC-TAD perf driver");
MODULE_AUTHOR("Bhaskara Budiredla <bbudiredla@marvell.com>");
MODULE_LICENSE("GPL v2");
--
2.25.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