* Re: [PATCH RFC bpf-next 1/8] kasan: expose generic kasan helpers
From: Alexei Starovoitov @ 2026-04-14 14:36 UTC (permalink / raw)
To: Alexis Lothoré
Cc: Andrey Konovalov, Alexei Starovoitov, Daniel Borkmann,
Andrii Nakryiko, Martin KaFai Lau, Eduard Zingerman,
Kumar Kartikeya Dwivedi, Song Liu, Yonghong Song, Jiri Olsa,
John Fastabend, David S. Miller, David Ahern, Thomas Gleixner,
Ingo Molnar, Borislav Petkov, Dave Hansen, X86 ML, H. Peter Anvin,
Shuah Khan, Maxime Coquelin, Alexandre Torgue, Andrey Ryabinin,
Alexander Potapenko, Dmitry Vyukov, Vincenzo Frascino,
Andrew Morton, ebpf, Bastien Curutchet, Thomas Petazzoni,
Xu Kuohai, bpf, LKML, Network Development,
open list:KERNEL SELFTEST FRAMEWORK, linux-stm32,
linux-arm-kernel, kasan-dev, linux-mm
In-Reply-To: <DHSWK17EZUDP.GIJ6BX2NFR6U@bootlin.com>
On Tue, Apr 14, 2026 at 6:13 AM Alexis Lothoré
<alexis.lothore@bootlin.com> wrote:
>
> Hi Andrey, thanks for the prompt review !
>
> On Tue Apr 14, 2026 at 12:19 AM CEST, Andrey Konovalov wrote:
> > On Mon, Apr 13, 2026 at 8:29 PM Alexis Lothoré (eBPF Foundation)
> > <alexis.lothore@bootlin.com> wrote:
> >>
>
> [...]
>
> >> +#ifdef CONFIG_KASAN_GENERIC
> >> +void __asan_load1(void *p);
> >> +void __asan_store1(void *p);
> >> +void __asan_load2(void *p);
> >> +void __asan_store2(void *p);
> >> +void __asan_load4(void *p);
> >> +void __asan_store4(void *p);
> >> +void __asan_load8(void *p);
> >> +void __asan_store8(void *p);
> >> +void __asan_load16(void *p);
> >> +void __asan_store16(void *p);
> >> +#endif /* CONFIG_KASAN_GENERIC */
> >
> > This looks ugly, let's not do this unless it's really required.
> >
> > You can just use kasan_check_read/write() instead - these are public
> > wrappers around the same shadow memory checking functions. And they
> > also work with the SW_TAGS mode, in case the BPF would want to use
> > that mode at some point. (For HW_TAGS, we only have kasan_check_byte()
> > that checks a single byte, but it can be extended in the future if
> > required to be used by BPF.)
>
> ACK, I'll try to use those kasan_check_read and kasan_check_write rather
> than __asan_{load,store}X.
No. The performance penalty will be too high.
hw_tags won't work without corresponding JIT work.
I see no point sacrificing performance for aesthetics.
__asan_load/storeX is what compilers emit.
In that sense JIT is a compiler it should emit exactly the same.
^ permalink raw reply
* Re: [PATCH net-next] net: stmmac: enable RPS and RBU interrupts
From: Russell King (Oracle) @ 2026-04-14 14:13 UTC (permalink / raw)
To: Sam Edwards
Cc: Jakub Kicinski, Andrew Lunn, Alexandre Torgue, Andrew Lunn,
David S. Miller, Eric Dumazet,
moderated list:BROADCOM BCM2711/BCM2835 ARM ARCHITECTURE,
linux-stm32, Linux Network Development Mailing List, Paolo Abeni
In-Reply-To: <CAH5Ym4i7VV53hQGY3AjAUW3B8g_ffgmw69kPhPrk2CmcRbguuQ@mail.gmail.com>
Hi Sam,
Most of this email was written this morning, but I didn't have a chance
to finish nor send it due to how busy I am.
I had also written a separate reply last night with detailed results of
what I was seeing but didn't/haven't got around to sending it. Not
currently sure whether I saved it as draft or got rid of it yet.
On Mon, Apr 13, 2026 at 02:54:30PM -0700, Sam Edwards wrote:
> On Mon, Apr 13, 2026, 11:49 Russell King (Oracle) <linux@armlinux.org.uk> wrote:
> >
> > On Mon, Apr 13, 2026 at 11:02:22AM -0700, Jakub Kicinski wrote:
> > > On Fri, 10 Apr 2026 14:07:51 +0100 Russell King (Oracle) wrote:
> > > > Since we are seeing receive buffer exhaustion on several platforms,
> > > > let's enable the interrupts so the statistics we publish via ethtool -S
> > > > actually work to aid diagnosis. I've been in two minds about whether
> > > > to send this patch, but given the problems with stmmac at the moment,
> > > > I think it should be merged.
> > >
> > > Sorry for a under-research response but wasn't there are person trying
> > > to fix the OOM starvation issue? Who was supposed to add a timer?
> > > Is your problem also OOM related or do you suspect something else?
> >
> > It is not OOM related. I have this patch applied:
> >
> > diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> > index 131ea887bedc..614d0e10e3e6 100644
> > --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> > +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> > @@ -5095,14 +5095,18 @@ static inline void stmmac_rx_refill(struct stmmac_priv *priv, u32 queue)
> >
> > if (!buf->page) {
> > buf->page = page_pool_alloc_pages(rx_q->page_pool, gfp);
> > - if (!buf->page)
> > + if (!buf->page) {
> > + netdev_err(priv->dev, "q%u: no buffer 1\n", queue);
> > break;
> > + }
> > }
> >
> > if (priv->sph_active && !buf->sec_page) {
> > buf->sec_page = page_pool_alloc_pages(rx_q->page_pool, gfp);
> > - if (!buf->sec_page)
> > + if (!buf->sec_page) {
> > + netdev_err(priv->dev, "q%u: no buffer 2\n", queue);
> > break;
> > + }
> >
> > buf->sec_addr = page_pool_get_dma_addr(buf->sec_page);
> > }
> >
> > and it is silent, so we are not suffering starvation of buffers.
> >
> > However, the hardware hangs during iperf3, and because it triggers the
> > MAC to stream PAUSE frames, and my network uses Netgear GS108 and GS116
> > unmanaged switches that always use flow-control between them (there's no
> > way not to) it takes down the entire network - as we've discussed
> > before. So, this problem is pretty fatal to the *entire* network.
> >
> > With this patch, the existing statistical counters for this condition
> > are incremented, and thus users can use ethtool -S to see what happened
> > and report whether they are seeing the same issue.
> >
> > Without this patch applied, there are no diagnostics from stmmac that
> > report what the state is. ethtool -d doesn't list the appropriate
> > registers (as I suspect part of the problem is the number of queues
> > is somewhat dynamic - userspace can change that configuration through
> > ethtool).
> >
> > Thus, one has to resort to using devmem2 to find out what's happened.
> > That's not user friendly.
> >
> > For me, devmem2 shows:
> >
> > Channel 0 status register:
> > Value at address 0x02491160: 0x00000484
> > bit 10: ETI early transmit interrupt - set
> > bit 9 : RWT receive watchdog - clear
> > bit 8 : RPS receieve process stopped - clear
> > bit 7 : RBU receive buffer unavailable - set
> > bit 6 : RI receive interrupt - clear
> > bit 2 : TBU transmit buffer unavailable - set
> > bit 1 : TPS transmit process stopped - clear
> > bit 0 : TI transmit interrupt - clear
>
> Should that reset trigger be RPS, not RBU? My understanding of these
> status bits is RBU is just "RxDMA has failed to take a frame from the
> RxFIFO" while RPS is "the RxFIFO is full." That would make RBU our
> critical threshold to start proactively refilling, and RPS the "too
> late, we lose" threshold.
That's a fine theory, but look at the channel 0 status register above,
noting that any interrupts that are raised but not enabled remain set.
RPS is not set, so RPS is not being raised, only RBU when this
condition occurs.
> Thinking aloud: Do you suppose the RxDMA waits for a wakeup signal
> sent whenever a frame is added to RxFIFO? That might explain why the
> former never recovers once the latter is full: a manual wakeup needs
> to be sent whenever we resolve RBU. Does the .enable_dma_reception()
> op need to be implemented for dwmac5, or have you tried that already?
I've not found anything in the closest documentation I have. The Xavier
is Synopsys IP v5.0, whereas i.MX8M is v5.1 - and v5.1 compared to
previous versions reads the same for statements concerning recovering
from a RBU condition:
"In ring mode, the application should advance the Receive Descriptor
Tail Pointer register of a channel. This bit is set only when the DMA
owns the previous Rx descriptor."
I've tried expanding what happens when RBU fires, dumping some of the
receive state and the receive ring:
[ 55.766199] dwc-eth-dwmac 2490000.ethernet eth0: q0: receive buffer unavailable: cur_rx=309 dirty_rx=309 last_cur_rx=245 last_cur_rx_post=309 last_dirty_rx=245 count=64 budget=64
cur_rx == dirty_rx _should_ mean that we fully refilled the ring. These
are their values at the point the RBU interrupt fires.
last_cur_rx and last_dirty_rx are the values of cur_rx/dirty_rx when
stmmac_rx() was last entered.
last_cur_rx_post is the value of cur_rx when stmmac_rx() finished
looping but before we have refilled the ring.
count is the value of count just before stmmac_rx() returns, budget is
the limit at that point.
The patch that prints errors should we fail to allocate a buffer is in
place, none of those errors fire, so we are fully repopulating the ring
each time stmmac_rx() runs.
[ 55.766785] RX descriptor ring:
[ 55.766802] 000 [0x0000007fffffe000]: 0x0 0x12 0x0 0x340105ee
[ 55.766826] 001 [0x0000007fffffe010]: 0x0 0x12 0x0 0x340105ee
[ 55.766843] 002 [0x0000007fffffe020]: 0x0 0x12 0x0 0x340105ee
[ 55.766860] 003 [0x0000007fffffe030]: 0x0 0x12 0x0 0x340105ee
...
[ 55.772205] 308 [0x0000007ffffff340]: 0x0 0x12 0x0 0x340105ee
[ 55.772221] 309 [0x0000007ffffff350]: 0x0 0x12 0x0 0x340105ee
[ 55.772237] 310 [0x0000007ffffff360]: 0x0 0x12 0x0 0x340105ee
[ 55.772253] 311 [0x0000007ffffff370]: 0x0 0x12 0x0 0x340105ee
[ 55.772268] 312 [0x0000007ffffff380]: 0x0 0x12 0x0 0x340105ee
[ 55.772284] 313 [0x0000007ffffff390]: 0x0 0x12 0x0 0x340105ee
[ 55.772300] 314 [0x0000007ffffff3a0]: 0x0 0x12 0x0 0x340105ee
[ 55.772315] 315 [0x0000007ffffff3b0]: 0x0 0x12 0x0 0x340105ee
...
[ 55.775539] 511 [0x0000007ffffffff0]: 0x0 0x12 0x0 0x340105ee
Every ring entry contains the same RDES3 value, so it really is
completely full at the point RBU fires (bit 31 clear means software
owns the descriptor, and it's basically saying first/last segment,
RDES1 valid, buffer 1 length of 1518.
The Rx tail pointer register contains 0xfffff3a0 which is entry 314.
The current receive descriptor address is also 0xfffff3a0. Note that
these values were obtained some time after the RBU interrupt fired
(due to the time taken for devmem2 to access every stmmac register -
I have a script that dumps the entire stmmac register state via
devmem2.)
The other thing to note is that when looking at debugfs
stmmaceth/eth0/descriptor* (or whatever it's called, I don't have the
NX powered to look at the moment, and I didn't take a copy of it last
night) all tne descriptor entries are fully repopulated with buffers
and owned by the hardware.
I've tried using devmem2 to write to the rx tail pointer to kick it
back into action, but that changes nothing. I've tried writing the
next descriptor value and previous descriptor value, but that appears
to have no effect, it stedfastly remains stuck - and as that is the
documented recovery from RBU and there's no "receive demand" register
listed in dwmac v4 or v5 documentation, there seems to be no other
documented way.
The debug registers that I provided in my previous email suggest that
the MAC is waiting for a packet, and MTL's descriptor reader is idle
(I'm guessing it would only briefly change when the tail pointer is
updated.)
Note that I have augmented the driver with more dma_rmb() + dma_wmb()
in stmmac_rx(), dwmac4_wrback_get_rx_status(), and stmmac_rx_refill()
to ensure that reads and writes to the descriptor ring are correctly
ordered. While this generally allows iperf3 to run for a few more
seconds, it doesn't solve the problem - it is very rare for iperf3
to actually complete before stmmac has taken down my entire network.
I have noticed that on some occasions I see a small number of RBU
interrupts before it falls over.
I'm not going to have much time to look at this today due to further
appointments (I also didn't yesterday - only an hour in the morning
and a bit more time late in the evening/night.) I should have more
time during the rest of the week... but that may change.
From the above, it looks like NAPI/stmmac driver isn't keeping up with
the packet flow coming from an i.MX6 platform (which is limited to
around 470Mbps due to internal SoC bus limitations.)
I'll also mention that stmmac falls apart even more if I run iperf3 -c
-R against an x86 machine that is capable of saturating the network,
so much so that the arm-smmu IOMMU throws errors even after the stmmac
hardware has been soft-reset for addresses that were in the ring
*prior* to the soft-reset occuring (stmmac is soft-reset each time the
netdev is brought up.) The only recovery from that is to reboot -
down/up the interface just spews more IOMMU errors. I don't have the
details of that to hand and I don't have enough time to re-run that
test this morning. From what I remember, the transmit side also stops
processing descriptors (one can see them accumulate in the debugfs
file,) which eventually leads to the netdev watchdog firing.
It currently looks like the stmmac v5 EQoS IP works fine only under
light packet loads. If one puts any stress on it, then the hardware
totally falls apart. This may point to an issue with the AXI bus
configuration that is specific to this platform, but that requires
further investigation.
I'll mention again, in case anyone's forgotten, that these problems
pre-date any of my cleanups I've made to stmmac. From what I remember
they are reproducible with the kernels that are supplied as part of
the nVidia BSP. Again, as I don't have access to the nVidia platform
at the moment, I can't include the details in this email.
--
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 80Mbps down 10Mbps up. Decent connectivity at last!
^ permalink raw reply
* Re: [PATCH 3/3] MAINTAINERS: add Axiado SGPIO controller
From: Krzysztof Kozlowski @ 2026-04-14 14:12 UTC (permalink / raw)
To: Petar Stepanovic, Tzu-Hao Wei, Swark Yang, Prasad Bolisetty,
Linus Walleij, Bartosz Golaszewski, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Harshit Shah, SriNavmani A
Cc: linux-gpio, devicetree, linux-arm-kernel, linux-kernel
In-Reply-To: <20260414-axiado-ax3000-sgpio-controller-v1-3-b5c7e4c2e69b@axiado.com>
On 14/04/2026 15:48, Petar Stepanovic wrote:
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 67db88b04537..56835c0a1863 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -4234,6 +4234,15 @@ S: Maintained
> F: Documentation/devicetree/bindings/sound/axentia,*
> F: sound/soc/atmel/tse850-pcm5142.c
>
> +AXIADO SGPIO DRIVER
> +M: Petar Stepanovic <pstepanovic@axiado.com>
> +M: SriNavmani A <srinavmani@axiado.com>
> +M: Prasad Bolisetty <pbolisetty@axiado.com>
I also expect reviews from the remaining maintainers, especially in all
the trivialities like posting very old code patterns.
Best regards,
Krzysztof
^ permalink raw reply
* Re: [PATCH RFC] ACPI: processor: idle: Do not propagate acpi_processor_ffh_lpi_probe() -ENODEV
From: Sudeep Holla @ 2026-04-14 14:10 UTC (permalink / raw)
To: Breno Leitao
Cc: lihuisong (C), Rafael J. Wysocki, Sudeep Holla, Len Brown,
lpieralisi, catalin.marinas, will, Rafael J. Wysocki, linux-acpi,
linux-kernel, pjaroszynski, guohanjun, linux-arm-kernel, rmikey,
kernel-team
In-Reply-To: <ad48gItCwrC-ar34@gmail.com>
On Tue, Apr 14, 2026 at 06:14:19AM -0700, Breno Leitao wrote:
> Hello Sudeep,
>
> On Tue, Apr 14, 2026 at 01:25:53PM +0100, Sudeep Holla wrote:
> > So while I understand that the kernel did not report an error previously, that
> > does not mean the _LPI table is merely moot on this platform when it contains
> > only a WFI state.
>
> Can you clarify whether datacenter ARM systems are expected to expose
> deeper idle states beyond WFI in their _LPI tables?
>
Of course any system that prefers to save power when its idling must have
these _LPI deeper idle states.
> Backing up, I'm observing 72 pr_err() messages during boot on these
> hosts and trying to determine whether this indicates a firmware issue or
> if the kernel needs adjustment.
I consider this a firmware issue, but not a fatal one. What matters more is
the behavior after those errors are reported.
If you force success, either through your change or through the PSCI approach
suggested by lihuisong, then in practice you are only enabling a cpuidle
driver with a single usable state: WFI. That is not inherently wrong, but it
also does not provide much benefit.
When the idle task needs to enter an idle state, it will ask the cpuidle
framework to choose the appropriate state. In this case, however, the
framework has no real decision to make, because the only available state is
WFI. If that is all the platform can support, then the same result can be
achieved more efficiently without registering the cpuidle driver at all, by
falling back to `arch_cpu_idle()`, as I mentioned earlier.
--
Regards,
Sudeep
^ permalink raw reply
* [PATCH net v2] net: airoha: Wait for NPU PPE configuration to complete in airoha_ppe_offload_setup()
From: Lorenzo Bianconi @ 2026-04-14 14:08 UTC (permalink / raw)
To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Lorenzo Bianconi
Cc: linux-arm-kernel, linux-mediatek, netdev
In order to properly enable flowtable hw offloading, poll
REG_PPE_FLOW_CFG register in airoha_ppe_offload_setup routine and
wait for NPU PPE configuration triggered by ppe_init callback to complete
before running airoha_ppe_hw_init().
Fixes: 00a7678310fe3 ("net: airoha: Introduce flowtable offload support")
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
Changes in v2:
- Check for both REG_PPE_PPE_FLOW_CFG(0) and REG_PPE_PPE_FLOW_CFG(1) to
complete.
- Link to v1: https://lore.kernel.org/r/20260412-airoha-wait-for-npu-config-offload-setup-v1-1-f4e0aa2a5d85@kernel.org
---
drivers/net/ethernet/airoha/airoha_ppe.c | 28 ++++++++++++++++++++++++++++
1 file changed, 28 insertions(+)
diff --git a/drivers/net/ethernet/airoha/airoha_ppe.c b/drivers/net/ethernet/airoha/airoha_ppe.c
index 62cfffb4f0e5..684c8ae9576f 100644
--- a/drivers/net/ethernet/airoha/airoha_ppe.c
+++ b/drivers/net/ethernet/airoha/airoha_ppe.c
@@ -1335,6 +1335,29 @@ static struct airoha_npu *airoha_ppe_npu_get(struct airoha_eth *eth)
return npu;
}
+static int airoha_ppe_wait_for_npu_init(struct airoha_eth *eth)
+{
+ int err;
+ u32 val;
+
+ /* PPE_FLOW_CFG default register value is 0. Since we reset FE
+ * during the device probe we can just check the configured value
+ * is not 0 here.
+ */
+ err = read_poll_timeout(airoha_fe_rr, val, val, USEC_PER_MSEC,
+ 100 * USEC_PER_MSEC, false, eth,
+ REG_PPE_PPE_FLOW_CFG(0));
+ if (err)
+ return err;
+
+ if (airoha_ppe_is_enabled(eth, 1))
+ err = read_poll_timeout(airoha_fe_rr, val, val, USEC_PER_MSEC,
+ 100 * USEC_PER_MSEC, false, eth,
+ REG_PPE_PPE_FLOW_CFG(1));
+
+ return err;
+}
+
static int airoha_ppe_offload_setup(struct airoha_eth *eth)
{
struct airoha_npu *npu = airoha_ppe_npu_get(eth);
@@ -1348,6 +1371,11 @@ static int airoha_ppe_offload_setup(struct airoha_eth *eth)
if (err)
goto error_npu_put;
+ /* Wait for NPU PPE configuration to complete */
+ err = airoha_ppe_wait_for_npu_init(eth);
+ if (err)
+ goto error_npu_put;
+
ppe_num_stats_entries = airoha_ppe_get_total_num_stats_entries(ppe);
if (ppe_num_stats_entries > 0) {
err = npu->ops.ppe_init_stats(npu, ppe->foe_stats_dma,
---
base-commit: b9d8b856689d2b968495d79fe653d87fcb8ad98c
change-id: 20260412-airoha-wait-for-npu-config-offload-setup-19d04522412d
Best regards,
--
Lorenzo Bianconi <lorenzo@kernel.org>
^ permalink raw reply related
* Re: [PATCH v6 3/3] arm64: dts: rockchip: Add Orange Pi 5 Pro board support
From: Dennis Gilmore @ 2026-04-14 14:07 UTC (permalink / raw)
To: Alexey Charkov
Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Heiko Stuebner,
FUKAUMI Naoki, Hsun Lai, Jonas Karlman, Chaoyi Chen, John Clark,
Michael Opdenacker, Quentin Schulz, Andrew Lunn, Chukun Pan,
Peter Robinson, Michael Riesch, Mykola Kvach, Jimmy Hon,
devicetree, linux-arm-kernel, linux-rockchip, linux-kernel
In-Reply-To: <CABjd4YwZJe8fO+kJiXRTq5gZirVvKvCqWzNdYqN3-6eMAZUFxQ@mail.gmail.com>
On Sat, Apr 11, 2026 at 1:00 PM Alexey Charkov <alchark@gmail.com> wrote:
>
> On Sat, Apr 11, 2026 at 6:47 AM <dennis@ausil.us> wrote:
> >
> > From: Dennis Gilmore <dennis@ausil.us>
> >
> > Add device tree for the Xunlong Orange Pi 5 Pro (RK3588S).
> >
> > - eMMC module, you can optionally solder a SPI NOR in place and turn
> > off the eMMC
> > - PCIe-attached NIC (pcie2x1l1)
> > - PCIe NVMe slot (pcie2x1l2)
> > - AP6256 WiFi (BCM43456) via SDIO with mmc-pwrseq
> > - BCM4345C5 Bluetooth
> > - es8388 audio
> > - USB 2.0 and USB 3.0
> > - Two HDMI ports, the second is connected to the SoC's DP controller
> > driven by a transparent LT8711UXD bridge that has firmware onboard and
> > needs no node defined.
> >
> > Vendors description and links to schematics available:
> > http://www.orangepi.org/html/hardWare/computerAndMicrocontrollers/details/Orange-Pi-5-Pro.html
>
> Hi Dennis,
>
> The most useful of these is the schematic, so it's best to include a
> direct link to that in a dedicated Link: tag
>
> Link: https://drive.google.com/file/d/1qs1DratHuh7C6J6MEtQIwUsiSrg8qgTi/view
Will change to that, I did not do it because a random Google Drive
link doesn't really indicate it as a source of truth
> [schematic]
>
> > Signed-off-by: Dennis Gilmore <dennis@ausil.us>
> > ---
> > .../display/rockchip/rockchip,dw-dp.yaml | 7 +
> > arch/arm64/boot/dts/rockchip/Makefile | 1 +
> > .../dts/rockchip/rk3588s-orangepi-5-pro.dts | 352 ++++++++++++++++++
> > drivers/gpu/drm/bridge/synopsys/dw-dp.c | 12 +
>
> These should be three separate patches, never lumped together. First
> the binding change, next the driver change. They go together via the
> subsystem tree (likely DRM in this case). Then the DTS addition (or
> change) separately (it goes via the SoC tree).
They were something I was doing as I worked on getting the second HDMI
port working, they ended up not being needed, and I should have
removed it there really should have only been the dts and Makefile. I
should have waited until the morning to review again and send.
> > 4 files changed, 372 insertions(+)
> > create mode 100644 arch/arm64/boot/dts/rockchip/rk3588s-orangepi-5-pro.dts
> >
> > diff --git a/Documentation/devicetree/bindings/display/rockchip/rockchip,dw-dp.yaml b/Documentation/devicetree/bindings/display/rockchip/rockchip,dw-dp.yaml
> > index 6345f0132d43..079a912d97f1 100644
> > --- a/Documentation/devicetree/bindings/display/rockchip/rockchip,dw-dp.yaml
> > +++ b/Documentation/devicetree/bindings/display/rockchip/rockchip,dw-dp.yaml
> > @@ -57,6 +57,13 @@ properties:
> > - const: i2s
> > - const: spdif
> >
> > + hpd-gpios:
> > + maxItems: 1
> > + description:
> > + GPIO used for hot plug detection when the controller's native HPD
> > + input is not connected. If not specified, the controller uses its
> > + internal HPD detection mechanism.
>
> Do you actually need this change? According to the schematic, the
> DP_HPDIN line from the DP-HDMI bridge is routed to the native
> DP0_HPDIN_M0 pin of the DP controller, so it shouldn't require this
> GPIO trick if the pinctrl is configured properly.
No I do not, It was an approach I had experimented with but did not
use and did not mean to include here.
> > phys:
> > maxItems: 1
> >
> > diff --git a/arch/arm64/boot/dts/rockchip/Makefile b/arch/arm64/boot/dts/rockchip/Makefile
> > index 4d384f153c13..c99dca2ae9e7 100644
> > --- a/arch/arm64/boot/dts/rockchip/Makefile
> > +++ b/arch/arm64/boot/dts/rockchip/Makefile
> > @@ -214,6 +214,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588s-nanopi-r6c.dtb
> > dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588s-odroid-m2.dtb
> > dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588s-orangepi-5.dtb
> > dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588s-orangepi-5b.dtb
> > +dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588s-orangepi-5-pro.dtb
> > dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588s-orangepi-cm5-base.dtb
> > dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588s-radxa-cm5-io.dtb
> > dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588s-roc-pc.dtb
> > diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-orangepi-5-pro.dts b/arch/arm64/boot/dts/rockchip/rk3588s-orangepi-5-pro.dts
> > new file mode 100644
> > index 000000000000..84c83aa69f63
> > --- /dev/null
> > +++ b/arch/arm64/boot/dts/rockchip/rk3588s-orangepi-5-pro.dts
> > @@ -0,0 +1,352 @@
> > +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> > +
> > +/dts-v1/;
> > +
> > +#include "rk3588s-orangepi-5.dtsi"
> > +
> > +/ {
> > + model = "Xunlong Orange Pi 5 Pro";
> > + compatible = "xunlong,orangepi-5-pro", "rockchip,rk3588s";
> > +
> > + aliases {
> > + mmc0 = &sdhci;
> > + mmc1 = &sdmmc;
> > + mmc2 = &sdio;
> > + };
> > +
> > + dp-con {
> > + compatible = "dp-connector";
>
> You don't have a physical DP connector on the board, so this node
> doesn't describe actual hardware, and is thus a no-go. What you have
> instead is an HDMI type A connector routed via an onboard DP to HDMI
> bridge, so you should describe exactly that in the device tree (a node
> for the HDMI connector, a node for the bridge, a node for the DP
> controller, and endpoints connected from the controller to the bridge,
> from the bridge to the connector). Please refer to the device tree for
> Radxa Rock 5 ITX, which has a similar setup (but a different bridge
> IC).
>
> I don't think your LT8711UXD has existing binding or driver entry, so
> a one-line patch will likely be needed to
> Documentation/devicetree/bindings/display/bridge/simple-bridge.yaml,
> and a separate one to drivers/gpu/drm/bridge/simple-bridge.c. Separate
> ones :)
Will add in v7
> > + port {
> > + dp_con_in: endpoint {
> > + remote-endpoint = <&dp0_out_con>;
> > + };
> > + };
> > + };
> > +
> > + analog-sound {
> > + compatible = "simple-audio-card";
> > + pinctrl-names = "default";
> > + pinctrl-0 = <&hp_detect>;
> > + simple-audio-card,bitclock-master = <&masterdai>;
> > + simple-audio-card,format = "i2s";
> > + simple-audio-card,frame-master = <&masterdai>;
> > + simple-audio-card,hp-det-gpios = <&gpio1 RK_PD5 GPIO_ACTIVE_HIGH>;
> > + simple-audio-card,mclk-fs = <256>;
> > + simple-audio-card,name = "rockchip,es8388";
> > + simple-audio-card,routing =
> > + "Headphones", "LOUT1",
> > + "Headphones", "ROUT1",
> > + "LINPUT1", "Microphone Jack",
> > + "RINPUT1", "Microphone Jack",
> > + "LINPUT2", "Onboard Microphone",
> > + "RINPUT2", "Onboard Microphone";
> > + simple-audio-card,widgets =
> > + "Microphone", "Microphone Jack",
> > + "Microphone", "Onboard Microphone",
> > + "Headphone", "Headphones";
> > +
> > + simple-audio-card,cpu {
> > + sound-dai = <&i2s2_2ch>;
> > + };
> > +
> > + masterdai: simple-audio-card,codec {
> > + sound-dai = <&es8388>;
> > + system-clock-frequency = <12288000>;
> > + };
> > + };
> > +
> > + pwm-leds {
> > + compatible = "pwm-leds";
> > +
> > + led-0 {
> > + color = <LED_COLOR_ID_BLUE>;
> > + function = LED_FUNCTION_STATUS;
> > + linux,default-trigger = "heartbeat";
> > + max-brightness = <255>;
> > + pwms = <&pwm15 0 1000000 0>;
> > + };
> > +
> > + led-1 {
> > + color = <LED_COLOR_ID_GREEN>;
> > + function = LED_FUNCTION_ACTIVITY;
> > + linux,default-trigger = "heartbeat";
> > + max-brightness = <255>;
> > + pwms = <&pwm3 0 1000000 0>;
> > + };
> > + };
> > +
> > + fan: pwm-fan {
> > + compatible = "pwm-fan";
> > + #cooling-cells = <2>;
> > + cooling-levels = <0 50 100 150 200 255>;
> > + fan-supply = <&vcc5v0_sys>;
> > + pwms = <&pwm2 0 20000000 0>;
> > + };
> > +
> > + vcc3v3_dp: regulator-vcc3v3-dp {
> > + compatible = "regulator-fixed";
> > + enable-active-high;
> > + gpios = <&gpio3 RK_PC2 GPIO_ACTIVE_HIGH>;
>
> Please don't forget to add explicit pinctrl nodes for each GPIO pin
> you use (here and in other places like this). These GPIOs happen to
> work on Linux without configuring their pin control first, but that is
> pure luck and coincidence due to how the respective Linux subsystems
> are wired together, and if you ever need to use this device tree in
> e.g. U-boot (which also derives its DTS from the Linux kernel tree) it
> will break there.
Will do
> > + regulator-always-on;
> > + regulator-boot-on;
>
> Does it have to be always-on, boot-on? This looks like a hack to work
> around the fact that you didn't define the bridge node, which uses
> this as its supply. Please model the dependencies explicitly - most
> likely that will let you drop these attributes.
without these the the dp to HDMI bridge does not power up, and HPD
does not work,
> > + regulator-max-microvolt = <3300000>;
> > + regulator-min-microvolt = <3300000>;
>
> It's two separate regulators on your schematic, one DCDC at 1.25V and
> the other a load switch at 3.3V, driving six separate voltage inputs
> of the DP bridge. They are both controlled by the same GPIO pin
> though, so _maybe_ it's okay to have just one "virtual" node like this
> to model them together. Would be great for the DT maintainers to weigh
> in on this.
>
> > + regulator-name = "vcc3v3_dp";
> > + vin-supply = <&vcc_3v3_s3>;
> > + };
> > +
> > + vcc3v3_phy1: regulator-vcc3v3-phy1 {
> > + compatible = "regulator-fixed";
> > + enable-active-high;
> > + gpios = <&gpio3 RK_PB7 GPIO_ACTIVE_HIGH>;
> > + regulator-boot-on;
>
> See above
>
> > + regulator-max-microvolt = <3300000>;
> > + regulator-min-microvolt = <3300000>;
> > + regulator-name = "vcc3v3_phy1";
> > + startup-delay-us = <50000>;
> > + vin-supply = <&vcc_3v3_s3>;
> > + };
> > +
> > + vcc5v0_otg: regulator-vcc5v0-otg {
> > + compatible = "regulator-fixed";
> > + enable-active-high;
> > + gpios = <&gpio0 RK_PC4 GPIO_ACTIVE_HIGH>;
> > + pinctrl-names = "default";
> > + pinctrl-0 = <&vcc5v0_otg_en>;
> > + regulator-max-microvolt = <5000000>;
> > + regulator-min-microvolt = <5000000>;
> > + regulator-name = "vcc5v0_otg";
> > + vin-supply = <&vcc5v0_sys>;
> > + };
> > +
> > + sdio_pwrseq: sdio-pwrseq {
> > + compatible = "mmc-pwrseq-simple";
> > + clocks = <&hym8563>;
> > + clock-names = "ext_clock";
> > + post-power-on-delay-ms = <200>;
> > + reset-gpios = <&gpio0 RK_PD0 GPIO_ACTIVE_LOW>;
>
> This GPIO also needs a pinctrl
>
> > + };
> > +
> > + typea_con: usb-a-connector {
> > + compatible = "usb-a-connector";
> > + data-role = "host";
> > + label = "USB3 Type-A";
> > + power-role = "source";
> > + vbus-supply = <&vcc5v0_otg>;
> > + };
> > +};
> > +
> > +&dp0 {
> > + pinctrl-names = "default";
> > + pinctrl-0 = <&dp0m0_pins>;
>
> This switches your HPD pin to the native DP controller handling
> (DP0_HPDIN_M0), so the GPIO bits you've patched into the controller
> driver aren't even used, and it doesn't look like you tested that code
> path.
Right, I had not meant to include. It was something I had worked on in
refactoring it and went a different route.
>
> > + status = "okay";
> > +};
> > +
> > +&dp0_in {
> > + dp0_in_vp1: endpoint {
> > + remote-endpoint = <&vp1_out_dp0>;
> > + };
> > +};
> > +
> > +&dp0_out {
> > + dp0_out_con: endpoint {
> > + remote-endpoint = <&dp_con_in>;
>
> This will need to be rewritten once you add the proper bridge chain
> leading up to the HDMI type A connector.
Yep
> > + };
> > +};
> > +
> > +&i2c1 {
> > + pinctrl-names = "default";
> > + pinctrl-0 = <&i2c1m4_xfer>;
> > + status = "okay";
> > +};
> > +
> > +&i2c3 {
> > + pinctrl-names = "default";
> > + pinctrl-0 = <&i2c3m0_xfer>;
> > + status = "okay";
> > +
> > + es8388: audio-codec@11 {
> > + compatible = "everest,es8388", "everest,es8328";
> > + reg = <0x11>;
> > + #sound-dai-cells = <0>;
> > + AVDD-supply = <&vcc_3v3_s0>;
>
> Are you sure? Schematic says VCCA_3V3_S0, which is a different
> regulator (PLDO4 output of the PMIC)
>
> > + DVDD-supply = <&vcc_1v8_s0>;
>
> Schematic says VCCA_1V8_S0, which is a different regulator (PLDO1
> output of the PMIC)
>
> > + HPVDD-supply = <&vcc_3v3_s0>;
>
> Schematic says VCCA_3V3_S0
>
> > + PVDD-supply = <&vcc_3v3_s0>;
>
> Schematic says VCCA_1V8_S0
I will rename these. It was what was used in the original orange pi 5
boards and was carried over, but looking at their schematics, they are
labeled the same so changing makes sense. after digging in the Pi 5
Pro names two of the regulators differently to the 5 and 5b. and the
naming of the current ones does not match the schematic
>
> > + assigned-clock-rates = <12288000>;
> > + assigned-clocks = <&cru I2S2_2CH_MCLKOUT>;
> > + clocks = <&cru I2S2_2CH_MCLKOUT>;
> > + pinctrl-names = "default";
> > + pinctrl-0 = <&i2s2m1_mclk>;
> > + };
> > +};
> > +
> > +&i2c4 {
> > + pinctrl-names = "default";
> > + pinctrl-0 = <&i2c4m3_xfer>;
> > + status = "okay";
> > +};
> > +
> > +&i2s2_2ch {
> > + pinctrl-0 = <&i2s2m1_lrck &i2s2m1_sclk
> > + &i2s2m1_sdi &i2s2m1_sdo>;
> > + status = "okay";
> > +};
> > +
> > +&package_thermal {
> > + polling-delay = <1000>;
> > +
> > + cooling-maps {
> > + map0 {
> > + trip = <&package_fan0>;
> > + cooling-device = <&fan THERMAL_NO_LIMIT 1>;
> > + };
> > +
> > + map1 {
> > + trip = <&package_fan1>;
> > + cooling-device = <&fan 2 THERMAL_NO_LIMIT>;
> > + };
> > + };
> > +
> > + trips {
> > + package_fan0: package-fan0 {
> > + hysteresis = <2000>;
> > + temperature = <55000>;
> > + type = "active";
> > + };
> > +
> > + package_fan1: package-fan1 {
> > + hysteresis = <2000>;
> > + temperature = <65000>;
> > + type = "active";
> > + };
> > + };
> > +};
> > +
> > +/* NVMe */
> > +&pcie2x1l1 {
> > + pinctrl-names = "default";
> > + pinctrl-0 = <&pcie30x1m1_1_clkreqn &pcie30x1m1_1_waken>;
> > + reset-gpios = <&gpio4 RK_PA2 GPIO_ACTIVE_HIGH>;
>
> The GPIO also needs a pinctrl
Will fix
> > + supports-clkreq;
> > + vpcie3v3-supply = <&vcc_3v3_s3>;
> > + status = "okay";
> > +};
> > +
> > +/* NIC */
> > +&pcie2x1l2 {
> > + reset-gpios = <&gpio3 RK_PD1 GPIO_ACTIVE_HIGH>;
>
> The GPIO also needs a pinctrl
Will fix
> > + vpcie3v3-supply = <&vcc3v3_phy1>;
> > + status = "okay";
> > +};
> > +
> > +&pinctrl {
> > + bluetooth {
> > + bt_wake_gpio: bt-wake-pin {
> > + rockchip,pins = <0 RK_PC6 RK_FUNC_GPIO &pcfg_pull_none>;
> > + };
> > +
> > + bt_wake_host_irq: bt-wake-host-irq {
> > + rockchip,pins = <0 RK_PC5 RK_FUNC_GPIO &pcfg_pull_down>;
> > + };
> > + };
> > +
> > + usb {
> > + vcc5v0_otg_en: vcc5v0-otg-en {
> > + rockchip,pins = <0 RK_PC4 RK_FUNC_GPIO &pcfg_pull_none>;
> > + };
> > + };
> > +
> > + wlan {
> > + wifi_host_wake_irq: wifi-host-wake-irq {
> > + rockchip,pins = <0 RK_PA0 RK_FUNC_GPIO &pcfg_pull_down>;
> > + };
> > + };
> > +};
> > +
> > +&pwm15 {
> > + pinctrl-names = "default";
> > + pinctrl-0 = <&pwm15m2_pins>;
> > + status = "okay";
> > +};
> > +
> > +&pwm2 {
> > + pinctrl-names = "default";
> > + pinctrl-0 = <&pwm2m1_pins>;
> > + status = "okay";
> > +};
> > +
> > +&pwm3 {
> > + pinctrl-names = "default";
> > + pinctrl-0 = <&pwm3m2_pins>;
> > + status = "okay";
> > +};
> > +
> > +&sdhci {
> > + status = "okay";
> > +};
> > +
> > +&sdio {
> > + #address-cells = <1>;
> > + #size-cells = <0>;
> > + bus-width = <4>;
> > + cap-sd-highspeed;
> > + cap-sdio-irq;
> > + keep-power-in-suspend;
> > + max-frequency = <150000000>;
> > + mmc-pwrseq = <&sdio_pwrseq>;
> > + no-mmc;
> > + no-sd;
> > + non-removable;
> > + sd-uhs-sdr104;
> > + status = "okay";
> > +
> > + ap6256: wifi@1 {
> > + compatible = "brcm,bcm43456-fmac", "brcm,bcm4329-fmac";
> > + reg = <1>;
> > + interrupt-names = "host-wake";
> > + interrupt-parent = <&gpio0>;
> > + interrupts = <RK_PA0 IRQ_TYPE_LEVEL_HIGH>;
> > + pinctrl-names = "default";
> > + pinctrl-0 = <&wifi_host_wake_irq>;
> > + };
> > +};
> > +
> > +&uart9 {
> > + pinctrl-names = "default";
> > + pinctrl-0 = <&uart9m2_xfer &uart9m2_ctsn &uart9m2_rtsn>;
> > + uart-has-rtscts;
> > + status = "okay";
> > +
> > + bluetooth {
> > + compatible = "brcm,bcm4345c5";
> > + clocks = <&hym8563>;
> > + clock-names = "lpo";
> > + device-wakeup-gpios = <&gpio0 RK_PC6 GPIO_ACTIVE_HIGH>;
> > + interrupt-names = "host-wakeup";
> > + interrupt-parent = <&gpio0>;
> > + interrupts = <RK_PC5 IRQ_TYPE_LEVEL_HIGH>;
> > + max-speed = <1500000>;
> > + pinctrl-names = "default";
> > + pinctrl-0 = <&bt_wake_host_irq &bt_wake_gpio>;
> > + shutdown-gpios = <&gpio0 RK_PD5 GPIO_ACTIVE_HIGH>;
> > + vbat-supply = <&vcc_3v3_s3>;
> > + vddio-supply = <&vcc_1v8_s3>;
> > + };
> > +};
> > +
> > +&usb_host0_xhci {
> > + dr_mode = "host";
> > +};
> > +
> > +&usbdp_phy0 {
> > + rockchip,dp-lane-mux = <0 1>;
>
> I'm wondering if the DP controller's "out" endpoint should go to the
> PHY instead of directly to the connector/bridge. That would describe
> the hardware better.
This was initially added to make sure that the type A port worked
because it uses lanes 2/3, and I needed to make sure 0/1, which route
to the dp were allocated. The DP PHY is already tied to the controller
via the phys property on &dp0 (inherited from rk3588s.dtsi), and the
lane mux is set via rockchip,dp-lane-mux on &usbdp_phy0. This matches
the convention used by rk3588-evb2-v10, rk3588s-coolpi-4b, and
rk3588s-indiedroid-nova — routing the dp0_out endpoint through the PHY
would diverge from the existing binding and all in-tree users.
> > +};
> > +
> > +&vp1 {
> > + vp1_out_dp0: endpoint@a {
> > + reg = <ROCKCHIP_VOP2_EP_DP0>;
> > + remote-endpoint = <&dp0_in_vp1>;
> > + };
> > +};
> > diff --git a/drivers/gpu/drm/bridge/synopsys/dw-dp.c b/drivers/gpu/drm/bridge/synopsys/dw-dp.c
> > index fd23ca2834b0..b58f57b69b22 100644
> > --- a/drivers/gpu/drm/bridge/synopsys/dw-dp.c
> > +++ b/drivers/gpu/drm/bridge/synopsys/dw-dp.c
> > @@ -8,6 +8,7 @@
> > */
> > #include <linux/bitfield.h>
> > #include <linux/clk.h>
> > +#include <linux/gpio/consumer.h>
> > #include <linux/iopoll.h>
> > #include <linux/irq.h>
> > #include <linux/media-bus-format.h>
> > @@ -330,6 +331,8 @@ struct dw_dp {
> > u8 pixel_mode;
> >
> > DECLARE_BITMAP(sdp_reg_bank, SDP_REG_BANK_SIZE);
> > +
> > + struct gpio_desc *hpd_gpiod;
> > };
> >
> > enum {
> > @@ -481,6 +484,9 @@ static bool dw_dp_hpd_detect(struct dw_dp *dp)
> > {
> > u32 value;
> >
> > + if (dp->hpd_gpiod)
> > + return gpiod_get_value_cansleep(dp->hpd_gpiod);
> > +
> > regmap_read(dp->regmap, DW_DP_HPD_STATUS, &value);
> >
> > return FIELD_GET(HPD_STATE, value) == DW_DP_HPD_STATE_PLUG;
> > @@ -2002,6 +2008,12 @@ struct dw_dp *dw_dp_bind(struct device *dev, struct drm_encoder *encoder,
> > return ERR_CAST(dp->regmap);
> > }
> >
> > + dp->hpd_gpiod = devm_gpiod_get_optional(dev, "hpd", GPIOD_IN);
>
> Not tested, not needed, why bother?..
this is not needed
> Best regards,
> Alexey
Thanks for the feedback
Dennis
^ permalink raw reply
* Re: [PATCH 1/3] dt-bindings: gpio: add Axiado SGPIO controller
From: Krzysztof Kozlowski @ 2026-04-14 14:06 UTC (permalink / raw)
To: Petar Stepanovic, Tzu-Hao Wei, Swark Yang, Prasad Bolisetty,
Linus Walleij, Bartosz Golaszewski, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Harshit Shah, SriNavmani A
Cc: linux-gpio, devicetree, linux-arm-kernel, linux-kernel
In-Reply-To: <20260414-axiado-ax3000-sgpio-controller-v1-1-b5c7e4c2e69b@axiado.com>
On 14/04/2026 15:48, Petar Stepanovic wrote:
> +properties:
> + compatible:
> + enum:
> + - axiado,sgpio
That's a SoC no? Where is SoC compatible?
> +
> + reg:
> + maxItems: 1
> +
> + gpio-controller: true
> +
> + '#gpio-cells':
> + const: 2
> +
> + interrupts:
> + maxItems: 1
> +
> + interrupt-controller: true
> +
> + '#interrupt-cells':
> + const: 2
> +
> + design-variant:
Sorry, but no, none of this and further properties apply to DT. Drop all
of them.
Please also read writing bindings so you won't make trivial mistakes.
...
> + sgpio@a000 {
> + compatible = "axiado,sgpio";
Don't come with own style, please. Look at other files.
> + reg = <0xa000 0x800>;
> + gpio-controller;
> + #gpio-cells = <2>;
Best regards,
Krzysztof
^ permalink raw reply
* Re: [PATCH 2/3] gpio: axiado: add SGPIO controller support
From: Krzysztof Kozlowski @ 2026-04-14 14:04 UTC (permalink / raw)
To: Petar Stepanovic, Tzu-Hao Wei, Swark Yang, Prasad Bolisetty,
Linus Walleij, Bartosz Golaszewski, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Harshit Shah, SriNavmani A
Cc: linux-gpio, devicetree, linux-arm-kernel, linux-kernel
In-Reply-To: <20260414-axiado-ax3000-sgpio-controller-v1-2-b5c7e4c2e69b@axiado.com>
On 14/04/2026 15:48, Petar Stepanovic wrote:
> +
> + for (i = 0; i < sgpio->max_offset_regs; i++) {
> + sgpio->slices[2].reg_ss[i] = 0;
> + dout_value = be32_to_cpu(prop[i]);
> +
> + for (dout_reverse = 0; dout_reverse < 32; ++dout_reverse) {
> + sgpio->slices[2].reg_ss[i] <<= 1;
> + sgpio->slices[2].reg_ss[i] |= (dout_value & 1);
> + dout_value >>= 1;
> + }
> + }
> +
> + sgpio_hw_init(sgpio);
> +
> + irq = platform_get_irq(pdev, 0);
> +
Odd style
> + if (irq < 0) {
> + dev_err(&pdev->dev, "Failed to get parent IRQ: %d\n", irq);
> + return irq;
> + }
> + /* Store parent IRQ for cleanup */
> + sgpio->parent_irq = irq;
> +
> + rc = devm_request_threaded_irq(&pdev->dev, irq, NULL, sgpio_irq_handler,
> + IRQF_ONESHOT, "axiado-sgpio", sgpio);
> +
> + if (rc < 0) {
> + dev_err(&pdev->dev, "Failed to request threaded IRQ %d: %d\n",
> + irq, rc);
Nope
> + return rc;
> + }
> +
> + sgpio->chip.parent = &pdev->dev;
> + sgpio->chip.ngpio = sgpio->ngpios * 2;
> + sgpio->chip.owner = THIS_MODULE;
> + sgpio->chip.direction_input = ax3000_sgpio_dir_in;
> + sgpio->chip.direction_output = ax3000_sgpio_dir_out;
> + sgpio->chip.get = ax3000_sgpio_get;
> + sgpio->chip.set = ax3000_sgpio_set;
> + sgpio->chip.label = dev_name(&pdev->dev);
> + sgpio->chip.base = -1;
> +
> + girq = &sgpio->chip.irq;
> +
> + girq->chip = &axiado_sgpio_irqchip;
> + girq->handler = handle_edge_irq;
> + girq->default_type = IRQ_TYPE_NONE;
> + girq->num_parents = 1;
> + girq->parents =
> + devm_kcalloc(&pdev->dev, 1, sizeof(*girq->parents), GFP_KERNEL);
> + if (!girq->parents) {
> + dev_err(&pdev->dev, "Failed to allocate parents array\n");
> + return -ENOMEM;
Ykes...
> + }
> +
> +static struct platform_driver sgpio_driver = {
> + .driver = {
> + .name = "sgpio",
> + .owner = THIS_MODULE,
Uh, that's 13 year old code. Please drop everything and write from
scratch using latest reviewed drivers as your base. No point to repeat
same review and fix the same issues we already fixed during last 13 years...
> + .of_match_table = ax_sgpio_match,
> + },
> + .probe = sgpio_probe,
> + .remove = sgpio_remove,
> +};
> +
> +static int __init ax_sgpio_init(void)
> +{
> + int ret;
> +
> + ret = platform_driver_register(&sgpio_driver);
> + if (ret < 0) {
> + pr_err("Failed to register SGPIO driver\n");
> + return ret;
> + }
> +
> + return 0;
> +}
> +
> +static void __exit ax_sgpio_exit(void)
> +{
> + platform_driver_unregister(&sgpio_driver);
> +}
> +
> +module_init(ax_sgpio_init);
> +module_exit(ax_sgpio_exit);
And that's one more.
module_platform_driver, no?
> +
> +MODULE_DESCRIPTION("Axiado Serial GPIO Driver");
> +MODULE_AUTHOR("Axiado Corporation");
> +MODULE_LICENSE("GPL");
>
Best regards,
Krzysztof
^ permalink raw reply
* Re: [PATCH v2 2/3] pmdomain: core: add support for power-domains-child-ids
From: Ulf Hansson @ 2026-04-14 14:03 UTC (permalink / raw)
To: Kevin Hilman (TI)
Cc: Rob Herring, Geert Uytterhoeven, linux-pm, devicetree,
linux-kernel, arm-scmi, linux-arm-kernel
In-Reply-To: <20260410-topic-lpm-pmdomain-child-ids-v2-2-83396e4b5f8b@baylibre.com>
On Sat, 11 Apr 2026 at 01:44, Kevin Hilman (TI) <khilman@baylibre.com> wrote:
>
> Currently, PM domains can only support hierarchy for simple
> providers (e.g. ones with #power-domain-cells = 0).
>
> Add support for oncell providers as well by adding a new property
> `power-domains-child-ids` to describe the parent/child relationship.
>
> For example, an SCMI PM domain provider has multiple domains, each of
> which might be a child of diffeent parent domains. In this example,
> the parent domains are MAIN_PD and WKUP_PD:
>
> scmi_pds: protocol@11 {
> reg = <0x11>;
> #power-domain-cells = <1>;
> power-domains = <&MAIN_PD>, <&WKUP_PD>;
> power-domains-child-ids = <15>, <19>;
> };
>
> With this example using the new property, SCMI PM domain 15 becomes a
> child domain of MAIN_PD, and SCMI domain 19 becomes a child domain of
> WKUP_PD.
>
> To support this feature, add two new core functions
>
> - of_genpd_add_child_ids()
> - of_genpd_remove_child_ids()
>
> which can be called by pmdomain providers to add/remove child domains
> if they support the new property power-domains-child-ids.
>
> The add function is "all or nothing". If it cannot add all of the
> child domains in the list, it will unwind any additions already made
> and report a failure.
>
> Signed-off-by: Kevin Hilman (TI) <khilman@baylibre.com>
> ---
> drivers/pmdomain/core.c | 166 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> include/linux/pm_domain.h | 16 ++++++++++++++++
> 2 files changed, 182 insertions(+)
>
> diff --git a/drivers/pmdomain/core.c b/drivers/pmdomain/core.c
> index 61c2277c9ce3..f978477dd546 100644
> --- a/drivers/pmdomain/core.c
> +++ b/drivers/pmdomain/core.c
> @@ -2909,6 +2909,172 @@ static struct generic_pm_domain *genpd_get_from_provider(
> return genpd;
> }
>
> +/**
> + * of_genpd_add_child_ids() - Parse power-domains-child-ids property
> + * @np: Device node pointer associated with the PM domain provider.
> + * @data: Pointer to the onecell data associated with the PM domain provider.
> + *
> + * Parse the power-domains and power-domains-child-ids properties to establish
> + * parent-child relationships for PM domains. The power-domains property lists
> + * parent domains, and power-domains-child-ids lists which child domain IDs
> + * should be associated with each parent.
> + *
> + * Uses "all or nothing" semantics: either all relationships are established
> + * successfully, or none are (any partially-added relationships are unwound
> + * on error).
> + *
> + * Returns 0 on success, -ENOENT if properties don't exist, or negative error code.
> + */
As I mentioned in my earlier reply for the previous version, returning
a specific error code when the property doesn't exist will complicate
handling for the caller. Moreover, we also need to make sure we don't
returning the same error code (-ENOENT) for a different error further
down the execution path in of_genpd_add_child_ids(). Otherwise it
would the caller treat the error code in the wrong way.
To me, there are two better ways to address this. For both options,
of_genpd_add_child_ids() should return 0 when
"power-domains-child-ids" is missing.
1) Add another helper function that checks if
"power-domains-child-ids" exists. The caller can then use this to
pre-parse the property and decide whether to treat it as an error.
2) As I suggested earlier, let of_genpd_add_child_ids() return the
number of assigned parents/children, while still using the all or
nothing approach, of course.
Kind regards
Uffe
> +int of_genpd_add_child_ids(struct device_node *np,
> + struct genpd_onecell_data *data)
> +{
> + struct of_phandle_args parent_args;
> + struct generic_pm_domain *parent_genpd, *child_genpd;
> + struct generic_pm_domain **pairs; /* pairs[2*i]=parent, pairs[2*i+1]=child */
> + u32 child_id;
> + int i, ret, count, child_count, added = 0;
> +
> + /* Check if both properties exist */
> + count = of_count_phandle_with_args(np, "power-domains", "#power-domain-cells");
> + if (count <= 0)
> + return -ENOENT;
> +
> + child_count = of_property_count_u32_elems(np, "power-domains-child-ids");
> + if (child_count < 0)
> + return -ENOENT;
> + if (child_count != count)
> + return -EINVAL;
> +
> + /* Allocate tracking array for error unwind (parent/child pairs) */
> + pairs = kmalloc_array(count * 2, sizeof(*pairs), GFP_KERNEL);
> + if (!pairs)
> + return -ENOMEM;
> +
> + for (i = 0; i < count; i++) {
> + ret = of_property_read_u32_index(np, "power-domains-child-ids",
> + i, &child_id);
> + if (ret)
> + goto err_unwind;
> +
> + /* Validate child ID is within bounds */
> + if (child_id >= data->num_domains) {
> + pr_err("Child ID %u out of bounds (max %u) for %pOF\n",
> + child_id, data->num_domains - 1, np);
> + ret = -EINVAL;
> + goto err_unwind;
> + }
> +
> + /* Get the child domain */
> + child_genpd = data->domains[child_id];
> + if (!child_genpd) {
> + pr_err("Child domain %u is NULL for %pOF\n", child_id, np);
> + ret = -EINVAL;
> + goto err_unwind;
> + }
> +
> + ret = of_parse_phandle_with_args(np, "power-domains",
> + "#power-domain-cells", i,
> + &parent_args);
> + if (ret)
> + goto err_unwind;
> +
> + /* Get the parent domain */
> + parent_genpd = genpd_get_from_provider(&parent_args);
> + of_node_put(parent_args.np);
> + if (IS_ERR(parent_genpd)) {
> + pr_err("Failed to get parent domain for %pOF: %ld\n",
> + np, PTR_ERR(parent_genpd));
> + ret = PTR_ERR(parent_genpd);
> + goto err_unwind;
> + }
> +
> + /* Establish parent-child relationship */
> + ret = pm_genpd_add_subdomain(parent_genpd, child_genpd);
> + if (ret) {
> + pr_err("Failed to add child domain %u to parent in %pOF: %d\n",
> + child_id, np, ret);
> + goto err_unwind;
> + }
> +
> + /* Track for potential unwind */
> + pairs[2 * added] = parent_genpd;
> + pairs[2 * added + 1] = child_genpd;
> + added++;
> +
> + pr_debug("Added child domain %u (%s) to parent %s for %pOF\n",
> + child_id, child_genpd->name, parent_genpd->name, np);
> + }
> +
> + kfree(pairs);
> + return 0;
> +
> +err_unwind:
> + /* Reverse all previously established relationships */
> + while (added-- > 0)
> + pm_genpd_remove_subdomain(pairs[2 * added], pairs[2 * added + 1]);
> + kfree(pairs);
> + return ret;
> +}
> +EXPORT_SYMBOL_GPL(of_genpd_add_child_ids);
> +
> +/**
> + * of_genpd_remove_child_ids() - Remove parent-child PM domain relationships
> + * @np: Device node pointer associated with the PM domain provider.
> + * @data: Pointer to the onecell data associated with the PM domain provider.
> + *
> + * Reverses the effect of of_genpd_add_child_ids() by parsing the same
> + * power-domains and power-domains-child-ids properties and calling
> + * pm_genpd_remove_subdomain() for each established relationship.
> + *
> + * Returns 0 on success, -ENOENT if properties don't exist, or negative error
> + * code on failure.
> + */
> +int of_genpd_remove_child_ids(struct device_node *np,
> + struct genpd_onecell_data *data)
> +{
> + struct of_phandle_args parent_args;
> + struct generic_pm_domain *parent_genpd, *child_genpd;
> + u32 child_id;
> + int i, ret, count, child_count;
> +
> + /* Check if both properties exist */
> + count = of_count_phandle_with_args(np, "power-domains", "#power-domain-cells");
> + if (count <= 0)
> + return -ENOENT;
> +
> + child_count = of_property_count_u32_elems(np, "power-domains-child-ids");
> + if (child_count < 0)
> + return -ENOENT;
> + if (child_count != count)
> + return -EINVAL;
> +
> + for (i = 0; i < count; i++) {
> + if (of_property_read_u32_index(np, "power-domains-child-ids",
> + i, &child_id))
> + continue;
> +
> + if (child_id >= data->num_domains || !data->domains[child_id])
> + continue;
> +
> + ret = of_parse_phandle_with_args(np, "power-domains",
> + "#power-domain-cells", i,
> + &parent_args);
> + if (ret)
> + continue;
> +
> + parent_genpd = genpd_get_from_provider(&parent_args);
> + of_node_put(parent_args.np);
> + if (IS_ERR(parent_genpd))
> + continue;
> +
> + child_genpd = data->domains[child_id];
> + pm_genpd_remove_subdomain(parent_genpd, child_genpd);
> + }
> +
> + return 0;
> +}
> +EXPORT_SYMBOL_GPL(of_genpd_remove_child_ids);
> +
> /**
> * of_genpd_add_device() - Add a device to an I/O PM domain
> * @genpdspec: OF phandle args to use for look-up PM domain
> diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h
> index f67a2cb7d781..b44615d79af6 100644
> --- a/include/linux/pm_domain.h
> +++ b/include/linux/pm_domain.h
> @@ -465,6 +465,10 @@ struct generic_pm_domain *of_genpd_remove_last(struct device_node *np);
> int of_genpd_parse_idle_states(struct device_node *dn,
> struct genpd_power_state **states, int *n);
> void of_genpd_sync_state(struct device_node *np);
> +int of_genpd_add_child_ids(struct device_node *np,
> + struct genpd_onecell_data *data);
> +int of_genpd_remove_child_ids(struct device_node *np,
> + struct genpd_onecell_data *data);
>
> int genpd_dev_pm_attach(struct device *dev);
> struct device *genpd_dev_pm_attach_by_id(struct device *dev,
> @@ -534,6 +538,18 @@ struct generic_pm_domain *of_genpd_remove_last(struct device_node *np)
> {
> return ERR_PTR(-EOPNOTSUPP);
> }
> +
> +static inline int of_genpd_add_child_ids(struct device_node *np,
> + struct genpd_onecell_data *data)
> +{
> + return -EOPNOTSUPP;
> +}
> +
> +static inline int of_genpd_remove_child_ids(struct device_node *np,
> + struct genpd_onecell_data *data)
> +{
> + return -EOPNOTSUPP;
> +}
> #endif /* CONFIG_PM_GENERIC_DOMAINS_OF */
>
> #ifdef CONFIG_PM
>
> --
> 2.51.0
>
^ permalink raw reply
* Re: [PATCH v2] Bluetooth: Add Broadcom channel priority commands
From: Luiz Augusto von Dentz @ 2026-04-14 14:00 UTC (permalink / raw)
To: fnkl.kernel
Cc: Sven Peter, Janne Grunau, Neal Gompa, Marcel Holtmann,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Simon Horman, linux-kernel, asahi, linux-arm-kernel,
linux-bluetooth, netdev
In-Reply-To: <20260407-brcm-prio-v2-1-3f745edf49af@gmail.com>
Hi Sasha,
On Tue, Apr 7, 2026 at 1:46 PM Sasha Finkelstein via B4 Relay
<devnull+fnkl.kernel.gmail.com@kernel.org> wrote:
>
> From: Sasha Finkelstein <fnkl.kernel@gmail.com>
>
> Certain Broadcom bluetooth chips (bcm4377/bcm4378/bcm438) need ACL
> streams carrying audio to be set as "high priority" using a vendor
> specific command to prevent 10-ish second-long dropouts whenever
> something does a device scan. This patch sends the command when the
> socket priority is set to TC_PRIO_INTERACTIVE, as BlueZ does for audio.
>
> Signed-off-by: Sasha Finkelstein <fnkl.kernel@gmail.com>
> ---
> Changes in v2:
> - new ioctl got nack-ed, so let's use sk_priority as the trigger
> - Link to v1: https://lore.kernel.org/r/20260407-brcm-prio-v1-1-f38b17376640@gmail.com
> ---
> MAINTAINERS | 2 ++
> drivers/bluetooth/hci_bcm4377.c | 2 ++
> include/net/bluetooth/bluetooth.h | 4 ++++
> include/net/bluetooth/hci_core.h | 11 +++++++++++
> net/bluetooth/Kconfig | 7 +++++++
> net/bluetooth/Makefile | 1 +
> net/bluetooth/brcm.c | 29 +++++++++++++++++++++++++++++
> net/bluetooth/brcm.h | 17 +++++++++++++++++
> net/bluetooth/hci_conn.c | 28 ++++++++++++++++++++++++++++
> net/bluetooth/l2cap_sock.c | 13 +++++++++++++
> 10 files changed, 114 insertions(+)
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index c3fe46d7c4bc..81be021367ec 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -2562,6 +2562,8 @@ F: include/dt-bindings/pinctrl/apple.h
> F: include/linux/mfd/macsmc.h
> F: include/linux/soc/apple/*
> F: include/uapi/drm/asahi_drm.h
> +F: net/bluetooth/brcm.c
> +F: net/bluetooth/brcm.h
>
> ARM/ARTPEC MACHINE SUPPORT
> M: Jesper Nilsson <jesper.nilsson@axis.com>
> diff --git a/drivers/bluetooth/hci_bcm4377.c b/drivers/bluetooth/hci_bcm4377.c
> index 925d0a635945..5f79920c0306 100644
> --- a/drivers/bluetooth/hci_bcm4377.c
> +++ b/drivers/bluetooth/hci_bcm4377.c
> @@ -2397,6 +2397,8 @@ static int bcm4377_probe(struct pci_dev *pdev, const struct pci_device_id *id)
> if (bcm4377->hw->broken_le_ext_adv_report_phy)
> hci_set_quirk(hdev, HCI_QUIRK_FIXUP_LE_EXT_ADV_REPORT_PHY);
>
> + hci_set_brcm_capable(hdev);
> +
> pci_set_drvdata(pdev, bcm4377);
> hci_set_drvdata(hdev, bcm4377);
> SET_HCIDEV_DEV(hdev, &pdev->dev);
> diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h
> index 69eed69f7f26..07a250673950 100644
> --- a/include/net/bluetooth/bluetooth.h
> +++ b/include/net/bluetooth/bluetooth.h
> @@ -457,6 +457,7 @@ struct l2cap_ctrl {
> };
>
> struct hci_dev;
> +struct hci_conn;
>
> typedef void (*hci_req_complete_t)(struct hci_dev *hdev, u8 status, u16 opcode);
> typedef void (*hci_req_complete_skb_t)(struct hci_dev *hdev, u8 status,
> @@ -469,6 +470,9 @@ void hci_req_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 status,
> int hci_ethtool_ts_info(unsigned int index, int sk_proto,
> struct kernel_ethtool_ts_info *ts_info);
>
> +int hci_conn_setsockopt(struct hci_conn *conn, struct sock *sk, int level,
> + int optname, sockptr_t optval, unsigned int optlen);
> +
> #define HCI_REQ_START BIT(0)
> #define HCI_REQ_SKB BIT(1)
>
> diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
> index a7bffb908c1e..947e7c2b08dd 100644
> --- a/include/net/bluetooth/hci_core.h
> +++ b/include/net/bluetooth/hci_core.h
> @@ -642,6 +642,10 @@ struct hci_dev {
> bool aosp_quality_report;
> #endif
>
> +#if IS_ENABLED(CONFIG_BT_BRCMEXT)
> + bool brcm_capable;
> +#endif
> +
> int (*open)(struct hci_dev *hdev);
> int (*close)(struct hci_dev *hdev);
> int (*flush)(struct hci_dev *hdev);
> @@ -1791,6 +1795,13 @@ static inline void hci_set_aosp_capable(struct hci_dev *hdev)
> #endif
> }
>
> +static inline void hci_set_brcm_capable(struct hci_dev *hdev)
> +{
> +#if IS_ENABLED(CONFIG_BT_BRCMEXT)
> + hdev->brcm_capable = true;
> +#endif
> +}
> +
> static inline void hci_devcd_setup(struct hci_dev *hdev)
> {
> #ifdef CONFIG_DEV_COREDUMP
> diff --git a/net/bluetooth/Kconfig b/net/bluetooth/Kconfig
> index 6b2b65a66700..0f2a5fbcafc5 100644
> --- a/net/bluetooth/Kconfig
> +++ b/net/bluetooth/Kconfig
> @@ -110,6 +110,13 @@ config BT_AOSPEXT
> This options enables support for the Android Open Source
> Project defined HCI vendor extensions.
>
> +config BT_BRCMEXT
> + bool "Enable Broadcom extensions"
> + depends on BT
> + help
> + This option enables support for the Broadcom defined HCI
> + vendor extensions.
> +
> config BT_DEBUGFS
> bool "Export Bluetooth internals in debugfs"
> depends on BT && DEBUG_FS
> diff --git a/net/bluetooth/Makefile b/net/bluetooth/Makefile
> index a7eede7616d8..b4c9013a46ce 100644
> --- a/net/bluetooth/Makefile
> +++ b/net/bluetooth/Makefile
> @@ -24,5 +24,6 @@ bluetooth-$(CONFIG_BT_LE) += iso.o
> bluetooth-$(CONFIG_BT_LEDS) += leds.o
> bluetooth-$(CONFIG_BT_MSFTEXT) += msft.o
> bluetooth-$(CONFIG_BT_AOSPEXT) += aosp.o
> +bluetooth-$(CONFIG_BT_BRCMEXT) += brcm.o
> bluetooth-$(CONFIG_BT_DEBUGFS) += hci_debugfs.o
> bluetooth-$(CONFIG_BT_SELFTEST) += selftest.o
> diff --git a/net/bluetooth/brcm.c b/net/bluetooth/brcm.c
> new file mode 100644
> index 000000000000..9aa0a265ab3d
> --- /dev/null
> +++ b/net/bluetooth/brcm.c
> @@ -0,0 +1,29 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Copyright (C) 2026 The Asahi Linux Contributors
> + */
> +
> +#include <net/bluetooth/bluetooth.h>
> +#include <net/bluetooth/hci_core.h>
> +
> +#include "brcm.h"
> +
> +int brcm_set_high_priority(struct hci_dev *hdev, u16 handle, bool enable)
> +{
> + struct sk_buff *skb;
> + u8 cmd[3];
> +
> + if (!hdev->brcm_capable)
> + return 0;
> +
> + cmd[0] = handle;
> + cmd[1] = handle >> 8;
Adding a packed struct and then using something like cpu_to_le16 is
probably preferable over above.
> + cmd[2] = !!enable;
> +
> + skb = hci_cmd_sync(hdev, 0xfc57, sizeof(cmd), cmd, HCI_CMD_TIMEOUT);
> + if (IS_ERR(skb))
> + return PTR_ERR(skb);
> +
> + kfree_skb(skb);
> + return 0;
> +}
> diff --git a/net/bluetooth/brcm.h b/net/bluetooth/brcm.h
> new file mode 100644
> index 000000000000..fdaee63bd1d2
> --- /dev/null
> +++ b/net/bluetooth/brcm.h
> @@ -0,0 +1,17 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +/*
> + * Copyright (C) 2026 The Asahi Linux Contributors
> + */
> +
> +#if IS_ENABLED(CONFIG_BT_BRCMEXT)
> +
> +int brcm_set_high_priority(struct hci_dev *hdev, u16 handle, bool enable);
> +
> +#else
> +
> +static inline int brcm_set_high_priority(struct hci_dev *hdev, u16 handle, bool enable)
> +{
> + return 0;
> +}
> +
> +#endif
> diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
> index 11d3ad8d2551..096163840f62 100644
> --- a/net/bluetooth/hci_conn.c
> +++ b/net/bluetooth/hci_conn.c
> @@ -35,6 +35,7 @@
> #include <net/bluetooth/iso.h>
> #include <net/bluetooth/mgmt.h>
>
> +#include "brcm.h"
> #include "smp.h"
> #include "eir.h"
>
> @@ -3070,6 +3071,33 @@ int hci_conn_set_phy(struct hci_conn *conn, u32 phys)
> }
> }
>
> +int hci_conn_setsockopt(struct hci_conn *conn, struct sock *sk, int level,
> + int optname, sockptr_t optval, unsigned int optlen)
> +{
> + int val;
> + bool old_high, new_high, changed;
> +
> + if (level != SOL_SOCKET)
> + return 0;
> +
> + if (optname != SO_PRIORITY)
> + return 0;
> +
> + if (optlen < sizeof(int))
> + return -EINVAL;
> +
> + if (copy_from_sockptr(&val, optval, sizeof(val)))
> + return -EFAULT;
> +
> + old_high = sk->sk_priority >= TC_PRIO_INTERACTIVE;
> + new_high = val >= TC_PRIO_INTERACTIVE;
> + changed = old_high != new_high;
> + if (!changed)
> + return 0;
> +
> + return brcm_set_high_priority(conn->hdev, conn->handle, new_high);
The skb carries the priority (skb->priority), not sure why you need to
capture the sk_priority instead, doing so ignores the load balance
that hci_core performs to avoid starving connections.
> +}
> +
> static int abort_conn_sync(struct hci_dev *hdev, void *data)
> {
> struct hci_conn *conn = data;
> diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
> index 71e8c1b45bce..d5eef87accc4 100644
> --- a/net/bluetooth/l2cap_sock.c
> +++ b/net/bluetooth/l2cap_sock.c
> @@ -891,6 +891,16 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname,
>
> BT_DBG("sk %p", sk);
>
> + if (level == SOL_SOCKET) {
> + conn = chan->conn;
> + if (conn)
> + err = hci_conn_setsockopt(conn->hcon, sock->sk, level,
> + optname, optval, optlen);
> + if (err)
> + return err;
> + return sock_setsockopt(sock, level, optname, optval, optlen);
> + }
> +
> if (level == SOL_L2CAP)
> return l2cap_sock_setsockopt_old(sock, optname, optval, optlen);
>
> @@ -1931,6 +1941,9 @@ static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock,
>
> INIT_LIST_HEAD(&l2cap_pi(sk)->rx_busy);
>
> + if (sock)
> + set_bit(SOCK_CUSTOM_SOCKOPT, &sock->flags);
This is more complicated than it needs to be. I'd just add a new
callback, `hdev->set_priority(handle, skb->priority)`, so the driver
is called whenever it needs to elevate a connection's priority, that
said there could be cases where a connection needs its priority set
momentarily to transmit A2DP, followed by OBEX packets that are best
effort. Therefore, `hci_conn` will probably need to track the priority
so it can detect when it needs changing on a per skb basis.
> chan = l2cap_chan_create();
> if (!chan) {
> sk_free(sk);
>
> ---
> base-commit: bfe62a454542cfad3379f6ef5680b125f41e20f4
> change-id: 20260407-brcm-prio-b630e6cc3834
>
> Best regards,
> --
> Sasha Finkelstein <fnkl.kernel@gmail.com>
>
>
--
Luiz Augusto von Dentz
^ permalink raw reply
* Re: Re: [PATCH] ASoC: imx-rpmsg: Fix ignore-suspend-widgets only applied to codec DAPM
From: Mark Brown @ 2026-04-14 13:57 UTC (permalink / raw)
To: Chancel Liu
Cc: shengjiu.wang@gmail.com, Xiubo.Lee@gmail.com, festevam@gmail.com,
nicoleotsuka@gmail.com, lgirdwood@gmail.com, perex@perex.cz,
tiwai@suse.com, Frank Li, s.hauer@pengutronix.de,
kernel@pengutronix.de, linux-sound@vger.kernel.org,
linuxppc-dev@lists.ozlabs.org, imx@lists.linux.dev,
linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org
In-Reply-To: <AM9PR04MB83539BD1328151697DA85859E3242@AM9PR04MB8353.eurprd04.prod.outlook.com>
[-- Attachment #1: Type: text/plain, Size: 1427 bytes --]
On Mon, Apr 13, 2026 at 03:13:51AM +0000, Chancel Liu wrote:
> Thanks for pointing this out. I really appreciate your suggestion to
> move this functionality into core-level. Several machine drivers could
> benefit if there's an unified ignore‑suspend mechanism.
> I have an idea to make it support a generic and reusable mechanism in
> the core rather than something each machine driver has to re‑implement.
> The design follows a simple structure:
> 1. Parse and store the name of widgets to ignore suspend in
> struct snd_soc_card
> The name list of widgets to ignore suspend can come either from DT or
> from the machine driver. Different boards/machines have different
> routing and power requirements. So allowing DT to specify
> "ignore-suspend-widgets" is important. It enables each device to define
> its own policy rather than forcing hard‑coded rules. To support this, a
> helper such as snd_soc_of_parse_ignore_suspend_widgets() can be defined
> in core and provided.
> 2. Apply ignore_suspend flags during snd_soc_bind_card()
> After all components have been probed and all DAPM widgets are
> registered in snd_soc_bind_card(), perform a unified search through
> the card’s widget list and mark matching widgets with
> ignore_suspend = 1. Any runtime prefixing applied during widget
> creation should be handled well by the lookup.
That sounds like a reasonable plan.
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply
* [PATCH 1/3] dt-bindings: gpio: add Axiado SGPIO controller
From: Petar Stepanovic @ 2026-04-14 13:48 UTC (permalink / raw)
To: Petar Stepanovic, Tzu-Hao Wei, Swark Yang, Prasad Bolisetty,
Linus Walleij, Bartosz Golaszewski, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Harshit Shah, SriNavmani A
Cc: linux-gpio, devicetree, linux-arm-kernel, linux-kernel
In-Reply-To: <20260414-axiado-ax3000-sgpio-controller-v1-0-b5c7e4c2e69b@axiado.com>
Add device tree binding for the Axiado SGPIO controller.
The SGPIO controller provides a serialized interface for
controlling multiple GPIO signals over a limited number of
physical lines. It supports configurable data direction and
interrupt handling.
The binding describes the properties required to instantiate
the controller and register it as a GPIO provider.
Signed-off-by: Petar Stepanovic <pstepanovic@axiado.com>
---
.../devicetree/bindings/gpio/axiado,sgpio.yaml | 98 ++++++++++++++++++++++
1 file changed, 98 insertions(+)
diff --git a/Documentation/devicetree/bindings/gpio/axiado,sgpio.yaml b/Documentation/devicetree/bindings/gpio/axiado,sgpio.yaml
new file mode 100644
index 000000000000..1533446d69f1
--- /dev/null
+++ b/Documentation/devicetree/bindings/gpio/axiado,sgpio.yaml
@@ -0,0 +1,98 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/gpio/axiado,sgpio.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Axiado SGPIO Controller
+
+maintainers:
+ - Petar Stepanovic <pstepanovic@axiado.com>
+ - SriNavmani A <srinavmani@axiado.com>
+ - Prasad Bolisetty <pbolisetty@axiado.com>
+
+description: |
+ The SGPIO controller provides a serialized interface for controlling
+ multiple GPIO signals over a limited number of physical lines.
+ It supports configurable data direction and interrupt handling.
+
+properties:
+ compatible:
+ enum:
+ - axiado,sgpio
+
+ reg:
+ maxItems: 1
+
+ gpio-controller: true
+
+ '#gpio-cells':
+ const: 2
+
+ interrupts:
+ maxItems: 1
+
+ interrupt-controller: true
+
+ '#interrupt-cells':
+ const: 2
+
+ design-variant:
+ description: SGPIO design variant size in bits (e.g. 128 or 512).
+ enum: [128, 512]
+ $ref: /schemas/types.yaml#/definitions/uint32
+
+ ngpios:
+ description: The number of gpios this controller has.
+ $ref: /schemas/types.yaml#/definitions/uint32
+
+ bus-frequency:
+ description: The SGPIO shift clock frequency in Hz.
+ $ref: /schemas/types.yaml#/definitions/uint32
+
+ apb-frequency:
+ description: The APB bus frequency in Hz.
+ $ref: /schemas/types.yaml#/definitions/uint32
+
+ dout-init:
+ description: Initial values for the dout registers.
+ $ref: /schemas/types.yaml#/definitions/uint32-array
+ minItems: 4
+ maxItems: 4
+
+required:
+ - compatible
+ - reg
+ - gpio-controller
+ - '#gpio-cells'
+ - interrupts
+ - interrupt-controller
+ - '#interrupt-cells'
+ - design-variant
+ - ngpios
+ - bus-frequency
+ - apb-frequency
+ - dout-init
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/interrupt-controller/irq.h>
+
+ sgpio@a000 {
+ compatible = "axiado,sgpio";
+ reg = <0xa000 0x800>;
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ interrupt-parent = <&gpio6>;
+ interrupts = <17 IRQ_TYPE_LEVEL_HIGH>;
+ design-variant = <128>;
+ ngpios = <128>;
+ bus-frequency = <1000000>;
+ apb-frequency = <100000000>;
+ dout-init = <0x00300000 0x00006371 0x00003800 0x00000000>;
+ };
--
2.34.1
^ permalink raw reply related
* [PATCH 0/3] Subject: [PATCH 0/3] gpio: add support for Axiado SGPIO controller
From: Petar Stepanovic @ 2026-04-14 13:48 UTC (permalink / raw)
To: Petar Stepanovic, Tzu-Hao Wei, Swark Yang, Prasad Bolisetty,
Linus Walleij, Bartosz Golaszewski, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Harshit Shah, SriNavmani A
Cc: linux-gpio, devicetree, linux-arm-kernel, linux-kernel
The SGPIO controller provides a serialized interface for
controlling multiple GPIO signals over a limited number of
physical lines. It supports configurable data direction and
interrupt handling.
This series adds support for the Axiado SGPIO controller.
The series includes:
- Device tree binding documentation
- GPIO driver implementation
- MAINTAINERS entry
The driver integrates with the Linux GPIO subsystem and
registers the controller as a gpio_chip.
Tested on Axiado platforms.
---
Patch 1: dt-bindings: gpio: add Axiado SGPIO controller
Patch 2: gpio: axiado: add SGPIO controller support
Patch 3: MAINTAINERS: add Axiado SGPIO controller
Signed-off-by: Petar Stepanovic <pstepanovic@axiado.com>
---
Petar Stepanovic (3):
dt-bindings: gpio: add Axiado SGPIO controller
gpio: axiado: add SGPIO controller support
MAINTAINERS: add Axiado SGPIO controller
.../devicetree/bindings/gpio/axiado,sgpio.yaml | 98 +++
MAINTAINERS | 9 +
drivers/gpio/Kconfig | 18 +
drivers/gpio/Makefile | 1 +
drivers/gpio/gpio-axiado-sgpio.c | 780 +++++++++++++++++++++
5 files changed, 906 insertions(+)
---
base-commit: 63804fed149a6750ffd28610c5c1c98cce6bd377
change-id: 20260320-axiado-ax3000-sgpio-controller-00f6e1db6ce9
Best regards,
--
Petar Stepanovic <pstepanovic@axiado.com>
^ permalink raw reply
* [PATCH 3/3] MAINTAINERS: add Axiado SGPIO controller
From: Petar Stepanovic @ 2026-04-14 13:48 UTC (permalink / raw)
To: Petar Stepanovic, Tzu-Hao Wei, Swark Yang, Prasad Bolisetty,
Linus Walleij, Bartosz Golaszewski, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Harshit Shah, SriNavmani A
Cc: linux-gpio, devicetree, linux-arm-kernel, linux-kernel
In-Reply-To: <20260414-axiado-ax3000-sgpio-controller-v1-0-b5c7e4c2e69b@axiado.com>
Add MAINTAINERS entry for the Axiado SGPIO controller driver
and corresponding device tree binding.
Signed-off-by: Petar Stepanovic <pstepanovic@axiado.com>
---
MAINTAINERS | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/MAINTAINERS b/MAINTAINERS
index 67db88b04537..56835c0a1863 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -4234,6 +4234,15 @@ S: Maintained
F: Documentation/devicetree/bindings/sound/axentia,*
F: sound/soc/atmel/tse850-pcm5142.c
+AXIADO SGPIO DRIVER
+M: Petar Stepanovic <pstepanovic@axiado.com>
+M: SriNavmani A <srinavmani@axiado.com>
+M: Prasad Bolisetty <pbolisetty@axiado.com>
+L: linux-gpio@vger.kernel.org
+S: Maintained
+F: Documentation/devicetree/bindings/gpio/axiado,sgpio.yaml
+F: drivers/gpio/gpio-axiado-sgpio.c
+
AXIS ARTPEC ARM64 SoC SUPPORT
M: Jesper Nilsson <jesper.nilsson@axis.com>
M: Lars Persson <lars.persson@axis.com>
--
2.34.1
^ permalink raw reply related
* [PATCH 2/3] gpio: axiado: add SGPIO controller support
From: Petar Stepanovic @ 2026-04-14 13:48 UTC (permalink / raw)
To: Petar Stepanovic, Tzu-Hao Wei, Swark Yang, Prasad Bolisetty,
Linus Walleij, Bartosz Golaszewski, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Harshit Shah, SriNavmani A
Cc: linux-gpio, devicetree, linux-arm-kernel, linux-kernel
In-Reply-To: <20260414-axiado-ax3000-sgpio-controller-v1-0-b5c7e4c2e69b@axiado.com>
Add support for the Axiado SGPIO controller.
The controller provides a serialized interface for GPIOs with
configurable direction and interrupt support.
The driver registers the controller as a gpio_chip and uses
regmap for register access.
Signed-off-by: Petar Stepanovic <pstepanovic@axiado.com>
---
drivers/gpio/Kconfig | 18 +
drivers/gpio/Makefile | 1 +
drivers/gpio/gpio-axiado-sgpio.c | 780 +++++++++++++++++++++++++++++++++++++++
3 files changed, 799 insertions(+)
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index bd185482a7fd..42c56d157092 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -198,6 +198,24 @@ config GPIO_ATH79
Select this option to enable GPIO driver for
Atheros AR71XX/AR724X/AR913X SoC devices.
+config GPIO_AXIADO_SGPIO
+ bool "Axiado SGPIO support"
+ depends on OF_GPIO
+ depends on ARCH_AXIADO || COMPILE_TEST
+ select GPIO_GENERIC
+ select GPIOLIB_IRQCHIP
+ select REGMAP
+ help
+ Enable support for the Axiado Serial GPIO (SGPIO) controller.
+
+ The SGPIO controller provides a serialized interface for
+ controlling multiple GPIO signals over a limited number of
+ physical lines. It supports configurable data direction and
+ interrupt handling.
+
+ This driver integrates with the Linux GPIO subsystem and
+ exposes the controller as a standard GPIO provider.
+
config GPIO_RASPBERRYPI_EXP
tristate "Raspberry Pi 3 GPIO Expander"
default RASPBERRYPI_FIRMWARE
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 2421a8fd3733..909a97551807 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -42,6 +42,7 @@ obj-$(CONFIG_GPIO_ARIZONA) += gpio-arizona.o
obj-$(CONFIG_GPIO_ASPEED) += gpio-aspeed.o
obj-$(CONFIG_GPIO_ASPEED_SGPIO) += gpio-aspeed-sgpio.o
obj-$(CONFIG_GPIO_ATH79) += gpio-ath79.o
+obj-$(CONFIG_GPIO_AXIADO_SGPIO) += gpio-axiado-sgpio.o
obj-$(CONFIG_GPIO_BCM_KONA) += gpio-bcm-kona.o
obj-$(CONFIG_GPIO_BCM_XGS_IPROC) += gpio-xgs-iproc.o
obj-$(CONFIG_GPIO_BD71815) += gpio-bd71815.o
diff --git a/drivers/gpio/gpio-axiado-sgpio.c b/drivers/gpio/gpio-axiado-sgpio.c
new file mode 100644
index 000000000000..8cd349ec6f53
--- /dev/null
+++ b/drivers/gpio/gpio-axiado-sgpio.c
@@ -0,0 +1,780 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2022-2026 Axiado Corporation
+ */
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/spinlock.h>
+
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/irqdomain.h>
+
+#include <linux/gpio/driver.h>
+
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_irq.h>
+
+#include <linux/regmap.h>
+
+struct sgpio_reg_offsets {
+ u32 mux_0;
+ u32 preset_0;
+ u32 count_0;
+ u32 pos_0;
+
+ u32 mux_1;
+ u32 ld;
+ u32 ld_ss;
+
+ u32 preset_1;
+ u32 count_1;
+ u32 pos_1;
+
+ u32 mux_2;
+ u32 dout;
+ u32 dout_ss;
+
+ u32 preset_2;
+ u32 count_2;
+ u32 pos_2;
+
+ u32 mux_3;
+ u32 preset_3;
+ u32 count_3;
+ u32 pos_3;
+
+ u32 mux_4;
+ u32 oe;
+ u32 oe_ss;
+
+ u32 preset_4;
+ u32 count_4;
+ u32 pos_4;
+
+ u32 mask;
+ u32 ctrl_en;
+ u32 ctrl_en_pos;
+
+ u32 din_ss;
+ u32 status;
+};
+
+static const struct sgpio_reg_offsets sgpio_offsets_512 = {
+ .mux_0 = 0x000,
+ .preset_0 = 0x1dc,
+ .count_0 = 0x1f0,
+ .pos_0 = 0x204,
+
+ .mux_1 = 0x004,
+ .ld = 0x014,
+ .ld_ss = 0x0d8,
+
+ .preset_1 = 0x1e0,
+ .count_1 = 0x1f4,
+ .pos_1 = 0x208,
+
+ .mux_2 = 0x008,
+ .dout = 0x054,
+ .dout_ss = 0x158,
+
+ .preset_2 = 0x1e4,
+ .count_2 = 0x1f8,
+ .pos_2 = 0x20c,
+
+ .mux_3 = 0x00c,
+ .preset_3 = 0x1e8,
+ .count_3 = 0x1fc,
+ .pos_3 = 0x210,
+
+ .mux_4 = 0x010,
+ .oe = 0x0d4,
+ .oe_ss = 0x1d8,
+
+ .preset_4 = 0x1ec,
+ .count_4 = 0x200,
+ .pos_4 = 0x214,
+
+ .mask = 0x224,
+ .ctrl_en = 0x218,
+ .ctrl_en_pos = 0x21c,
+
+ .din_ss = 0x198,
+ .status = 0x228,
+};
+
+static const struct sgpio_reg_offsets sgpio_offsets_128 = {
+ .mux_0 = 0x000,
+ .preset_0 = 0x08c,
+ .count_0 = 0x0a0,
+ .pos_0 = 0x0b4,
+
+ .mux_1 = 0x004,
+ .ld = 0x014,
+ .ld_ss = 0x048,
+
+ .preset_1 = 0x090,
+ .count_1 = 0x0a4,
+ .pos_1 = 0x0b8,
+
+ .mux_2 = 0x008,
+ .dout = 0x024,
+ .dout_ss = 0x068,
+
+ .preset_2 = 0x094,
+ .count_2 = 0x0a8,
+ .pos_2 = 0x0bc,
+
+ .mux_3 = 0x00c,
+ .preset_3 = 0x098,
+ .count_3 = 0x0ac,
+ .pos_3 = 0x0c0,
+
+ .mux_4 = 0x010,
+ .oe = 0x044,
+ .oe_ss = 0x088,
+
+ .preset_4 = 0x09c,
+ .count_4 = 0x0b0,
+ .pos_4 = 0x0c4,
+
+ .mask = 0x0d4,
+ .ctrl_en = 0x0c8,
+ .ctrl_en_pos = 0x0cc,
+
+ .din_ss = 0x078,
+ .status = 0x0d8,
+};
+
+#define MAX_SGPIO_PINS 512
+#define MAX_OFFSET_REG 16
+#define MAX_SLICE_COUNT 5
+
+struct ax3000_slice_info {
+ u32 out_mux;
+ u32 sgpio_mux;
+ u32 slice_mux;
+ u32 reg[MAX_OFFSET_REG];
+ u32 reg_ss[MAX_OFFSET_REG];
+ u32 preset;
+ u32 count;
+ u32 pos;
+};
+
+struct ax3000_sgpio {
+ u32 preset_value;
+ u32 count_value;
+ u32 pos_reg;
+ struct ax3000_slice_info
+ slices[MAX_SLICE_COUNT]; /* 0=clk,1=load,2=out,3=in,4=oe */
+ spinlock_t lock;
+ int ngpios;
+ int max_sgpio_pins;
+ int max_offset_regs;
+ struct gpio_chip chip;
+ u32 irq_unmasked[MAX_SGPIO_PINS];
+ int parent_irq;
+ struct regmap *regmap;
+ u32 regmap_base_offset;
+ struct sgpio_reg_offsets *regs;
+};
+
+static int sgpio_set_irq_type(struct irq_data *d, unsigned int type);
+static void sgpio_mask_irq(struct irq_data *d);
+static void sgpio_unmask_irq(struct irq_data *d);
+static void sgpio_irq_shutdown(struct irq_data *d);
+
+static const struct irq_chip axiado_sgpio_irqchip = {
+ .name = "axiado-sgpio",
+ .irq_mask = sgpio_mask_irq,
+ .irq_unmask = sgpio_unmask_irq,
+ .irq_set_type = sgpio_set_irq_type,
+ .irq_shutdown = sgpio_irq_shutdown,
+ .flags = IRQCHIP_IMMUTABLE | IRQCHIP_MASK_ON_SUSPEND,
+};
+
+static void ax3000_sgpio_set(struct gpio_chip *chip, unsigned int offset,
+ int value)
+{
+ struct ax3000_sgpio *sgpio = gpiochip_get_data(chip);
+ unsigned long flags;
+ u32 bank = (offset / 2) / 32;
+ u32 position = (offset / 2) % 32;
+
+ spin_lock_irqsave(&sgpio->lock, flags);
+ if (value)
+ sgpio->slices[2].reg_ss[bank] |= BIT(position);
+ else
+ sgpio->slices[2].reg_ss[bank] &= ~BIT(position);
+
+ spin_unlock_irqrestore(&sgpio->lock, flags);
+ regmap_write(sgpio->regmap,
+ sgpio->regmap_base_offset + sgpio->regs->dout_ss +
+ (bank * 4),
+ sgpio->slices[2].reg_ss[bank]);
+}
+
+static int ax3000_sgpio_get(struct gpio_chip *chip, unsigned int offset)
+{
+ struct ax3000_sgpio *sgpio = gpiochip_get_data(chip);
+ u32 bank = (offset / 2) / 32;
+ u32 position = (offset / 2) % 32;
+
+ if (offset % 2 == 0)
+ return !!(sgpio->slices[3].reg_ss[bank] & BIT(position));
+ else
+ return !!(sgpio->slices[2].reg_ss[bank] & BIT(position));
+}
+
+static int ax3000_sgpio_dir_in(struct gpio_chip *chip, unsigned int offset)
+{
+ if (!(offset % 2))
+ return 0;
+ else
+ return -EINVAL;
+}
+
+static int ax3000_sgpio_dir_out(struct gpio_chip *chip, unsigned int offset,
+ int value)
+{
+ if (offset % 2) {
+ if (chip->set)
+ chip->set(chip, offset, value);
+ return 0;
+ } else {
+ return -EINVAL;
+ }
+}
+
+static irqreturn_t sgpio_irq_handler(int irq, void *arg)
+{
+ struct ax3000_sgpio *sgpio = (struct ax3000_sgpio *)arg;
+ unsigned long flags;
+ u32 status, new_value;
+ u32 changed_value;
+ int i, bit, reg_ptr;
+
+ /* Read-on-clear (ACK) parent cause */
+ regmap_read(sgpio->regmap,
+ sgpio->regmap_base_offset + sgpio->regs->status, &status);
+ status >>= 16;
+
+ bool has_shifted_layout = (sgpio->max_offset_regs == MAX_OFFSET_REG);
+
+ reg_ptr = has_shifted_layout ? 16 - DIV_ROUND_UP(sgpio->ngpios, 32) : 0;
+
+ for (i = 0; i < DIV_ROUND_UP(sgpio->ngpios, 32); i++, reg_ptr++) {
+ if (status & BIT(reg_ptr)) {
+ regmap_read(sgpio->regmap,
+ sgpio->regmap_base_offset +
+ sgpio->regs->din_ss + (reg_ptr * 4),
+ &new_value);
+ spin_lock_irqsave(&sgpio->lock, flags);
+ changed_value = sgpio->slices[3].reg_ss[i] ^ new_value;
+ sgpio->slices[3].reg_ss[i] = new_value;
+ spin_unlock_irqrestore(&sgpio->lock, flags);
+
+ while (changed_value) {
+ bit = __ffs(changed_value);
+ changed_value &= ~BIT(bit);
+
+ irq_hw_number_t hwirq = i * 32 + bit;
+
+ if (sgpio->irq_unmasked[hwirq]) {
+ unsigned int child_irq;
+
+ child_irq = irq_find_mapping(sgpio->chip.irq.domain,
+ hwirq);
+
+ if (child_irq)
+ handle_nested_irq(child_irq);
+ }
+ }
+ }
+ }
+
+ return IRQ_HANDLED;
+}
+
+static void sgpio_hw_init(struct ax3000_sgpio *sgpio)
+{
+ u32 bank;
+ u32 position;
+ int i = 0;
+ bool has_shifted_layout = (sgpio->max_offset_regs == MAX_OFFSET_REG);
+
+ /* slice A0, Clock Pin - 0 */
+ regmap_write(sgpio->regmap,
+ sgpio->regmap_base_offset + sgpio->regs->mux_0, 0x306);
+ regmap_write(sgpio->regmap,
+ sgpio->regmap_base_offset + sgpio->regs->preset_0,
+ sgpio->preset_value);
+ regmap_write(sgpio->regmap,
+ sgpio->regmap_base_offset + sgpio->regs->count_0,
+ sgpio->count_value);
+ regmap_write(sgpio->regmap,
+ sgpio->regmap_base_offset + sgpio->regs->pos_0, 0x1f001f);
+
+ /* Slice B1, Data Load Pin - 1 */
+ bank = (sgpio->ngpios - 1) / 32;
+ position = (sgpio->ngpios - 1) % 32;
+
+ regmap_write(sgpio->regmap,
+ sgpio->regmap_base_offset + sgpio->regs->mux_1,
+ has_shifted_layout ? 0x30c : 0x304);
+
+ for (i = 0; i < bank; i++) {
+ regmap_write(sgpio->regmap,
+ sgpio->regmap_base_offset + sgpio->regs->ld +
+ (i * 4),
+ 0xffffffff);
+ regmap_write(sgpio->regmap,
+ sgpio->regmap_base_offset + sgpio->regs->ld_ss +
+ (i * 4),
+ 0xffffffff);
+ }
+
+ if (position) {
+ u32 val;
+
+ val = sgpio->slices[1].reg_ss[i];
+ val |= GENMASK(position - 1, 0);
+
+ regmap_write(sgpio->regmap,
+ sgpio->regmap_base_offset + sgpio->regs->ld +
+ (i * 4),
+ val);
+ regmap_write(sgpio->regmap,
+ sgpio->regmap_base_offset + sgpio->regs->ld_ss +
+ (i * 4),
+ val);
+ }
+
+ regmap_write(sgpio->regmap,
+ sgpio->regmap_base_offset + sgpio->regs->preset_1,
+ sgpio->preset_value);
+ regmap_write(sgpio->regmap,
+ sgpio->regmap_base_offset + sgpio->regs->count_1,
+ sgpio->count_value);
+ regmap_write(sgpio->regmap,
+ sgpio->regmap_base_offset + sgpio->regs->pos_1,
+ sgpio->pos_reg);
+
+ /* Slice C2, Data Out Pin - 2 */
+ bank = sgpio->ngpios / 32;
+ position = sgpio->ngpios % 32;
+
+ regmap_write(sgpio->regmap,
+ sgpio->regmap_base_offset + sgpio->regs->mux_2,
+ has_shifted_layout ? 0x30c : 0x304);
+
+ for (i = 0; i < bank; i++) {
+ regmap_write(sgpio->regmap,
+ sgpio->regmap_base_offset + sgpio->regs->dout +
+ (i * 4),
+ sgpio->slices[2].reg_ss[i]);
+ regmap_write(sgpio->regmap,
+ sgpio->regmap_base_offset + sgpio->regs->dout_ss +
+ (i * 4),
+ sgpio->slices[2].reg_ss[i]);
+ }
+
+ if (position) {
+ regmap_write(sgpio->regmap,
+ sgpio->regmap_base_offset + sgpio->regs->dout +
+ (i * 4),
+ sgpio->slices[2].reg_ss[i]);
+ regmap_write(sgpio->regmap,
+ sgpio->regmap_base_offset + sgpio->regs->dout_ss +
+ (i * 4),
+ sgpio->slices[2].reg_ss[i]);
+ }
+
+ regmap_write(sgpio->regmap,
+ sgpio->regmap_base_offset + sgpio->regs->preset_2,
+ sgpio->preset_value);
+ regmap_write(sgpio->regmap,
+ sgpio->regmap_base_offset + sgpio->regs->count_2,
+ sgpio->count_value);
+ regmap_write(sgpio->regmap,
+ sgpio->regmap_base_offset + sgpio->regs->pos_2,
+ sgpio->pos_reg);
+
+ /* Slice D3, Data In Pin - 3 */
+ regmap_write(sgpio->regmap,
+ sgpio->regmap_base_offset + sgpio->regs->mux_3, 0x14C);
+ regmap_write(sgpio->regmap,
+ sgpio->regmap_base_offset + sgpio->regs->preset_3,
+ sgpio->preset_value);
+ regmap_write(sgpio->regmap,
+ sgpio->regmap_base_offset + sgpio->regs->count_3,
+ sgpio->count_value);
+ regmap_write(sgpio->regmap,
+ sgpio->regmap_base_offset + sgpio->regs->pos_3,
+ sgpio->pos_reg);
+
+ /* Slice E4, Output Enable for respective pins */
+ regmap_write(sgpio->regmap,
+ sgpio->regmap_base_offset + sgpio->regs->mux_4,
+ has_shifted_layout ? 0x10c : 0x104);
+ regmap_write(sgpio->regmap, sgpio->regmap_base_offset + sgpio->regs->oe,
+ 0xffffffff);
+ regmap_write(sgpio->regmap,
+ sgpio->regmap_base_offset + sgpio->regs->oe_ss,
+ 0xffffffff);
+ regmap_write(sgpio->regmap,
+ sgpio->regmap_base_offset + sgpio->regs->preset_4,
+ sgpio->preset_value);
+ regmap_write(sgpio->regmap,
+ sgpio->regmap_base_offset + sgpio->regs->count_4,
+ sgpio->count_value);
+ regmap_write(sgpio->regmap,
+ sgpio->regmap_base_offset + sgpio->regs->pos_4, 0x1f001f);
+
+ regmap_write(sgpio->regmap,
+ sgpio->regmap_base_offset + sgpio->regs->mask, 0xdfff);
+
+ regmap_write(sgpio->regmap,
+ sgpio->regmap_base_offset + sgpio->regs->ctrl_en, 0xffff);
+ regmap_write(sgpio->regmap,
+ sgpio->regmap_base_offset + sgpio->regs->ctrl_en_pos,
+ 0xffff);
+}
+
+static int sgpio_set_irq_type(struct irq_data *d, unsigned int type)
+{
+ switch (type) {
+ case IRQ_TYPE_EDGE_BOTH:
+ case IRQ_TYPE_EDGE_RISING:
+ case IRQ_TYPE_EDGE_FALLING:
+ irq_set_handler_locked(d, handle_edge_irq);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static void sgpio_mask_irq(struct irq_data *d)
+{
+ struct gpio_chip *chip;
+ struct ax3000_sgpio *sgpio;
+ u32 irq_num;
+
+ chip = irq_data_get_irq_chip_data(d);
+ if (!chip) {
+ pr_err("Unable to get gpio_chip for IRQ\n");
+ return;
+ }
+
+ sgpio = gpiochip_get_data(chip);
+ if (!sgpio) {
+ pr_err("Unable to get chip data\n");
+ return;
+ }
+
+ irq_num = irqd_to_hwirq(d);
+ sgpio->irq_unmasked[irq_num / 2] = 0;
+}
+
+static void sgpio_unmask_irq(struct irq_data *d)
+{
+ struct gpio_chip *chip;
+ struct ax3000_sgpio *sgpio;
+ u32 irq_num;
+
+ chip = irq_data_get_irq_chip_data(d);
+ if (!chip) {
+ pr_err("Unable to get gpio_chip for IRQ\n");
+ return;
+ }
+
+ sgpio = gpiochip_get_data(chip);
+ if (!sgpio) {
+ pr_err("Unable to get chip data\n");
+ return;
+ }
+
+ irq_num = irqd_to_hwirq(d);
+ sgpio->irq_unmasked[irq_num / 2] = 1;
+}
+
+static void sgpio_irq_shutdown(struct irq_data *d)
+{
+ sgpio_mask_irq(d);
+}
+
+static int sgpio_probe(struct platform_device *pdev)
+{
+ int rc;
+ int irq;
+ int i;
+ const __be32 *prop;
+ struct gpio_irq_chip *girq;
+ struct ax3000_sgpio *sgpio;
+ u32 variant;
+ u32 dout_value;
+ u32 bus_frequency;
+ u32 apb_frequency;
+ int dout_reverse;
+
+ void __iomem *base;
+
+ const struct regmap_config regmap_config = {
+ .reg_bits = 32,
+ .val_bits = 32,
+ .reg_stride = 4,
+ };
+
+ sgpio = devm_kzalloc(&pdev->dev, sizeof(*sgpio), GFP_KERNEL);
+ if (!sgpio)
+ return -ENOMEM;
+
+ spin_lock_init(&sgpio->lock);
+
+ sgpio->regmap = dev_get_regmap(pdev->dev.parent, NULL);
+
+ if (sgpio->regmap) {
+ rc = of_property_read_u32(pdev->dev.of_node, "reg",
+ &sgpio->regmap_base_offset);
+ if (rc) {
+ dev_err(&pdev->dev, "Failed to read reg property: %d\n",
+ rc);
+ return rc;
+ }
+ dev_info(&pdev->dev, "Using regmap with base offset: 0x%x\n",
+ sgpio->regmap_base_offset);
+ } else {
+ base = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(base))
+ return PTR_ERR(base);
+
+ sgpio->regmap =
+ devm_regmap_init_mmio(&pdev->dev, base, ®map_config);
+
+ if (IS_ERR(sgpio->regmap))
+ return PTR_ERR(sgpio->regmap);
+
+ sgpio->regmap_base_offset = 0;
+
+ dev_info(&pdev->dev, "Using MMIO regmap\n");
+ }
+
+ rc = device_property_read_u32(&pdev->dev, "ngpios", &sgpio->ngpios);
+ if (rc < 0) {
+ dev_err(&pdev->dev, "Could not read ngpios property\n");
+ return -EINVAL;
+ }
+
+ if (device_property_read_u32(&pdev->dev, "design-variant", &variant)) {
+ dev_err(&pdev->dev, "design-variant not specified in DT\n");
+ return -EINVAL;
+ }
+
+ if (variant == 128) {
+ sgpio->regs = &sgpio_offsets_128;
+ sgpio->max_sgpio_pins = 128;
+ sgpio->max_offset_regs = 4;
+ } else if (variant == 512) {
+ sgpio->regs = &sgpio_offsets_512;
+ sgpio->max_sgpio_pins = 512;
+ sgpio->max_offset_regs = 16;
+ } else {
+ return -EINVAL;
+ }
+
+ if (sgpio->ngpios > sgpio->max_sgpio_pins) {
+ dev_err(&pdev->dev, "ngpio is greater than 512 pins\n");
+ return -EINVAL;
+ }
+
+ rc = device_property_read_u32(&pdev->dev, "bus-frequency",
+ &bus_frequency);
+ if (rc < 0) {
+ dev_err(&pdev->dev, "Could not read bus-frequency property\n");
+ return -EINVAL;
+ }
+
+ rc = device_property_read_u32(&pdev->dev, "apb-frequency",
+ &apb_frequency);
+ if (rc < 0) {
+ dev_err(&pdev->dev, "Could not read apb-frequency property\n");
+ return -EINVAL;
+ }
+
+ sgpio->preset_value = (apb_frequency / bus_frequency) - 1;
+ sgpio->count_value = sgpio->preset_value;
+
+ u32 pos;
+
+ pos = sgpio->ngpios - 1;
+ sgpio->pos_reg = (pos << 16) | pos;
+
+ prop = of_get_property(pdev->dev.of_node, "dout-init", NULL);
+ if (!prop) {
+ dev_err(&pdev->dev, "Failed to get dout-init\n");
+ return -EINVAL;
+ }
+
+ for (i = 0; i < sgpio->max_offset_regs; i++) {
+ sgpio->slices[2].reg_ss[i] = 0;
+ dout_value = be32_to_cpu(prop[i]);
+
+ for (dout_reverse = 0; dout_reverse < 32; ++dout_reverse) {
+ sgpio->slices[2].reg_ss[i] <<= 1;
+ sgpio->slices[2].reg_ss[i] |= (dout_value & 1);
+ dout_value >>= 1;
+ }
+ }
+
+ sgpio_hw_init(sgpio);
+
+ irq = platform_get_irq(pdev, 0);
+
+ if (irq < 0) {
+ dev_err(&pdev->dev, "Failed to get parent IRQ: %d\n", irq);
+ return irq;
+ }
+ /* Store parent IRQ for cleanup */
+ sgpio->parent_irq = irq;
+
+ rc = devm_request_threaded_irq(&pdev->dev, irq, NULL, sgpio_irq_handler,
+ IRQF_ONESHOT, "axiado-sgpio", sgpio);
+
+ if (rc < 0) {
+ dev_err(&pdev->dev, "Failed to request threaded IRQ %d: %d\n",
+ irq, rc);
+ return rc;
+ }
+
+ sgpio->chip.parent = &pdev->dev;
+ sgpio->chip.ngpio = sgpio->ngpios * 2;
+ sgpio->chip.owner = THIS_MODULE;
+ sgpio->chip.direction_input = ax3000_sgpio_dir_in;
+ sgpio->chip.direction_output = ax3000_sgpio_dir_out;
+ sgpio->chip.get = ax3000_sgpio_get;
+ sgpio->chip.set = ax3000_sgpio_set;
+ sgpio->chip.label = dev_name(&pdev->dev);
+ sgpio->chip.base = -1;
+
+ girq = &sgpio->chip.irq;
+
+ girq->chip = &axiado_sgpio_irqchip;
+ girq->handler = handle_edge_irq;
+ girq->default_type = IRQ_TYPE_NONE;
+ girq->num_parents = 1;
+ girq->parents =
+ devm_kcalloc(&pdev->dev, 1, sizeof(*girq->parents), GFP_KERNEL);
+ if (!girq->parents) {
+ dev_err(&pdev->dev, "Failed to allocate parents array\n");
+ return -ENOMEM;
+ }
+ girq->parents[0] = irq;
+
+ rc = devm_gpiochip_add_data(&pdev->dev, &sgpio->chip, sgpio);
+ if (rc < 0) {
+ dev_err(&pdev->dev, "Could not register gpiochip, %d\n", rc);
+ return rc;
+ }
+
+ /* Store driver data for remove() */
+ platform_set_drvdata(pdev, sgpio);
+ dev_info(&pdev->dev, "SGPIO registered with %d GPIOs\n",
+ sgpio->chip.ngpio);
+
+ return 0;
+}
+
+static int sgpio_remove(struct platform_device *pdev)
+{
+ struct ax3000_sgpio *sgpio = platform_get_drvdata(pdev);
+ int i;
+
+ if (!sgpio)
+ return 0;
+
+ /* Disable interrupts in hardware */
+ if (sgpio->regs) {
+ regmap_write(sgpio->regmap,
+ sgpio->regmap_base_offset + sgpio->regs->mask,
+ 0x0);
+ regmap_write(sgpio->regmap,
+ sgpio->regmap_base_offset + sgpio->regs->ctrl_en,
+ 0x0);
+ }
+
+ /* Disable and synchronize parent IRQ to avoid races with handlers */
+ if (sgpio->parent_irq >= 0) {
+ disable_irq(sgpio->parent_irq);
+ synchronize_irq(sgpio->parent_irq);
+ }
+
+ /* Ensure all GPIO IRQ handlers complete before removal */
+ if (sgpio->chip.irq.domain) {
+ struct irq_domain *domain = sgpio->chip.irq.domain;
+ unsigned int irq;
+ int hwirq;
+
+ for (hwirq = 0; hwirq < sgpio->chip.ngpio; hwirq++) {
+ irq = irq_find_mapping(domain, hwirq);
+ if (irq) {
+ disable_irq(irq);
+ synchronize_irq(irq);
+ }
+ }
+ }
+
+ /* Clear internal IRQ state */
+ for (i = 0; i < sgpio->max_sgpio_pins; i++)
+ sgpio->irq_unmasked[i] = 0;
+
+ return 0;
+}
+
+static const struct of_device_id ax_sgpio_match[] = {
+ { .compatible = "axiado,sgpio" },
+ {}
+};
+MODULE_DEVICE_TABLE(of, ax_sgpio_match);
+
+static struct platform_driver sgpio_driver = {
+ .driver = {
+ .name = "sgpio",
+ .owner = THIS_MODULE,
+ .of_match_table = ax_sgpio_match,
+ },
+ .probe = sgpio_probe,
+ .remove = sgpio_remove,
+};
+
+static int __init ax_sgpio_init(void)
+{
+ int ret;
+
+ ret = platform_driver_register(&sgpio_driver);
+ if (ret < 0) {
+ pr_err("Failed to register SGPIO driver\n");
+ return ret;
+ }
+
+ return 0;
+}
+
+static void __exit ax_sgpio_exit(void)
+{
+ platform_driver_unregister(&sgpio_driver);
+}
+
+module_init(ax_sgpio_init);
+module_exit(ax_sgpio_exit);
+
+MODULE_DESCRIPTION("Axiado Serial GPIO Driver");
+MODULE_AUTHOR("Axiado Corporation");
+MODULE_LICENSE("GPL");
--
2.34.1
^ permalink raw reply related
* [GIT PULL] arm64 updates for 7.1
From: Catalin Marinas @ 2026-04-14 13:47 UTC (permalink / raw)
To: Linus Torvalds
Cc: Will Deacon, Thomas Gleixner, James Morse, Ben Horgan,
linux-arm-kernel, linux-kernel
Hi Linus,
Please pull the first round of arm64 updates for 7.1. The biggest
changes are MPAM enablement in drivers/resctrl and new PMU support under
drivers/perf. On the core side, FEAT_LSUI lets futex atomic operations
with EL0 permissions, avoiding PAN toggling. The rest is mostly TLB
invalidation refactoring, further generic entry work, sysreg updates and
a few fixes. More details in the tag.
The generic entry patches touch include/linux/*entry* and kernel/entry/*
as they are based on a tag from tip. Not sure when Thomas will send them
your way, so sending the arm64 pull request in the meantime.
There are a couple of trivial conflicts against mainline with the KVM
tree and an arm64 fix. I solved them as below:
-------------8<-----------------------------
diff --cc arch/arm64/kernel/rsi.c
index 9e846ce4ef9c,6e883bc43186..92160f2e57ff
--- a/arch/arm64/kernel/rsi.c
+++ b/arch/arm64/kernel/rsi.c
@@@ -145,9 -144,9 +145,9 @@@ void __init arm64_rsi_init(void
return;
if (!rsi_version_matches())
return;
- if (WARN_ON(rsi_get_realm_config(&config)))
+ if (WARN_ON(rsi_get_realm_config(lm_alias(&config))))
return;
- prot_ns_shared = BIT(config.ipa_bits - 1);
+ prot_ns_shared = __phys_to_pte_val(BIT(config.ipa_bits - 1));
if (arm64_ioremap_prot_hook_register(realm_ioremap_hook))
return;
diff --cc arch/arm64/kvm/at.c
index a024d9a770dc,1adf88a57328..9f8f0ae8e86e
--- a/arch/arm64/kvm/at.c
+++ b/arch/arm64/kvm/at.c
@@@ -1753,8 -1785,10 +1783,10 @@@ int __kvm_at_swap_desc(struct kvm *kvm
if (!writable)
return -EPERM;
- ptep = (u64 __user *)hva + offset;
+ ptep = (void __user *)hva + offset;
- if (cpus_have_final_cap(ARM64_HAS_LSE_ATOMICS))
+ if (cpus_have_final_cap(ARM64_HAS_LSUI))
+ r = __lsui_swap_desc(ptep, old, new);
+ else if (cpus_have_final_cap(ARM64_HAS_LSE_ATOMICS))
r = __lse_swap_desc(ptep, old, new);
else
r = __llsc_swap_desc(ptep, old, new);
-------------8<-----------------------------
Thanks.
The following changes since commit 1f318b96cc84d7c2ab792fcc0bfd42a7ca890681:
Linux 7.0-rc3 (2026-03-08 16:56:54 -0700)
are available in the Git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux tags/arm64-upstream
for you to fetch changes up to 480a9e57cceaf42db6ff874dbfe91de201935035:
Merge branches 'for-next/misc', 'for-next/tlbflush', 'for-next/ttbr-macros-cleanup', 'for-next/kselftest', 'for-next/feat_lsui', 'for-next/mpam', 'for-next/hotplug-batched-tlbi', 'for-next/bbml2-fixes', 'for-next/sysreg', 'for-next/generic-entry' and 'for-next/acpi', remote-tracking branches 'arm64/for-next/perf' and 'arm64/for-next/read-once' into for-next/core (2026-04-10 14:22:24 +0100)
----------------------------------------------------------------
arm64 updates for 7.1:
Core features:
- Add support for FEAT_LSUI, allowing futex atomic operations without
toggling Privileged Access Never (PAN)
- Further refactor the arm64 exception handling code towards the
generic entry infrastructure
- Optimise __READ_ONCE() with CONFIG_LTO=y and allow alias analysis
through it
Memory management:
- Refactor the arm64 TLB invalidation API and implementation for better
control over barrier placement and level-hinted invalidation
- Enable batched TLB flushes during memory hot-unplug
- Fix rodata=full block mapping support for realm guests (when
BBML2_NOABORT is available)
Perf and PMU:
- Add support for a whole bunch of system PMUs featured in NVIDIA's
Tegra410 SoC (cspmu extensions for the fabric and PCIe, new drivers
for CPU/C2C memory latency PMUs)
- Clean up iomem resource handling in the Arm CMN driver
- Fix signedness handling of AA64DFR0.{PMUVer,PerfMon}
MPAM (Memory Partitioning And Monitoring):
- Add architecture context-switch and hiding of the feature from KVM
- Add interface to allow MPAM to be exposed to user-space using resctrl
- Add errata workaround for some existing platforms
- Add documentation for using MPAM and what shape of platforms can use
resctrl
Miscellaneous:
- Check DAIF (and PMR, where relevant) at task-switch time
- Skip TFSR_EL1 checks and barriers in synchronous MTE tag check mode
(only relevant to asynchronous or asymmetric tag check modes)
- Remove a duplicate allocation in the kexec code
- Remove redundant save/restore of SCS SP on entry to/from EL0
- Generate the KERNEL_HWCAP_ definitions from the arm64 hwcap
descriptions
- Add kselftest coverage for cmpbr_sigill()
- Update sysreg definitions
----------------------------------------------------------------
Aneesh Kumar K.V (Arm) (1):
arm64: rsi: use linear-map alias for realm config buffer
Anshuman Khandual (5):
arm64/mm: Describe TTBR1_BADDR_4852_OFFSET
arm64/mm: Directly use TTBRx_EL1_ASID_MASK
arm64/mm: Directly use TTBRx_EL1_CnP
arm64/mm: Enable batched TLB flush in unmap_hotplug_range()
arm64/mm: Reject memory removal that splits a kernel leaf mapping
Ben Horgan (11):
arm_mpam: Reset when feature configuration bit unset
arm64/sysreg: Add MPAMSM_EL1 register
KVM: arm64: Preserve host MPAM configuration when changing traps
KVM: arm64: Make MPAMSM_EL1 accesses UNDEF
arm64: mpam: Drop the CONFIG_EXPERT restriction
arm64: mpam: Initialise and context switch the MPAMSM_EL1 register
arm_mpam: resctrl: Hide CDP emulation behind CONFIG_EXPERT
arm_mpam: resctrl: Add rmid index helpers
arm_mpam: resctrl: Wait for cacheinfo to be ready
arm_mpam: resctrl: Add monitor initialisation and domain boilerplate
arm64: mpam: Add initial MPAM documentation
Besar Wicaksono (7):
perf/arm_cspmu: nvidia: Rename doc to Tegra241
perf/arm_cspmu: nvidia: Add Tegra410 UCF PMU
perf/arm_cspmu: Add arm_cspmu_acpi_dev_get
perf/arm_cspmu: nvidia: Add Tegra410 PCIE PMU
perf/arm_cspmu: nvidia: Add Tegra410 PCIE-TGT PMU
perf: add NVIDIA Tegra410 CPU Memory Latency PMU
perf: add NVIDIA Tegra410 C2C PMU
Catalin Marinas (1):
Merge branches 'for-next/misc', 'for-next/tlbflush', 'for-next/ttbr-macros-cleanup', 'for-next/kselftest', 'for-next/feat_lsui', 'for-next/mpam', 'for-next/hotplug-batched-tlbi', 'for-next/bbml2-fixes', 'for-next/sysreg', 'for-next/generic-entry' and 'for-next/acpi', remote-tracking branches 'arm64/for-next/perf' and 'arm64/for-next/read-once' into for-next/core
Chen Ni (1):
perf/arm-cmn: Fix incorrect error check for devm_ioremap()
Dave Martin (2):
arm_mpam: resctrl: Convert to/from MPAMs fixed-point formats
arm_mpam: resctrl: Add kunit test for control format conversions
Haoyu Lu (1):
ACPI: AGDI: fix missing newline in error message
James Clark (3):
KVM: arm64: Read PMUVer as unsigned
arm64: cpufeature: Make PMUVer and PerfMon unsigned
arm64: cpufeature: Use pmuv3_implemented() function
James Morse (22):
arm64: mpam: Context switch the MPAM registers
arm64: mpam: Re-initialise MPAM regs when CPU comes online
arm64: mpam: Advertise the CPUs MPAM limits to the driver
arm64: mpam: Add cpu_pm notifier to restore MPAM sysregs
arm64: mpam: Add helpers to change a task or cpu's MPAM PARTID/PMG values
KVM: arm64: Force guest EL1 to use user-space's partid configuration
arm_mpam: resctrl: Add boilerplate cpuhp and domain allocation
arm_mpam: resctrl: Pick the caches we will use as resctrl resources
arm_mpam: resctrl: Implement resctrl_arch_reset_all_ctrls()
arm_mpam: resctrl: Add resctrl_arch_get_config()
arm_mpam: resctrl: Implement helpers to update configuration
arm_mpam: resctrl: Add plumbing against arm64 task and cpu hooks
arm_mpam: resctrl: Add CDP emulation
arm_mpam: resctrl: Add support for 'MB' resource
arm_mpam: resctrl: Add support for csu counters
arm_mpam: resctrl: Allow resctrl to allocate monitors
arm_mpam: resctrl: Add resctrl_arch_rmid_read()
arm_mpam: resctrl: Update the rmid reallocation limit
arm_mpam: resctrl: Add empty definitions for assorted resctrl functions
arm64: mpam: Select ARCH_HAS_CPU_RESCTRL
arm_mpam: resctrl: Call resctrl_init() on platforms that can support resctrl
arm_mpam: Quirk CMN-650's CSU NRDY behaviour
Jisheng Zhang (1):
arm64: remove ARCH_INLINE_*
Kevin Brodsky (1):
arm64: mm: Use generic enum pgtable_level
Marco Elver (2):
arm64: Optimize __READ_ONCE() with CONFIG_LTO=y
arm64, compiler-context-analysis: Permit alias analysis through __READ_ONCE() with CONFIG_LTO=y
Mark Brown (7):
arm64/sysreg: Update SMIDR_EL1 to DDI0601 2025-06
arm64/hwcap: Generate the KERNEL_HWCAP_ definitions for the hwcaps
arm64/sysreg: Update ID_AA64ISAR0_EL1 description to DDI0601 2025-12
arm64/sysreg: Update ID_AA64ISAR2_EL1 description to DDI0601 2025-12
arm64/sysreg: Update ID_AA64FPFR0_EL1 description to DDI0601 2025-12
arm64/sysreg: Update ID_AA64ZFR0_EL1 description to DDI0601 2025-12
arm64/sysreg: Update ID_AA64SMFR0_EL1 description to DDI0601 2025-12
Mark Rutland (10):
entry: Fix stale comment for irqentry_enter()
entry: Remove local_irq_{enable,disable}_exit_to_user()
entry: Move irqentry_enter() prototype later
entry: Split kernel mode logic from irqentry_{enter,exit}()
entry: Split preemption from irqentry_exit_to_kernel_mode()
arm64: entry: Don't preempt with SError or Debug masked
arm64: entry: Consistently prefix arm64-specific wrappers
arm64: entry: Use irqentry_{enter_from,exit_to}_kernel_mode()
arm64: entry: Use split preemption logic
arm64: Check DAIF (and PMR) at task-switch time
Michael Ugrin (1):
arm64: Kconfig: fix duplicate word in CMDLINE help text
Muhammad Usama Anjum (1):
arm64: mte: Skip TFSR_EL1 checks and barriers in synchronous tag check mode
Nathan Chancellor (1):
perf/arm-cmn: Fix resource_size_t printk specifier in arm_cmn_init_dtc()
Robin Murphy (1):
perf/arm-cmn: Stop claiming entire iomem region
Ryan Roberts (13):
arm64: mm: Re-implement the __tlbi_level macro as a C function
arm64: mm: Introduce a C wrapper for by-range TLB invalidation
arm64: mm: Implicitly invalidate user ASID based on TLBI operation
arm64: mm: Re-implement the __flush_tlb_range_op macro in C
arm64: mm: Refactor flush_tlb_page() to use __tlbi_level_asid()
arm64: mm: Refactor __flush_tlb_range() to take flags
arm64: mm: More flags for __flush_tlb_range()
arm64: mm: Wrap flush_tlb_page() around __do_flush_tlb_range()
arm64: mm: Provide level hint for flush_tlb_page()
arm64: mm: __ptep_set_access_flags must hint correct TTL
arm64: mm: Fix rodata=full block mapping support for realm guests
arm64: mm: Handle invalid large leaf mappings correctly
arm64: mm: Remove pmd_sect() and pud_sect()
Shanker Donthineni (4):
arm_mpam: Add quirk framework
arm_mpam: Add workaround for T241-MPAM-1
arm_mpam: Add workaround for T241-MPAM-4
arm_mpam: Add workaround for T241-MPAM-6
Wang Wensheng (1):
arm64: kexec: Remove duplicate allocation for trans_pgd
Will Deacon (5):
arm64: scs: Remove redundant save/restore of SCS SP on entry to/from EL0
arm64: mm: Push __TLBI_VADDR() into __tlbi_level()
arm64: mm: Inline __TLBI_VADDR_RANGE() into __tlbi_range()
arm64: mm: Simplify __TLBI_RANGE_NUM() macro
arm64: mm: Simplify __flush_tlb_range_limit_excess()
Yeoreum Yun (8):
arm64: cpufeature: Add FEAT_LSUI
KVM: arm64: Expose FEAT_LSUI to guests
KVM: arm64: kselftest: set_id_regs: Add test for FEAT_LSUI
arm64: futex: Refactor futex atomic operation
arm64: futex: Support futex with FEAT_LSUI
KVM: arm64: Use CAST instruction for swapping guest descriptor
arm64: Kconfig: Add support for LSUI
arm64: armv8_deprecated: Disable swp emulation when FEAT_LSUI present
Yifan Wu (1):
selftests/arm64: Implement cmpbr_sigill() to hwcap test
Zeng Heng (1):
arm_mpam: Ensure in_reset_state is false after applying configuration
Documentation/admin-guide/perf/index.rst | 3 +-
.../{nvidia-pmu.rst => nvidia-tegra241-pmu.rst} | 8 +-
.../admin-guide/perf/nvidia-tegra410-pmu.rst | 522 ++++++
Documentation/arch/arm64/index.rst | 1 +
Documentation/arch/arm64/mpam.rst | 72 +
Documentation/arch/arm64/silicon-errata.rst | 9 +
arch/arm/include/asm/arm_pmuv3.h | 7 +
arch/arm64/Kconfig | 54 +-
arch/arm64/include/asm/asm-uaccess.h | 2 +-
arch/arm64/include/asm/cpucaps.h | 2 +
arch/arm64/include/asm/el2_setup.h | 3 +-
arch/arm64/include/asm/futex.h | 311 +++-
arch/arm64/include/asm/hugetlb.h | 12 +-
arch/arm64/include/asm/hwcap.h | 120 +-
arch/arm64/include/asm/lsui.h | 27 +
arch/arm64/include/asm/mmu.h | 10 +-
arch/arm64/include/asm/mmu_context.h | 3 +-
arch/arm64/include/asm/mpam.h | 96 ++
arch/arm64/include/asm/mte.h | 6 +
arch/arm64/include/asm/pgtable-hwdef.h | 9 +-
arch/arm64/include/asm/pgtable-prot.h | 2 +
arch/arm64/include/asm/pgtable.h | 60 +-
arch/arm64/include/asm/resctrl.h | 2 +
arch/arm64/include/asm/rwonce.h | 24 +-
arch/arm64/include/asm/scs.h | 8 +
arch/arm64/include/asm/thread_info.h | 3 +
arch/arm64/include/asm/tlb.h | 6 +-
arch/arm64/include/asm/tlbflush.h | 471 +++---
arch/arm64/include/asm/uaccess.h | 6 +-
arch/arm64/kernel/Makefile | 1 +
arch/arm64/kernel/armv8_deprecated.c | 14 +
arch/arm64/kernel/cpufeature.c | 47 +-
arch/arm64/kernel/entry-common.c | 52 +-
arch/arm64/kernel/entry.S | 6 +-
arch/arm64/kernel/machine_kexec.c | 3 -
arch/arm64/kernel/mpam.c | 62 +
arch/arm64/kernel/mte.c | 10 +-
arch/arm64/kernel/process.c | 32 +
arch/arm64/kernel/rsi.c | 2 +-
arch/arm64/kernel/sys_compat.c | 2 +-
arch/arm64/kvm/at.c | 34 +-
arch/arm64/kvm/debug.c | 5 +-
arch/arm64/kvm/hyp/include/hyp/switch.h | 12 +-
arch/arm64/kvm/hyp/nvhe/hyp-init.S | 4 +-
arch/arm64/kvm/hyp/nvhe/mm.c | 2 +-
arch/arm64/kvm/hyp/nvhe/tlb.c | 2 -
arch/arm64/kvm/hyp/pgtable.c | 4 +-
arch/arm64/kvm/hyp/vhe/sysreg-sr.c | 16 +
arch/arm64/kvm/hyp/vhe/tlb.c | 2 -
arch/arm64/kvm/sys_regs.c | 5 +-
arch/arm64/mm/context.c | 8 +-
arch/arm64/mm/contpte.c | 12 +-
arch/arm64/mm/fault.c | 30 +-
arch/arm64/mm/hugetlbpage.c | 10 +-
arch/arm64/mm/init.c | 9 +-
arch/arm64/mm/mmu.c | 286 +++-
arch/arm64/mm/pageattr.c | 50 +-
arch/arm64/mm/trans_pgd.c | 42 +-
arch/arm64/tools/Makefile | 8 +-
arch/arm64/tools/cpucaps | 1 +
arch/arm64/tools/gen-kernel-hwcaps.sh | 23 +
arch/arm64/tools/sysreg | 36 +-
drivers/acpi/arm64/agdi.c | 2 +-
drivers/perf/Kconfig | 14 +
drivers/perf/Makefile | 2 +
drivers/perf/arm-cmn.c | 70 +-
drivers/perf/arm_cspmu/arm_cspmu.c | 19 +-
drivers/perf/arm_cspmu/arm_cspmu.h | 17 +-
drivers/perf/arm_cspmu/nvidia_cspmu.c | 618 ++++++-
drivers/perf/nvidia_t410_c2c_pmu.c | 1051 ++++++++++++
drivers/perf/nvidia_t410_cmem_latency_pmu.c | 736 +++++++++
drivers/resctrl/Kconfig | 9 +-
drivers/resctrl/Makefile | 1 +
drivers/resctrl/mpam_devices.c | 305 +++-
drivers/resctrl/mpam_internal.h | 108 +-
drivers/resctrl/mpam_resctrl.c | 1704 ++++++++++++++++++++
drivers/resctrl/test_mpam_resctrl.c | 315 ++++
include/linux/arm_mpam.h | 32 +
include/linux/entry-common.h | 2 +-
include/linux/irq-entry-common.h | 256 ++-
kernel/entry/common.c | 107 +-
tools/testing/selftests/arm64/abi/hwcap.c | 3 +-
tools/testing/selftests/kvm/arm64/set_id_regs.c | 1 +
83 files changed, 7117 insertions(+), 946 deletions(-)
rename Documentation/admin-guide/perf/{nvidia-pmu.rst => nvidia-tegra241-pmu.rst} (98%)
create mode 100644 Documentation/admin-guide/perf/nvidia-tegra410-pmu.rst
create mode 100644 Documentation/arch/arm64/mpam.rst
create mode 100644 arch/arm64/include/asm/lsui.h
create mode 100644 arch/arm64/include/asm/mpam.h
create mode 100644 arch/arm64/include/asm/resctrl.h
create mode 100644 arch/arm64/kernel/mpam.c
create mode 100644 arch/arm64/tools/gen-kernel-hwcaps.sh
create mode 100644 drivers/perf/nvidia_t410_c2c_pmu.c
create mode 100644 drivers/perf/nvidia_t410_cmem_latency_pmu.c
create mode 100644 drivers/resctrl/mpam_resctrl.c
create mode 100644 drivers/resctrl/test_mpam_resctrl.c
--
Catalin
^ permalink raw reply
* Re: [PATCH RFC bpf-next 8/8] selftests/bpf: add tests to validate KASAN on JIT programs
From: Alexis Lothoré @ 2026-04-14 13:43 UTC (permalink / raw)
To: Andrey Konovalov, Alexis Lothoré (eBPF Foundation)
Cc: Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko,
Martin KaFai Lau, Eduard Zingerman, Kumar Kartikeya Dwivedi,
Song Liu, Yonghong Song, Jiri Olsa, John Fastabend,
David S. Miller, David Ahern, Thomas Gleixner, Ingo Molnar,
Borislav Petkov, Dave Hansen, x86, H. Peter Anvin, Shuah Khan,
Maxime Coquelin, Alexandre Torgue, Andrey Ryabinin,
Alexander Potapenko, Dmitry Vyukov, Vincenzo Frascino,
Andrew Morton, ebpf, Bastien Curutchet, Thomas Petazzoni,
Xu Kuohai, bpf, linux-kernel, netdev, linux-kselftest,
linux-stm32, linux-arm-kernel, kasan-dev, linux-mm
In-Reply-To: <CA+fCnZekgcEgsZnRrOB=+HoG=neRg=oLTt2jStyrPJ6mYf2ctQ@mail.gmail.com>
On Tue Apr 14, 2026 at 12:20 AM CEST, Andrey Konovalov wrote:
> On Mon, Apr 13, 2026 at 8:29 PM Alexis Lothoré (eBPF Foundation)
> <alexis.lothore@bootlin.com> wrote:
>>
>> Add a basic KASAN test runner that loads and test-run programs that can
>> trigger memory management bugs. The test captures kernel logs and ensure
>> that the expected KASAN splat is emitted by searching for the
>> corresponding first lines in the report.
>>
>> This version implements two faulty programs triggering either a
>> user-after-free, or an out-of-bounds memory usage. The bugs are
>> triggered thanks to some dedicated kfuncs in bpf_testmod.c, but two
>> different techniques are used, as some cases can be quite hard to
>> trigger in a pure "black box" approach:
>> - for reads, we can make the used kfuncs return some faulty pointers
>> that ebpf programs will manipulate, they will generate legitimate
>> kasan reports as a consequence
>> - applying the same trick for faulty writes is harder, as ebpf programs
>> can't write kernel data freely. So ebpf programs can call another
>> specific testing kfunc that will alter the shadow memory matching the
>> passed memory (eg: a map). When the program will try to write to the
>> corresponding memory, it will trigger a report as well.
>>
>> Signed-off-by: Alexis Lothoré (eBPF Foundation) <alexis.lothore@bootlin.com>
>> ---
>> The way of bringing kasan_poison into bpf_testmod is definitely not
>> ideal. But I would like to validate the testing approach (triggering
>> real faulty accesses, which is hard on some cases, VS manually poisoning
>> BPF-manipulated memory) before eventually making clean bridges between
>> KASAN APIs and bpf_testmod.c, if the latter approach is the valid one.
>
> Would it make sense to put these tests into KASAN KUnit tests in
> mm/kasan/kasan_test_c.c? I assume there is a kernel API to JIT BPF
> programs from the kernel itself?
Possibly indeed, but I think one important use case will be the
possibility to run those tests in BPF CI ([1]), and this depends on
those tests being integrated in the test_progs framework
(tools/testing/selftests/bpf)
[1] https://github.com/kernel-patches/bpf/pulls
> There, you can just call kasan_poison(), some tests already do this.
> And you can also extend the KASAN KUnit test framework to find out
> whether the bad access is a read or write, if you want to check this.
Alexis
--
Alexis Lothoré, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply
* Re: [PATCH 2/3] pmdomain: core: add support for power-domains-child-ids
From: Ulf Hansson @ 2026-04-14 13:42 UTC (permalink / raw)
To: Kevin Hilman
Cc: Rob Herring, Geert Uytterhoeven, linux-pm, devicetree,
linux-kernel, arm-scmi, linux-arm-kernel
In-Reply-To: <7hqzomqwpv.fsf@baylibre.com>
On Sat, 11 Apr 2026 at 00:25, Kevin Hilman <khilman@baylibre.com> wrote:
>
> Ulf Hansson <ulf.hansson@linaro.org> writes:
>
> > On Fri, 10 Apr 2026 at 02:45, Kevin Hilman <khilman@baylibre.com> wrote:
> >>
> >> Ulf Hansson <ulf.hansson@linaro.org> writes:
> >>
> >> > On Wed, 11 Mar 2026 at 01:19, Kevin Hilman (TI) <khilman@baylibre.com> wrote:
> >> >>
> >> >> Currently, PM domains can only support hierarchy for simple
> >> >> providers (e.g. ones with #power-domain-cells = 0).
> >> >>
> >> >> Add support for oncell providers as well by adding a new property
> >> >> `power-domains-child-ids` to describe the parent/child relationship.
> >> >>
> >> >> For example, an SCMI PM domain provider has multiple domains, each of
> >> >> which might be a child of diffeent parent domains. In this example,
> >> >> the parent domains are MAIN_PD and WKUP_PD:
> >> >>
> >> >> scmi_pds: protocol@11 {
> >> >> reg = <0x11>;
> >> >> #power-domain-cells = <1>;
> >> >> power-domains = <&MAIN_PD>, <&WKUP_PD>;
> >> >> power-domains-child-ids = <15>, <19>;
> >> >> };
> >> >>
> >> >> With this example using the new property, SCMI PM domain 15 becomes a
> >> >> child domain of MAIN_PD, and SCMI domain 19 becomes a child domain of
> >> >> WKUP_PD.
> >> >>
> >> >> To support this feature, add two new core functions
> >> >>
> >> >> - of_genpd_add_child_ids()
> >> >> - of_genpd_remove_child_ids()
> >> >>
> >> >> which can be called by pmdomain providers to add/remove child domains
> >> >> if they support the new property power-domains-child-ids.
> >> >>
> >> >> Signed-off-by: Kevin Hilman (TI) <khilman@baylibre.com>
> >> >
> >> > Thanks for working on this! It certainly is a missing feature!
> >>
> >> You're welcome, thanks for the detailed review.
> >>
> >> >> ---
> >> >> drivers/pmdomain/core.c | 169 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> >> >> include/linux/pm_domain.h | 16 ++++++++++++++++
> >> >> 2 files changed, 185 insertions(+)
> >> >>
> >> >> diff --git a/drivers/pmdomain/core.c b/drivers/pmdomain/core.c
> >> >> index 61c2277c9ce3..acb45dd540b7 100644
> >> >> --- a/drivers/pmdomain/core.c
> >> >> +++ b/drivers/pmdomain/core.c
> >> >> @@ -2909,6 +2909,175 @@ static struct generic_pm_domain *genpd_get_from_provider(
> >> >> return genpd;
> >> >> }
> >> >>
> >> >> +/**
> >> >> + * of_genpd_add_child_ids() - Parse power-domains-child-ids property
> >> >> + * @np: Device node pointer associated with the PM domain provider.
> >> >> + * @data: Pointer to the onecell data associated with the PM domain provider.
> >> >> + *
> >> >> + * Parse the power-domains and power-domains-child-ids properties to establish
> >> >> + * parent-child relationships for PM domains. The power-domains property lists
> >> >> + * parent domains, and power-domains-child-ids lists which child domain IDs
> >> >> + * should be associated with each parent.
> >> >> + *
> >> >> + * Returns 0 on success, -ENOENT if properties don't exist, or negative error code.
> >> >
> >> > I think we should avoid returning specific error codes for specific
> >> > errors, simply because it usually becomes messy.
> >> >
> >> > If I understand correctly the intent here is to allow the caller to
> >> > check for -ENOENT and potentially avoid bailing out as it may not
> >> > really be an error, right?
> >>
> >> Right, -ENOENT is not an error of parsing, it's to indicate that there
> >> are no child-ids to be parsed.
> >>
> >> > Perhaps a better option is to return the number of children for whom
> >> > we successfully assigned parents. Hence 0 or a positive value allows
> >> > the caller to understand what happened. More importantly, a negative
> >> > error code then really becomes an error for the caller to consider.
> >>
> >> I explored this a bit, but it gets messy quick. It means we have to
> >> track cases where only some of the children were added as well as when
> >> all children were added. Personally, I think this should be an "all or
> >> nothing" thing. If all the children cannot be parsed/added, then none
> >> of them should be added.
> >>
> >> This also allows the remove to not have to care about how many were
> >> added, and just remove them all, with the additional benefit of not
> >> having to track the state of how many children were successfully added.
> >>
> >
> > I fully agree, it should be all or nothing. Failing with one
> > child/parent should end up with an error code being returned.
> >
> > That said, it still seems to make perfect sense to return the number
> > of children for whom we assigned parents for, no?
>
> No, because what will the caller use that number for? If we are
> assuming "all or nothing", what would we use it for (other than a debug print?)
>
> It also makes it a bit confusing what a zero return value means. Does
> that mean success? Or that zero children were added (which would be
> fail.)
>
> I prefer to keep it as is.
In that case, how should we treat the scenario where the device node
lacks a "power-domains-child-ids" property? In some cases it is
probably fine, while in others it may not be.
I guess the caller of of_genpd_add_child_ids(), would then need to
pre-parse for the "power-domains-child-ids" property before deciding
to call of_genpd_add_child_ids().
At least, we don't of_genpd_add_child_ids() to return an error code if
there is no "power-domains-child-ids" in the device node, as that
would just confuse the caller.
Kind regards
Uffe
^ permalink raw reply
* [PATCH v3] arm64: defconfig: Enable Rockchip video decoder
From: Detlev Casanova @ 2026-04-14 13:37 UTC (permalink / raw)
To: linux-kernel, linux-arm-kernel, kernel, linux-rockchip; +Cc: Detlev Casanova
The Rockchip video decoder (rkvdec) provides hardware-accelerated video
decoding on Rockchip SoCs. Enable it as a module so that users of these
widely used platforms get video decoding support out of the box.
Signed-off-by: Detlev Casanova <detlev.casanova@collabora.com>
---
Changes in v3:
- Update commit message
- Link to v2: https://patch.msgid.link/20260326-rkvdec-add-defconfig-v2-1-d65c296da9ba@collabora.com
Changes in v2:
- Update commit message
- Add missing CCs
- Link to v1: https://patch.msgid.link/20260325-rkvdec-add-defconfig-v1-1-89a55d3bb5c4@collabora.com
---
arch/arm64/configs/defconfig | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index b67d5b1fc45b..4b3f31cb4a94 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -931,6 +931,7 @@ CONFIG_VIDEO_RENESAS_VSP1=m
CONFIG_VIDEO_RCAR_DRIF=m
CONFIG_VIDEO_ROCKCHIP_CIF=m
CONFIG_VIDEO_ROCKCHIP_RGA=m
+CONFIG_VIDEO_ROCKCHIP_VDEC=m
CONFIG_VIDEO_SAMSUNG_EXYNOS_GSC=m
CONFIG_VIDEO_SAMSUNG_S5P_JPEG=m
CONFIG_VIDEO_SAMSUNG_S5P_MFC=m
---
base-commit: bbeb83d3182abe0d245318e274e8531e5dd7a948
change-id: 20260325-rkvdec-add-defconfig-eaa11ab14f1f
Best regards,
--
Detlev Casanova <detlev.casanova@collabora.com>
^ permalink raw reply related
* Re: [PATCH 0/3] arm64/virt: Add Arm CCA measurement register support
From: Jason Gunthorpe @ 2026-04-14 13:35 UTC (permalink / raw)
To: Suzuki K Poulose
Cc: Sami Mujawar, Dan Williams, linux-arm-kernel, linux-kernel,
catalin.marinas, will, thuth, steven.price, gshan, YeoReum.Yun,
cedric.xing, Dan Williams, Dionna Glaze, Aneesh Kumar K . V,
Alexey Kardashevskiy, linux-coco@lists.linux.dev
In-Reply-To: <a1831d3d-af31-4fa7-b107-f4001841f051@arm.com>
On Tue, Apr 14, 2026 at 02:26:58PM +0100, Suzuki K Poulose wrote:
> On 14/04/2026 13:29, Jason Gunthorpe wrote:
> > On Tue, Apr 14, 2026 at 11:10:51AM +0100, Suzuki K Poulose wrote:
> >
> > > > Isn't this also sort of incomplete? Doesn't anything serious need
> > > > signed measurements? Isnt't there alot more data that comes out of RMM
> > > > than just a few measurement registers?
> > > As mentioned above, this series adds the support for Runtime Extendible
> > > Measurements (REM in CCA, RTMR on TDX). The RIM+Platform Attestation is
> > > already provided via the TSM_REPORT
> >
> > Okay, but what actual use is this?
> >
>
> Good point. This REMs are planned to be used for EFI_CC_MEASUREMENT_PROTOCOL
> as described below:
>
> https://github.com/tianocore/edk2/issues/11383
So this is tying it to the same FW event log that TPM uses.
I think that strengthens my point this should all be uninform. TPM
drivers are directly exposing the event log today, but I guess that
needs generalization if non-TPM drivers are going to present it as
well.
How do you imagine getting and manipulating the EFI event log to use
with this?
Jason
^ permalink raw reply
* Re: [PATCH v1 1/2] arm_mpam: resctrl: Fix broken error path in mpam_resctrl_alloc_domain()
From: Ben Horgan @ 2026-04-14 13:31 UTC (permalink / raw)
Cc: Dan Carpenter, Dan Carpenter, James Morse, Reinette Chatre,
Fenghua Yu, lkml, linux-arm-kernel
In-Reply-To: <20260414132758.196874-2-ben.horgan@arm.com>
Apologies, I just sent the same patch twice with different subjects. This one can be ignored.
Thanks,
Ben
On 4/14/26 14:27, Ben Horgan wrote:
> Dan Carpenter reports that, in mpam_resctrl_alloc_domain(), any_mon_comp is
> used in an 'if' condition when it may be uninitialized. Initialize it to
> NULL so that the check behaves correctly when no monitor components are
> found.
>
> Reported-by: Dan Carpenter <error27@gmail.com>
> Fixes: 264c285999fc ("arm_mpam: resctrl: Add monitor initialisation and domain boilerplate")
> Signed-off-by: Ben Horgan <ben.horgan@arm.com>
> ---
> drivers/resctrl/mpam_resctrl.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/resctrl/mpam_resctrl.c b/drivers/resctrl/mpam_resctrl.c
> index a9938006d0e6..d80df486a313 100644
> --- a/drivers/resctrl/mpam_resctrl.c
> +++ b/drivers/resctrl/mpam_resctrl.c
> @@ -1399,7 +1399,7 @@ mpam_resctrl_alloc_domain(unsigned int cpu, struct mpam_resctrl_res *res)
> }
>
> if (r->mon_capable) {
> - struct mpam_component *any_mon_comp;
> + struct mpam_component *any_mon_comp = NULL;
> struct mpam_resctrl_mon *mon;
> enum resctrl_event_id eventid;
>
^ permalink raw reply
* [PATCH v1 2/2] arm_mpam: resctrl: Make resctrl_mon_ctx_waiters static
From: Ben Horgan @ 2026-04-14 13:27 UTC (permalink / raw)
To: ben.horgan
Cc: Dan Carpenter, Dan Carpenter, James Morse, Reinette Chatre,
Fenghua Yu, lkml, linux-arm-kernel, kernel test robot
In-Reply-To: <20260414132758.196874-1-ben.horgan@arm.com>
resctrl_mon_ctx_waiters is not used outside of this file, so make it
static. This fixes the sparse warning:
drivers/resctrl/mpam_resctrl.c:25:1: warning: symbol 'resctrl_mon_ctx_waiters' was not declared. Should it be static?
Reported-by: kernel test robot <lkp@intel.com>
Closes: https://lore.kernel.org/oe-kbuild-all/202603281842.c2K96tJA-lkp@intel.com/
Fixes: 2a3c79c61539 ("arm_mpam: resctrl: Allow resctrl to allocate monitors")
Signed-off-by: Ben Horgan <ben.horgan@arm.com>
---
drivers/resctrl/mpam_resctrl.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/resctrl/mpam_resctrl.c b/drivers/resctrl/mpam_resctrl.c
index d80df486a313..bb933b224851 100644
--- a/drivers/resctrl/mpam_resctrl.c
+++ b/drivers/resctrl/mpam_resctrl.c
@@ -22,7 +22,7 @@
#include "mpam_internal.h"
-DECLARE_WAIT_QUEUE_HEAD(resctrl_mon_ctx_waiters);
+static DECLARE_WAIT_QUEUE_HEAD(resctrl_mon_ctx_waiters);
/*
* The classes we've picked to map to resctrl resources, wrapped
--
2.43.0
^ permalink raw reply related
* [PATCH v1 1/2] arm_mpam: resctrl: Fix the check for no monitor components found
From: Ben Horgan @ 2026-04-14 13:27 UTC (permalink / raw)
To: ben.horgan
Cc: Dan Carpenter, Dan Carpenter, James Morse, Reinette Chatre,
Fenghua Yu, lkml, linux-arm-kernel
In-Reply-To: <20260414132758.196874-1-ben.horgan@arm.com>
Dan Carpenter reports that, in mpam_resctrl_alloc_domain(), any_mon_comp is
used in an 'if' condition when it may be uninitialized. Initialize it to
NULL so that the check behaves correctly when no monitor components are
found.
Reported-by: Dan Carpenter <error27@gmail.com>
Fixes: 264c285999fc ("arm_mpam: resctrl: Add monitor initialisation and domain boilerplate")
Signed-off-by: Ben Horgan <ben.horgan@arm.com>
---
drivers/resctrl/mpam_resctrl.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/resctrl/mpam_resctrl.c b/drivers/resctrl/mpam_resctrl.c
index a9938006d0e6..d80df486a313 100644
--- a/drivers/resctrl/mpam_resctrl.c
+++ b/drivers/resctrl/mpam_resctrl.c
@@ -1399,7 +1399,7 @@ mpam_resctrl_alloc_domain(unsigned int cpu, struct mpam_resctrl_res *res)
}
if (r->mon_capable) {
- struct mpam_component *any_mon_comp;
+ struct mpam_component *any_mon_comp = NULL;
struct mpam_resctrl_mon *mon;
enum resctrl_event_id eventid;
--
2.43.0
^ permalink raw reply related
* [PATCH v1 1/2] arm_mpam: resctrl: Fix broken error path in mpam_resctrl_alloc_domain()
From: Ben Horgan @ 2026-04-14 13:27 UTC (permalink / raw)
To: ben.horgan
Cc: Dan Carpenter, Dan Carpenter, James Morse, Reinette Chatre,
Fenghua Yu, lkml, linux-arm-kernel
In-Reply-To: <20260414132758.196874-1-ben.horgan@arm.com>
Dan Carpenter reports that, in mpam_resctrl_alloc_domain(), any_mon_comp is
used in an 'if' condition when it may be uninitialized. Initialize it to
NULL so that the check behaves correctly when no monitor components are
found.
Reported-by: Dan Carpenter <error27@gmail.com>
Fixes: 264c285999fc ("arm_mpam: resctrl: Add monitor initialisation and domain boilerplate")
Signed-off-by: Ben Horgan <ben.horgan@arm.com>
---
drivers/resctrl/mpam_resctrl.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/resctrl/mpam_resctrl.c b/drivers/resctrl/mpam_resctrl.c
index a9938006d0e6..d80df486a313 100644
--- a/drivers/resctrl/mpam_resctrl.c
+++ b/drivers/resctrl/mpam_resctrl.c
@@ -1399,7 +1399,7 @@ mpam_resctrl_alloc_domain(unsigned int cpu, struct mpam_resctrl_res *res)
}
if (r->mon_capable) {
- struct mpam_component *any_mon_comp;
+ struct mpam_component *any_mon_comp = NULL;
struct mpam_resctrl_mon *mon;
enum resctrl_event_id eventid;
--
2.43.0
^ permalink raw reply related
* Re: [PATCH 0/3] arm64/virt: Add Arm CCA measurement register support
From: Suzuki K Poulose @ 2026-04-14 13:26 UTC (permalink / raw)
To: Jason Gunthorpe
Cc: Sami Mujawar, Dan Williams, linux-arm-kernel, linux-kernel,
catalin.marinas, will, thuth, steven.price, gshan, YeoReum.Yun,
cedric.xing, Dan Williams, Dionna Glaze, Aneesh Kumar K . V,
Alexey Kardashevskiy, linux-coco@lists.linux.dev
In-Reply-To: <20260414122950.GW3694781@ziepe.ca>
On 14/04/2026 13:29, Jason Gunthorpe wrote:
> On Tue, Apr 14, 2026 at 11:10:51AM +0100, Suzuki K Poulose wrote:
>
>>> Isn't this also sort of incomplete? Doesn't anything serious need
>>> signed measurements? Isnt't there alot more data that comes out of RMM
>>> than just a few measurement registers?
>> As mentioned above, this series adds the support for Runtime Extendible
>> Measurements (REM in CCA, RTMR on TDX). The RIM+Platform Attestation is
>> already provided via the TSM_REPORT
>
> Okay, but what actual use is this?
>
Good point. This REMs are planned to be used for
EFI_CC_MEASUREMENT_PROTOCOL as described below:
https://github.com/tianocore/edk2/issues/11383
At the moment they are exposed as raw, similar to the Intel TDX RTMRs.
This may eventually need to be connected to IMA subsystem.
> Extendable measrements with no log
> Measurement read back without signature
>
> What is the use case? What do you imagine any userspace will do with
> this? Put it in the cover letter.
Agreed.
>
> I don't think the raw rmm calls are sufficiently developed to be
> usable directly by userspace. They are less capable than TPM and even
> TPM has a lot of software around it to make it useful.
See above.
Kind regards
Suzuki
>
> Jason
^ permalink raw reply
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