* Re: [Question mpam mpam/snapshot+extras/v6.18-rc1] Question with Configuring iommu_group in 'task'
From: Zeng Heng @ 2026-04-16 3:02 UTC (permalink / raw)
To: Ben Horgan, James Morse
Cc: Qinxin Xia, amitsinght, baisheng.gao, baolin.wang, carl,
dave.martin, david, dfustini, fenghuay, gshan, jonathan.cameron,
kobak, lcherian, linux-arm-kernel, linux-kernel, peternewman,
punit.agrawal, quic_jiles, reinette.chatre, rohit.mathew, scott,
sdonthineni, xhao, Linuxarm
In-Reply-To: <f800f0d5-7a00-4dad-95fe-a2aac2ece5ef@arm.com>
On 2026/4/15 20:42, Ben Horgan wrote:
> Hi Zeng,
>
> On 4/15/26 02:27, Zeng Heng wrote:
>> Hi Ben,
>>
>> On 2026/4/13 23:02, Ben Horgan wrote:
>>> Hi Qinxin,
>>>
>>> On 4/3/26 03:44, Qinxin Xia wrote:
>>>>
>>>>
>>>> On 2026/3/27 18:47:49, Ben Horgan <ben.horgan@arm.com> wrote:
>>>>> Hi Qinxin,
>>>>>
>>>>> On 3/27/26 10:21, Qinxin Xia wrote:
>>>>>>
>>>>>> Hello everyone!
>>>>>>
>>>>>> In earlier versions, mpam supports the configuration of iommu_groups.
>>>>>>
>>>>>> 823 static ssize_t rdtgroup_tasks_write(struct kernfs_open_file *of,
>>>>>> 824 char *buf, size_t nbytes,
>>>>>> loff_t off)
>>>>>> 825 {
>>>>>> 826 struct rdtgroup *rdtgrp;
>>>>>> 827 int iommu_group_id;
>>>>>> 828 bool is_iommu;
>>>>>> 829 char *pid_str;
>>>>>> 830 int ret = 0;
>>>>>> 831 pid_t pid;
>>>>>> 832
>>>>>> 833 rdtgrp = rdtgroup_kn_lock_live(of->kn);
>>>>>> 834 if (!rdtgrp) {
>>>>>> 835 rdtgroup_kn_unlock(of->kn);
>>>>>> 836 return -ENOENT;
>>>>>> 837 }
>>>>>> 838 rdt_last_cmd_clear();
>>>>>> 839
>>>>>> 840 if (rdtgrp->mode == RDT_MODE_PSEUDO_LOCKED ||
>>>>>> 841 rdtgrp->mode == RDT_MODE_PSEUDO_LOCKSETUP) {
>>>>>> 842 ret = -EINVAL;
>>>>>> 843 rdt_last_cmd_puts("Pseudo-locking in progress\n");
>>>>>> 844 goto unlock;
>>>>>> 845 }
>>>>>> 846
>>>>>> 847 while (buf && buf[0] != '\0' && buf[0] != '\n') {
>>>>>> 848 pid_str = strim(strsep(&buf, ","));
>>>>>> 849
>>>>>> 850 is_iommu = string_is_iommu_group(pid_str, &iommu_group_id);
>>>>>>
>>>>>> What puzzles me is why we would put it under 'task'—this seems a little
>>>>>> strange to users.It seems they are not related.Why don't we add a new
>>>>>> interface like 'iommu'?
>>>>>
>>>>> I think it is likely that this interface would change if upstream support is added.
>>>>>
>>>>
>>>> I have done some work in this direction before, and I will release an
>>>> RFC later for further discussion.:-)
>>>
>>> Looking forward to seeing it.
>>>
>>> Ben
>>>
>>
>> Following the current SMMU approach, I've submitted several bugfix
>> patches for the MPAM driver, but haven't received any review feedback
>> yet.
>>
>> To avoid these being overlooked, I'd like to kindly remind to take a
>> look:
>> v2: https://lore.kernel.org/all/20260414032610.1523958-1-zengheng4@huawei.com/
>> v1: https://lore.kernel.org/all/20251107063300.1580046-1-zengheng4@huawei.com/
>>
>> Additionally, I'd like to check on the status of this branch — is it
>> still actively maintained? It would be helpful to understand the future
>> plans for MPAM development.
>
> The MPAM snapshot and extras branches are no longer maintained. Work on these has stopped so that we can focus on
> upstream. Apologies for not making this clear earlier.
>
Ack. If the extras branch scheme mentioned above is rebased onto
upstream, these bugfix patches would remain applicable and worth
reviewing.
Best regards,
Zeng Heng
^ permalink raw reply
* RE: [PATCH v2] pmdomain: imx: Make IMX8M/IMX9 BLK_CTRL tristate
From: Zhipeng Wang @ 2026-04-16 1:59 UTC (permalink / raw)
To: Frank Li
Cc: ulfh@kernel.org, s.hauer@pengutronix.de, kernel@pengutronix.de,
festevam@gmail.com, linux-pm@vger.kernel.org, imx@lists.linux.dev,
linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org, Xuegang Liu, Jindong Yue
In-Reply-To: <ad83MtdMP4rci3Ya@lizhi-Precision-Tower-5810>
> On Mon, Apr 13, 2026 at 02:30:49PM +0900, Zhipeng Wang wrote:
> > Convert IMX8M_BLK_CTRL and IMX9_BLK_CTRL from bool to tristate to
> > allow building as loadable modules.
> >
> > Add prompt strings to make these options visible and configurable in
> > menuconfig, keeping them enabled by default on appropriate platforms.
> >
> > Also remove the IMX_GPCV2_PM_DOMAINS dependency from
> IMX9_BLK_CTRL.
> > This dependency was incorrect from the beginning - i.MX93 uses a
>
> s/-/because
>
> Reviewed-by: Frank Li <Frank.Li@nxp.com>
>
Hi Frank,
Thank you! v3 sent.
BRs,
Zhipeng
> > different power domain architecture compared to i.MX8M series:
> >
> > - i.MX8M uses GPCv2 (General Power Controller v2) for power domain
> > management, hence IMX8M_BLK_CTRL correctly depends on it.
> >
> > - i.MX93 uses BLK_CTRL directly without GPCv2. The hardware doesn't
> > have GPCv2 at all.
> >
> > Signed-off-by: Zhipeng Wang <zhipeng.wang_1@nxp.com>
> > ---
> > drivers/pmdomain/imx/Kconfig | 11 +++++++----
> > 1 file changed, 7 insertions(+), 4 deletions(-)
> >
> > diff --git a/drivers/pmdomain/imx/Kconfig
> > b/drivers/pmdomain/imx/Kconfig index 00203615c65e..9168d183b0c5
> 100644
> > --- a/drivers/pmdomain/imx/Kconfig
> > +++ b/drivers/pmdomain/imx/Kconfig
> > @@ -10,15 +10,18 @@ config IMX_GPCV2_PM_DOMAINS
> > default y if SOC_IMX7D
> >
> > config IMX8M_BLK_CTRL
> > - bool
> > - default SOC_IMX8M && IMX_GPCV2_PM_DOMAINS
> > + tristate "i.MX8M BLK CTRL driver"
> > + depends on SOC_IMX8M
> > + depends on IMX_GPCV2_PM_DOMAINS
> > depends on PM_GENERIC_DOMAINS
> > depends on COMMON_CLK
> > + default y
> >
> > config IMX9_BLK_CTRL
> > - bool
> > - default SOC_IMX9 && IMX_GPCV2_PM_DOMAINS
> > + tristate "i.MX93 BLK CTRL driver"
> > + depends on SOC_IMX9
> > depends on PM_GENERIC_DOMAINS
> > + default y
> >
> > config IMX_SCU_PD
> > bool "IMX SCU Power Domain driver"
> > --
> > 2.34.1
> >
^ permalink raw reply
* [PATCH v3] pmdomain: imx: Make IMX8M/IMX9 BLK_CTRL tristate
From: Zhipeng Wang @ 2026-04-16 1:56 UTC (permalink / raw)
To: ulfh, Frank.Li, s.hauer
Cc: kernel, festevam, linux-pm, imx, linux-arm-kernel, linux-kernel,
xuegang.liu, jindong.yue
Convert IMX8M_BLK_CTRL and IMX9_BLK_CTRL from bool to tristate
to allow building as loadable modules.
Add prompt strings to make these options visible and configurable
in menuconfig, keeping them enabled by default on appropriate platforms.
Also remove the IMX_GPCV2_PM_DOMAINS dependency from IMX9_BLK_CTRL.
This dependency was incorrect from the beginning because i.MX93 uses a
different power domain architecture compared to i.MX8M series:
- i.MX8M uses GPCv2 (General Power Controller v2) for power domain
management, hence IMX8M_BLK_CTRL correctly depends on it.
- i.MX93 uses BLK_CTRL directly without GPCv2. The hardware doesn't
have GPCv2 at all.
Signed-off-by: Zhipeng Wang <zhipeng.wang_1@nxp.com>
Reviewed-by: Frank Li <Frank.Li@nxp.com>
---
drivers/pmdomain/imx/Kconfig | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/drivers/pmdomain/imx/Kconfig b/drivers/pmdomain/imx/Kconfig
index 00203615c65e..9168d183b0c5 100644
--- a/drivers/pmdomain/imx/Kconfig
+++ b/drivers/pmdomain/imx/Kconfig
@@ -10,15 +10,18 @@ config IMX_GPCV2_PM_DOMAINS
default y if SOC_IMX7D
config IMX8M_BLK_CTRL
- bool
- default SOC_IMX8M && IMX_GPCV2_PM_DOMAINS
+ tristate "i.MX8M BLK CTRL driver"
+ depends on SOC_IMX8M
+ depends on IMX_GPCV2_PM_DOMAINS
depends on PM_GENERIC_DOMAINS
depends on COMMON_CLK
+ default y
config IMX9_BLK_CTRL
- bool
- default SOC_IMX9 && IMX_GPCV2_PM_DOMAINS
+ tristate "i.MX93 BLK CTRL driver"
+ depends on SOC_IMX9
depends on PM_GENERIC_DOMAINS
+ default y
config IMX_SCU_PD
bool "IMX SCU Power Domain driver"
--
2.34.1
^ permalink raw reply related
* RE: [PATCH v29 2/4] dt-bindings: i2c: ast2600-i2c.yaml: Add global-regs properties
From: Ryan Chen @ 2026-04-16 1:38 UTC (permalink / raw)
To: Conor Dooley
Cc: jk@codeconstruct.com.au, andriy.shevchenko@linux.intel.com,
Andi Shyti, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Joel Stanley, Andrew Jeffery, Benjamin Herrenschmidt, Rayn Chen,
Philipp Zabel, linux-i2c@vger.kernel.org,
devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
linux-aspeed@lists.ozlabs.org, linux-kernel@vger.kernel.org,
openbmc@lists.ozlabs.org
In-Reply-To: <20260415-unrushed-collected-562130070d8b@spud>
> Subject: Re: [PATCH v29 2/4] dt-bindings: i2c: ast2600-i2c.yaml: Add global-regs
> properties
>
> On Wed, Apr 15, 2026 at 01:14:03PM +0800, Ryan Chen wrote:
> > Add the aspeed,global-regs phandle to reference the AST2600 global
> > registers syscon node, containing the SoC-common I2C register set.
> >
> > These properties apply only to the AST2600 binding. Legacy DTs remain
> > unchanged.
> >
> > Signed-off-by: Ryan Chen <ryan_chen@aspeedtech.com>
>
> I hate to do it to you on v29, but can you please explain what this
> "soc-common i2c register set" actually is/does in your commit message.
Thanks your review.
The common means this global register is common register have common
register control used by all i2c bus.
Such like register layout mode (new vs. legacy) and shared base clock dividers.
> The patch seems fine, so with that
> Acked-by: Conor Dooley <conor.dooley@microchip.com>
> pw-bot: not-applicable
>
> > ---
> > Changes in v29:
> > - remove aspeed,enable-dma properties.
> >
> > Changes in v28:
> > - update commit message correspond with aspeed,enable-dma.
> > - remove aspeed,transfer-mode and add aspeed,enable-dma property and
> > description.
> > - Fix aspeed,enable-dma description to reflect hardware capability rather
> > than software behavior
> >
> > Changes in v27:
> > - change aspeed,transfer-mode to aspeed,enable-dma.
> > ---
> > Documentation/devicetree/bindings/i2c/aspeed,ast2600-i2c.yaml | 7
> > +++++++
> > 1 file changed, 7 insertions(+)
> >
> > diff --git
> > a/Documentation/devicetree/bindings/i2c/aspeed,ast2600-i2c.yaml
> > b/Documentation/devicetree/bindings/i2c/aspeed,ast2600-i2c.yaml
> > index de2c359037da..0c769efb76a5 100644
> > --- a/Documentation/devicetree/bindings/i2c/aspeed,ast2600-i2c.yaml
> > +++ b/Documentation/devicetree/bindings/i2c/aspeed,ast2600-i2c.yaml
> > @@ -37,6 +37,12 @@ properties:
> > resets:
> > maxItems: 1
> >
> > + aspeed,global-regs:
> > + $ref: /schemas/types.yaml#/definitions/phandle
> > + description:
> > + Phandle reference to the i2c global syscon node, containing the
> > + SoC-common i2c register set.
> > +
> > required:
> > - reg
> > - compatible
> > @@ -59,4 +65,5 @@ examples:
> > resets = <&syscon ASPEED_RESET_I2C>;
> > clock-frequency = <100000>;
> > interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>;
> > + aspeed,global-regs = <&i2c_global>;
> > };
> >
> > --
> > 2.34.1
> >
^ permalink raw reply
* Re: [PATCH v3 2/2] mmc: dw_mmc: exynos: increase DMA threshold value for exynos7870
From: Shawn Lin @ 2026-04-16 0:29 UTC (permalink / raw)
To: Kaustabh Chakraborty, Ulf Hansson, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Jaehoon Chung,
Krzysztof Kozlowski, Alim Akhtar
Cc: shawn.lin, linux-mmc, devicetree, linux-kernel, linux-arm-kernel,
linux-samsung-soc
In-Reply-To: <20260415-dwmmc-dma-thr-v3-2-31014d36b6ee@disroot.org>
在 2026/04/15 星期三 23:02, Kaustabh Chakraborty 写道:
> Exynos 7870 compatible controllers, such as SDIO ones are not able to
> perform DMA transfers for small sizes of data (~16 to ~512 bytes),
> resulting in cache issues in subsequent transfers. Increase the DMA
> transfer threshold to 512 to allow the shorter transfers to take place,
> bypassing DMA.
>
Reviewed-by: Shawn Lin <shawn.lin@rock-chips.com>
> Signed-off-by: Kaustabh Chakraborty <kauschluss@disroot.org>
> ---
> drivers/mmc/host/dw_mmc-exynos.c | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/drivers/mmc/host/dw_mmc-exynos.c b/drivers/mmc/host/dw_mmc-exynos.c
> index 261344d3a8cfe..4b76b997ddc15 100644
> --- a/drivers/mmc/host/dw_mmc-exynos.c
> +++ b/drivers/mmc/host/dw_mmc-exynos.c
> @@ -141,6 +141,7 @@ static int dw_mci_exynos_priv_init(struct dw_mci *host)
> priv->ctrl_type == DW_MCI_TYPE_EXYNOS7870_SMU) {
> /* Quirk needed for certain Exynos SoCs */
> host->quirks |= DW_MMC_QUIRK_FIFO64_32;
> + host->dma_threshold = 512;
> }
>
> if (priv->ctrl_type == DW_MCI_TYPE_ARTPEC8) {
>
^ permalink raw reply
* Re: [PATCH v3 1/2] mmc: dw_mmc: implement option for configuring DMA threshold
From: Shawn Lin @ 2026-04-16 0:27 UTC (permalink / raw)
To: Kaustabh Chakraborty, Ulf Hansson, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Jaehoon Chung,
Krzysztof Kozlowski, Alim Akhtar
Cc: shawn.lin, linux-mmc, devicetree, linux-kernel, linux-arm-kernel,
linux-samsung-soc
In-Reply-To: <20260415-dwmmc-dma-thr-v3-1-31014d36b6ee@disroot.org>
在 2026/04/15 星期三 23:02, Kaustabh Chakraborty 写道:
> Some controllers, such as certain Exynos SDIO ones, are unable to
> perform DMA transfers of small amount of bytes properly. Following the
> device tree schema, implement the property to define the DMA transfer
> threshold (from a hard coded value of 16 bytes) so that lesser number of
> bytes can be transferred safely skipping DMA in such controllers. The
> value of 16 bytes stays as the default for controllers which do not
> define it. This value can be overridden by implementation-specific init
> sequences.
Reviewed-by: Shawn Lin <shawn.lin@rock-chips.com>
>
> Signed-off-by: Kaustabh Chakraborty <kauschluss@disroot.org>
> ---
> drivers/mmc/host/dw_mmc.c | 4 ++--
> drivers/mmc/host/dw_mmc.h | 2 ++
> 2 files changed, 4 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
> index 20193ee7b73eb..3b4157f34d11f 100644
> --- a/drivers/mmc/host/dw_mmc.c
> +++ b/drivers/mmc/host/dw_mmc.c
> @@ -40,7 +40,6 @@
> SDMMC_INT_RESP_ERR | SDMMC_INT_HLE)
> #define DW_MCI_ERROR_FLAGS (DW_MCI_DATA_ERROR_FLAGS | \
> DW_MCI_CMD_ERROR_FLAGS)
> -#define DW_MCI_DMA_THRESHOLD 16
>
> #define DW_MCI_FREQ_MAX 200000000 /* unit: HZ */
> #define DW_MCI_FREQ_MIN 100000 /* unit: HZ */
> @@ -821,7 +820,7 @@ static int dw_mci_pre_dma_transfer(struct dw_mci *host,
> * non-word-aligned buffers or lengths. Also, we don't bother
> * with all the DMA setup overhead for short transfers.
> */
> - if (data->blocks * data->blksz < DW_MCI_DMA_THRESHOLD)
> + if (data->blocks * data->blksz < host->dma_threshold)
> return -EINVAL;
>
> if (data->blksz & 3)
> @@ -3185,6 +3184,7 @@ struct dw_mci *dw_mci_alloc_host(struct device *dev)
> host = mmc_priv(mmc);
> host->mmc = mmc;
> host->dev = dev;
> + host->dma_threshold = 16;
>
> return host;
> }
> diff --git a/drivers/mmc/host/dw_mmc.h b/drivers/mmc/host/dw_mmc.h
> index 42e58be74ce09..f29d40158dc59 100644
> --- a/drivers/mmc/host/dw_mmc.h
> +++ b/drivers/mmc/host/dw_mmc.h
> @@ -107,6 +107,7 @@ struct dw_mci_dma_slave {
> * @ciu_clk: Pointer to card interface unit clock instance.
> * @fifo_depth: depth of FIFO.
> * @data_addr_override: override fifo reg offset with this value.
> + * @dma_threshold: data threshold value in bytes to carry out a DMA transfer.
> * @wm_aligned: force fifo watermark equal with data length in PIO mode.
> * Set as true if alignment is needed.
> * @data_shift: log2 of FIFO item size.
> @@ -163,6 +164,7 @@ struct dw_mci {
> void __iomem *regs;
> void __iomem *fifo_reg;
> u32 data_addr_override;
> + u32 dma_threshold;
> bool wm_aligned;
>
> struct scatterlist *sg;
>
^ permalink raw reply
* Re: [PATCH net-next] net: stmmac: enable RPS and RBU interrupts
From: Russell King (Oracle) @ 2026-04-16 0:02 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: <CAH5Ym4j3GePEMEMmg1Z27gYfQ0N8Sc1BMW1rnvNZ4aLQ+cfFyQ@mail.gmail.com>
On Wed, Apr 15, 2026 at 01:50:53PM -0700, Sam Edwards wrote:
> On Wed, Apr 15, 2026 at 12:37 PM Russell King (Oracle)
> <linux@armlinux.org.uk> wrote:
> >
> > It's not a question about how I define RBU - this is defined by Synopsys
> > and I'm using it *exactly* that way as stated in the documentation.
> >
> > "This bit indicates that the host owns the Next Descriptor in the
> > Receive List and the DMA cannot acquire it. The Receive Process is
> > suspended. ... This bit is set only when the previous Receive
> > Descriptor is owned by the DMA."
> >
> > In other words, DMA has processed the previous receive descriptor which
> > _was_ owned by the hardware, written back to clear the OWN bit, and
> > then fetches the next descriptor and finds that the OWN bit is also
> > clear.
>
> I'm only trying to leave open the possibility that the Synopsys
> technical writer and the hardware implementation team weren't
> communicating clearly. We already have a situation where RPS isn't
> behaving as documented (even if that's likely just hardware
> misconfiguration), so while I'm currently pretty sure RBU carries no
> other (actual) meaning than "DMA caught up to OWN=0," I'm only about
> 75% confident.
It doesn't make sense for RPS to be set though. RPS is "Receive Process
Stopped" and it's documented as being raised when the receive process
enters the stopped state.
If we look at the DMA Debug Status 0 register at 0x100c, then this
gives us a four bit bitfield for channels 0, 1 and 2. Further channels
are in 0x1010. I've added code to dump these when RBU occurs:
dwc-eth-dwmac 2490000.ethernet eth0: debug status: 0x00006400 0x00000000
bits 11:8 are RPS0, which indiciates that the DMA channel 0 receive
process state is "Suspended (Rx Descriptor Unavailable)". If this were
0, then it would be "Stopped (Reset or Stop Receive Command issued)".
So, RPS isn't being raised because the process state isn't entering
the stopped state, which makes sense - because we haven't issued a
stop command, nor have we caused a reset, and the documented recovery
from this condition is to merely advance the tail pointer, rather than
issuing a command to re-start the receive process.
When this is done (because stmmac_rx() continues to periodically run
because of NAPI) RPS0 does change back to 3 "Running (Waiting for Rx
packet)" but it seems that although there are packets waiting to be
written out, that never happens (the Queue 0 Receive Debug register
indicates that there are packets in the receive queue, the receive
queue fill level is above the flow control activate threshold, and
the MAC itself hammers the network with pause frames as a result.)
Thus, I think that the fact that RPS isn't being signalled is entirely
reasonable and consistent with the available documentation.
--
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 v7 6/6] arm64: dts: rockchip: Add Orange Pi 5 Pro board support
From: Dennis Gilmore @ 2026-04-15 23:34 UTC (permalink / raw)
To: Alexey Charkov
Cc: Andrew Lunn, Andrzej Hajda, Chaoyi Chen, Conor Dooley,
David Airlie, devicetree, dri-devel, FUKAUMI Naoki,
Heiko Stuebner, Hsun Lai, Jernej Skrabec, Jimmy Hon, John Clark,
Jonas Karlman, Krzysztof Kozlowski, Laurent Pinchart,
linux-arm-kernel, linux-kernel, linux-rockchip, Maarten Lankhorst,
Maxime Ripard, Michael Opdenacker, Michael Riesch, Mykola Kvach,
Neil Armstrong, Peter Robinson, Quentin Schulz, Robert Foss,
Rob Herring, Simona Vetter, Thomas Zimmermann
In-Reply-To: <CABjd4YxfeCfRUneZfFx31WmQOexO0gcH8yHPQmRY38GKNk=Ztg@mail.gmail.com>
Hi Alexey,
On Wed, Apr 15, 2026 at 3:57 AM Alexey Charkov <alchark@gmail.com> wrote:
>
> On Wed, Apr 15, 2026 at 1:41 AM Dennis Gilmore <dennis@ausil.us> wrote:
> >
> > 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)
>
> Hi Dennis,
>
> Sashiko noticed [1] that the controller names here do not match the
> nodes/comments you have in the patch body - which ones are correct?
>
> [1] https://sashiko.dev/#/patchset/20260414214104.1363987-1-dennis%40ausil.us
The ones in the body are correct. will fix
> > - 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 through a Lontium LT8711UXD bridge.
> >
> > Vendors schematics are available at:
> > https://drive.google.com/file/d/1qs1DratHuh7C6J6MEtQIwUsiSrg8qgTi/view
> >
> > Signed-off-by: Dennis Gilmore <dennis@ausil.us>
> > ---
> > arch/arm64/boot/dts/rockchip/Makefile | 1 +
> > .../dts/rockchip/rk3588s-orangepi-5-pro.dts | 442 ++++++++++++++++++
> > 2 files changed, 443 insertions(+)
> > create mode 100644 arch/arm64/boot/dts/rockchip/rk3588s-orangepi-5-pro.dts
> >
> > 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..61462c66753d
> > --- /dev/null
> > +++ b/arch/arm64/boot/dts/rockchip/rk3588s-orangepi-5-pro.dts
> > @@ -0,0 +1,442 @@
> > +// 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;
> > + };
> > +
> > + hdmi1-con {
> > + compatible = "hdmi-connector";
> > + label = "HDMI1 OUT";
> > + type = "a";
> > +
> > + port {
> > + hdmi1_con_in: endpoint {
> > + remote-endpoint = <<8711uxd_out>;
> > + };
> > + };
> > + };
> > +
> > + lt8711uxd {
>
> Please use a generic node name per DT convention. "hdmi-bridge" perhaps?
>
Will adopt hdmi-bridge
> > + compatible = "lontium,lt8711uxd";
>
> Don't you want to add "vdd-supply = <&vcc3v3_dp>;" here? It costs you
> nothing, as it's already in the binding and in the driver, and having
> this dependency listed explicitly will let the kernel order the driver
> probes correctly, and also likely let you drop the boot-on/always-on
> annotation from the regulator node.
I will add the supply and test drop the boot-on/always-on
> > + ports {
> > + #address-cells = <1>;
> > + #size-cells = <0>;
> > +
> > + port@0 {
> > + reg = <0>;
> > +
> > + lt8711uxd_in: endpoint {
> > + remote-endpoint = <&dp0_out_con>;
> > + };
> > + };
> > +
> > + port@1 {
> > + reg = <1>;
> > +
> > + lt8711uxd_out: endpoint {
> > + remote-endpoint = <&hdmi1_con_in>;
> > + };
> > + };
> > + };
> > + };
> > +
> > + analog-sound {
> > + compatible = "simple-audio-card";
> > + pinctrl-names = "default";
> > + pinctrl-0 = <&hp_detect>;
> > + simple-audio-card,format = "i2s";
> > + 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>;
> > + };
> > +
> > + 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>;
> > + pinctrl-names = "default";
> > + pinctrl-0 = <&dp_bridge_en>;
> > + regulator-max-microvolt = <3300000>;
> > + regulator-min-microvolt = <3300000>;
> > + regulator-name = "vcc3v3_dp";
> > + regulator-always-on;
> > + regulator-boot-on;
>
> Please see if you can drop these always-on/boot-on when vdd-supply is
> explicitly listed in the bridge node
>
I have tested removing these with the supply change listed, the HDMI
bridge fails to power on, it does work okay with regulator-always-on
only. It seems necessary to ensure that the bridge is active and that
HPD works. I am open to trying something else to ensure it all works
> > + vin-supply = <&vcc_3v3_s3>;
> > + };
> > +
> > + vcc3v3_phy1: regulator-vcc3v3-phy1 {
> > + compatible = "regulator-fixed";
> > + enable-active-high;
> > + gpios = <&gpio3 RK_PB7 GPIO_ACTIVE_HIGH>;
> > + pinctrl-names = "default";
> > + pinctrl-0 = <&vcc3v3_phy1_en>;
>
> The board schematics call the pin "Ethernet_EN"
Will rename this
> > + 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";
> > + pinctrl-names = "default";
> > + pinctrl-0 = <&wifi_enable_h>;
> > + post-power-on-delay-ms = <200>;
> > + reset-gpios = <&gpio0 RK_PD0 GPIO_ACTIVE_LOW>;
> > + };
> > +
> > + 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>;
> > + status = "okay";
> > +};
> > +
> > +&dp0_in {
> > + dp0_in_vp1: endpoint {
> > + remote-endpoint = <&vp1_out_dp0>;
> > + };
> > +};
> > +
> > +&dp0_out {
> > + dp0_out_con: endpoint {
> > + remote-endpoint = <<8711uxd_in>;
> > + };
> > +};
> > +
> > +&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 = <&vcca_3v3_s0>;
> > + DVDD-supply = <&vcca_1v8_s0>;
> > + HPVDD-supply = <&vcca_3v3_s0>;
> > + PVDD-supply = <&vcca_1v8_s0>;
> > + 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 = <&pcie2x1l1_rst &pcie30x1m1_1_clkreqn &pcie30x1m1_1_waken>;
>
> Is there a particular reason to use the GPIO mode for the reset pin,
> rather than the (confusingly named) &pcie30x1m1_1_perstn in line with
> the other two?
There is no particular reason. rk3588-turing-rk1.dtsi is the only
example in the kernel currently doing something similar, and it is
implemented that way there. I agree that the naming is confusing. I
will change it.
> > + reset-gpios = <&gpio4 RK_PA2 GPIO_ACTIVE_HIGH>;
> > + supports-clkreq;
> > + vpcie3v3-supply = <&vcc_3v3_s3>;
> > + status = "okay";
> > +};
> > +
> > +/* NIC */
> > +&pcie2x1l2 {
> > + pinctrl-names = "default";
> > + pinctrl-0 = <&pcie2x1l2_rst>;
>
> Similar to the above - have you tried the dedicated hardware mode for
> this pin, i.e. &pcie20x1m0_perstn? You are not requesting the
> &pcie20x1m0_clkreqn or &pcie20x1m0_waken either, even though they are
> routed on the board - that will probably bite you if you try
> suspending the board.
I have not, I also have not tried to suspend. Will adopt and test.
> > + reset-gpios = <&gpio3 RK_PD1 GPIO_ACTIVE_HIGH>;
> > + 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>;
>
> If you care about power consumption of the board it's probably better
> to pull this down to make sure the Bluetooth module is predictably in
> a sleep state when not explicitly requested, not floating randomly.
> There is no dedicated pull-up/pull-down on your board.
Will do
> > + };
> > +
> > + bt_wake_host_irq: bt-wake-host-irq {
> > + rockchip,pins = <0 RK_PC5 RK_FUNC_GPIO &pcfg_pull_down>;
> > + };
> > + };
> > +
> > + dp {
> > + dp_bridge_en: dp-bridge-en {
> > + rockchip,pins = <3 RK_PC2 RK_FUNC_GPIO &pcfg_pull_none>;
>
> This pin doesn't have any dedicated pull-up/pull-down on the board, so
> you might end up in a weird power state for the period of time between
> the probing of the pinctrl subsystem and regulators. Better set it to
> &pcfg_pull_down, which matches the power-on-reset default state of
> this pin.
Will do
> > + };
> > + };
> > +
> > + pcie {
> > + pcie2x1l1_rst: pcie2x1l1-rst {
> > + rockchip,pins = <4 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>;
> > + };
> > +
> > + pcie2x1l2_rst: pcie2x1l2-rst {
> > + rockchip,pins = <3 RK_PD1 RK_FUNC_GPIO &pcfg_pull_none>;
> > + };
> > +
> > + vcc3v3_phy1_en: vcc3v3-phy1-en {
>
> The schematic calls this pin "Ethernet_EN", so perhaps use that in the
> label and node name for easier reference.
Will do
> > + rockchip,pins = <3 RK_PB7 RK_FUNC_GPIO &pcfg_pull_none>;
>
> As above: no dedicated pull resistors on the board, better set to
> &pcfg_pull_down in line with POR default.
Will do
> > + };
> > + };
> > +
> > + usb {
> > + vcc5v0_otg_en: vcc5v0-otg-en {
> > + rockchip,pins = <0 RK_PC4 RK_FUNC_GPIO &pcfg_pull_none>;
>
> As above: no dedicated pull resistors on the board, better set to
> &pcfg_pull_down in line with POR default.
Will do
> > + };
> > + };
> > +
> > + wlan {
> > + wifi_enable_h: wifi-enable-h {
> > + rockchip,pins = <0 RK_PD0 RK_FUNC_GPIO &pcfg_pull_none>;
>
> As above: no dedicated pull resistors on the board, better set to
> &pcfg_pull_down in line with POR default.
will do
> Best regards,
> Alexey
I appreciate the feedback
Dennis
^ permalink raw reply
* Re: [RFC][PATCH 3/4] ARM: dts: renesas: r8a7740: Add ZT/ZTR trace clock on R-Mobile A1
From: Marek Vasut @ 2026-04-15 23:34 UTC (permalink / raw)
To: Geert Uytterhoeven, Marek Vasut
Cc: linux-arm-kernel, Conor Dooley, Krzysztof Kozlowski, Magnus Damm,
Michael Turquette, Rob Herring, Stephen Boyd, devicetree,
linux-clk, linux-kernel, linux-renesas-soc
In-Reply-To: <CAMuHMdVOHaQU0qAYYQV3u7bAm3jzKmQM=btnpFaToxGxPrVGXA@mail.gmail.com>
On 4/7/26 2:06 PM, Geert Uytterhoeven wrote:
Hello Geert,
>> --- a/arch/arm/boot/dts/renesas/r8a7740.dtsi
>> +++ b/arch/arm/boot/dts/renesas/r8a7740.dtsi
>> @@ -551,9 +551,9 @@ cpg_clocks: cpg_clocks@e6150000 {
>> clock-output-names = "system", "pllc0", "pllc1",
>> "pllc2", "r",
>> "usb24s",
>> - "i", "zg", "b", "m1", "hp",
>> - "hpp", "usbp", "s", "zb", "m3",
>> - "cp";
>> + "i", "zg", "b", "m1", "ztr", "zt",
>> + "hp", "hpp", "usbp", "s", "zb",
>> + "m3", "cp";
>
> The order of the names must match the indices in the DT bindings below.
> Else consumers end up with a wrong parent clock, leading to issues
> like the I2C controller driver failing to probe because its parent
> clock is out of range.
Fixed in V2, thanks !
^ permalink raw reply
* [PATCH v2 4/4] ARM: dts: renesas: r8a7740: Describe coresight on R-Mobile A1
From: Marek Vasut @ 2026-04-15 23:31 UTC (permalink / raw)
To: linux-arm-kernel
Cc: Marek Vasut, Conor Dooley, Geert Uytterhoeven,
Krzysztof Kozlowski, Magnus Damm, Michael Turquette, Rob Herring,
Stephen Boyd, devicetree, linux-clk, linux-kernel,
linux-renesas-soc
In-Reply-To: <20260415233300.457892-1-marek.vasut+renesas@mailbox.org>
Describe coresight topology on R-Mobile A1. Extend the current PTM node
with connection funnel, TPIU, ETB and replicator. The coresight on this
hardware is clocked from the ZT/ZTR trace clock.
Signed-off-by: Marek Vasut <marek.vasut+renesas@mailbox.org>
---
Cc: Conor Dooley <conor+dt@kernel.org>
Cc: Geert Uytterhoeven <geert+renesas@glider.be>
Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
Cc: Magnus Damm <magnus.damm@gmail.com>
Cc: Michael Turquette <mturquette@baylibre.com>
Cc: Rob Herring <robh@kernel.org>
Cc: Stephen Boyd <sboyd@kernel.org>
Cc: devicetree@vger.kernel.org
Cc: linux-clk@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Cc: linux-renesas-soc@vger.kernel.org
---
V2: No change
---
arch/arm/boot/dts/renesas/r8a7740.dtsi | 114 ++++++++++++++++++++++++-
1 file changed, 111 insertions(+), 3 deletions(-)
diff --git a/arch/arm/boot/dts/renesas/r8a7740.dtsi b/arch/arm/boot/dts/renesas/r8a7740.dtsi
index f7136db7a2eae..c7056b96ec0b7 100644
--- a/arch/arm/boot/dts/renesas/r8a7740.dtsi
+++ b/arch/arm/boot/dts/renesas/r8a7740.dtsi
@@ -18,7 +18,7 @@ / {
cpus {
#address-cells = <1>;
#size-cells = <0>;
- cpu@0 {
+ cpu0: cpu@0 {
compatible = "arm,cortex-a9";
device_type = "cpu";
reg = <0x0>;
@@ -59,9 +59,117 @@ pmu {
interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>;
};
- ptm {
- compatible = "arm,coresight-etm3x";
+ replicator {
+ compatible = "arm,coresight-static-replicator";
+ clocks = <&cpg_clocks R8A7740_CLK_ZTR>;
+ clock-names = "atclk";
power-domains = <&pd_d4>;
+
+ out-ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ /* replicator output ports */
+ port@0 {
+ reg = <0>;
+
+ replicator_out_port0: endpoint {
+ remote-endpoint = <&tpiu_in_port>;
+ };
+ };
+ port@1 {
+ reg = <1>;
+
+ replicator_out_port1: endpoint {
+ remote-endpoint = <&etb_in_port>;
+ };
+ };
+ };
+
+ in-ports {
+ /* replicator input port */
+ port {
+ replicator_in_port0: endpoint {
+ remote-endpoint = <&funnel_out_port>;
+ };
+ };
+ };
+ };
+
+ etb@e6fa1000 {
+ compatible = "arm,coresight-etb10", "arm,primecell";
+ reg = <0xe6fa1000 0x1000>;
+ clocks = <&cpg_clocks R8A7740_CLK_ZT>, <&cpg_clocks R8A7740_CLK_ZTR>;
+ clock-names = "apb_pclk", "atclk";
+ power-domains = <&pd_d4>;
+
+ in-ports {
+ port {
+ etb_in_port: endpoint {
+ remote-endpoint = <&replicator_out_port1>;
+ };
+ };
+ };
+ };
+
+ tpiu@e6fa3000 {
+ compatible = "arm,coresight-tpiu", "arm,primecell";
+ reg = <0xe6fa3000 0x1000>;
+ clocks = <&cpg_clocks R8A7740_CLK_ZT>, <&cpg_clocks R8A7740_CLK_ZTR>;
+ clock-names = "apb_pclk", "atclk";
+ power-domains = <&pd_d4>;
+
+ in-ports {
+ port {
+ tpiu_in_port: endpoint {
+ remote-endpoint = <&replicator_out_port0>;
+ };
+ };
+ };
+ };
+
+ funnel {
+ compatible = "arm,coresight-static-funnel";
+
+ /* funnel output ports */
+ out-ports {
+ port {
+ funnel_out_port: endpoint {
+ remote-endpoint =
+ <&replicator_in_port0>;
+ };
+ };
+ };
+
+ in-ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ /* funnel input ports */
+ port@0 {
+ reg = <0>;
+ funnel0_in_port0: endpoint {
+ remote-endpoint = <&ptm0_out_port>;
+ };
+ };
+ };
+ };
+
+ ptm@e6fbc000 {
+ compatible = "arm,coresight-etm3x", "arm,primecell";
+ reg = <0xe6fbc000 0x1000>;
+ clocks = <&cpg_clocks R8A7740_CLK_ZT>, <&cpg_clocks R8A7740_CLK_ZTR>;
+ clock-names = "apb_pclk", "atclk";
+ cpu = <&cpu0>;
+ power-domains = <&pd_d4>;
+
+ out-ports {
+ port {
+ ptm0_out_port: endpoint {
+ remote-endpoint = <&funnel0_in_port0>;
+ };
+ };
+ };
};
ceu0: ceu@fe910000 {
--
2.53.0
^ permalink raw reply related
* [PATCH v2 3/4] ARM: dts: renesas: r8a7740: Add ZT/ZTR trace clock on R-Mobile A1
From: Marek Vasut @ 2026-04-15 23:31 UTC (permalink / raw)
To: linux-arm-kernel
Cc: Marek Vasut, Conor Dooley, Geert Uytterhoeven,
Krzysztof Kozlowski, Magnus Damm, Michael Turquette, Rob Herring,
Stephen Boyd, devicetree, linux-clk, linux-kernel,
linux-renesas-soc
In-Reply-To: <20260415233300.457892-1-marek.vasut+renesas@mailbox.org>
Add ZT trace bus and ZTR trace clock on the R-Mobile A1.
Signed-off-by: Marek Vasut <marek.vasut+renesas@mailbox.org>
---
Cc: Conor Dooley <conor+dt@kernel.org>
Cc: Geert Uytterhoeven <geert+renesas@glider.be>
Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
Cc: Magnus Damm <magnus.damm@gmail.com>
Cc: Michael Turquette <mturquette@baylibre.com>
Cc: Rob Herring <robh@kernel.org>
Cc: Stephen Boyd <sboyd@kernel.org>
Cc: devicetree@vger.kernel.org
Cc: linux-clk@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Cc: linux-renesas-soc@vger.kernel.org
---
V2: Add ztr/zt clock at the end of the list to match bindings
---
arch/arm/boot/dts/renesas/r8a7740.dtsi | 2 +-
include/dt-bindings/clock/r8a7740-clock.h | 2 ++
2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/arch/arm/boot/dts/renesas/r8a7740.dtsi b/arch/arm/boot/dts/renesas/r8a7740.dtsi
index d13ab86c3ab47..f7136db7a2eae 100644
--- a/arch/arm/boot/dts/renesas/r8a7740.dtsi
+++ b/arch/arm/boot/dts/renesas/r8a7740.dtsi
@@ -553,7 +553,7 @@ cpg_clocks: cpg_clocks@e6150000 {
"usb24s",
"i", "zg", "b", "m1", "hp",
"hpp", "usbp", "s", "zb", "m3",
- "cp";
+ "cp", "ztr", "zt";
};
/* Variable factor clocks (DIV6) */
diff --git a/include/dt-bindings/clock/r8a7740-clock.h b/include/dt-bindings/clock/r8a7740-clock.h
index 1b3fdb39cc426..8a8816b2ff6ac 100644
--- a/include/dt-bindings/clock/r8a7740-clock.h
+++ b/include/dt-bindings/clock/r8a7740-clock.h
@@ -24,6 +24,8 @@
#define R8A7740_CLK_ZB 14
#define R8A7740_CLK_M3 15
#define R8A7740_CLK_CP 16
+#define R8A7740_CLK_ZTR 17
+#define R8A7740_CLK_ZT 18
/* MSTP1 */
#define R8A7740_CLK_CEU21 28
--
2.53.0
^ permalink raw reply related
* [PATCH v2 2/4] clk: renesas: r8a7740: Implement ZT/ZTR trace clock on R-Mobile A1
From: Marek Vasut @ 2026-04-15 23:31 UTC (permalink / raw)
To: linux-arm-kernel
Cc: Marek Vasut, Conor Dooley, Geert Uytterhoeven,
Krzysztof Kozlowski, Magnus Damm, Michael Turquette, Rob Herring,
Stephen Boyd, devicetree, linux-clk, linux-kernel,
linux-renesas-soc
In-Reply-To: <20260415233300.457892-1-marek.vasut+renesas@mailbox.org>
Implement ZT trace bus and ZTR trace clock on the R-Mobile A1.
Signed-off-by: Marek Vasut <marek.vasut+renesas@mailbox.org>
---
Cc: Conor Dooley <conor+dt@kernel.org>
Cc: Geert Uytterhoeven <geert+renesas@glider.be>
Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
Cc: Magnus Damm <magnus.damm@gmail.com>
Cc: Michael Turquette <mturquette@baylibre.com>
Cc: Rob Herring <robh@kernel.org>
Cc: Stephen Boyd <sboyd@kernel.org>
Cc: devicetree@vger.kernel.org
Cc: linux-clk@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Cc: linux-renesas-soc@vger.kernel.org
---
V2: No change
---
drivers/clk/renesas/clk-r8a7740.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/clk/renesas/clk-r8a7740.c b/drivers/clk/renesas/clk-r8a7740.c
index 635d59ead499e..31a79674583e8 100644
--- a/drivers/clk/renesas/clk-r8a7740.c
+++ b/drivers/clk/renesas/clk-r8a7740.c
@@ -37,6 +37,8 @@ static struct div4_clk div4_clks[] = {
{ "zg", CPG_FRQCRA, 16 },
{ "b", CPG_FRQCRA, 8 },
{ "m1", CPG_FRQCRA, 4 },
+ { "ztr", CPG_FRQCRB, 20 },
+ { "zt", CPG_FRQCRB, 16 },
{ "hp", CPG_FRQCRB, 4 },
{ "hpp", CPG_FRQCRC, 20 },
{ "usbp", CPG_FRQCRC, 16 },
--
2.53.0
^ permalink raw reply related
* [PATCH v2 1/4] dt-bindings: clock: renesas,cpg-clocks: Document ZT/ZTR trace clock on R-Mobile A1
From: Marek Vasut @ 2026-04-15 23:31 UTC (permalink / raw)
To: linux-arm-kernel
Cc: Marek Vasut, Conor Dooley, Geert Uytterhoeven,
Krzysztof Kozlowski, Magnus Damm, Michael Turquette, Rob Herring,
Stephen Boyd, devicetree, linux-clk, linux-kernel,
linux-renesas-soc
In-Reply-To: <20260415233300.457892-1-marek.vasut+renesas@mailbox.org>
Document ZT trace bus and ZTR trace clock on the R-Mobile A1.
Signed-off-by: Marek Vasut <marek.vasut+renesas@mailbox.org>
---
Cc: Conor Dooley <conor+dt@kernel.org>
Cc: Geert Uytterhoeven <geert+renesas@glider.be>
Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
Cc: Magnus Damm <magnus.damm@gmail.com>
Cc: Michael Turquette <mturquette@baylibre.com>
Cc: Rob Herring <robh@kernel.org>
Cc: Stephen Boyd <sboyd@kernel.org>
Cc: devicetree@vger.kernel.org
Cc: linux-clk@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Cc: linux-renesas-soc@vger.kernel.org
---
V2: Reorder new clock at the end to match bindings
---
.../devicetree/bindings/clock/renesas,cpg-clocks.yaml | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/Documentation/devicetree/bindings/clock/renesas,cpg-clocks.yaml b/Documentation/devicetree/bindings/clock/renesas,cpg-clocks.yaml
index a0e09b7002f07..925ed35d6658a 100644
--- a/Documentation/devicetree/bindings/clock/renesas,cpg-clocks.yaml
+++ b/Documentation/devicetree/bindings/clock/renesas,cpg-clocks.yaml
@@ -41,7 +41,7 @@ properties:
clock-output-names:
minItems: 3
- maxItems: 17
+ maxItems: 19
renesas,mode:
description: Board-specific settings of the MD_CK* bits on R-Mobile A1
@@ -123,6 +123,8 @@ allOf:
- const: zb
- const: m3
- const: cp
+ - const: ztr
+ - const: zt
required:
- renesas,mode
@@ -240,6 +242,6 @@ examples:
#clock-cells = <1>;
clock-output-names = "system", "pllc0", "pllc1", "pllc2", "r",
"usb24s", "i", "zg", "b", "m1", "hp", "hpp",
- "usbp", "s", "zb", "m3", "cp";
+ "usbp", "s", "zb", "m3", "cp", "ztr", "zt";
renesas,mode = <0x05>;
};
--
2.53.0
^ permalink raw reply related
* [PATCH v2 0/4] Describe coresight on R-Mobile A1
From: Marek Vasut @ 2026-04-15 23:31 UTC (permalink / raw)
To: linux-arm-kernel
Cc: Marek Vasut, Conor Dooley, Geert Uytterhoeven,
Krzysztof Kozlowski, Magnus Damm, Michael Turquette, Rob Herring,
Stephen Boyd, devicetree, linux-clk, linux-kernel,
linux-renesas-soc
Implement support for ZT trace bus and ZTR trace clock on R-Mobile A1.
Describe coresight topology on R-Mobile A1. Extend the current PTM node
with connection funnel, TPIU, ETB and replicator. The coresight on this
hardware is clocked from the ZT/ZTR trace clock.
Please note that this is written according to R-Mobile A1 User's Manual:
Hardware , Rev.2.00 Sep. 2013 . I currently do not have access to this
hardware, therefore I am sending this as an RFC patchset.
Marek Vasut (4):
dt-bindings: clock: renesas,cpg-clocks: Document ZT/ZTR trace clock on
R-Mobile A1
clk: renesas: r8a7740: Implement ZT/ZTR trace clock on R-Mobile A1
ARM: dts: renesas: r8a7740: Add ZT/ZTR trace clock on R-Mobile A1
ARM: dts: renesas: r8a7740: Describe coresight on R-Mobile A1
.../bindings/clock/renesas,cpg-clocks.yaml | 6 +-
arch/arm/boot/dts/renesas/r8a7740.dtsi | 116 +++++++++++++++++-
drivers/clk/renesas/clk-r8a7740.c | 2 +
include/dt-bindings/clock/r8a7740-clock.h | 2 +
4 files changed, 120 insertions(+), 6 deletions(-)
---
Cc: Conor Dooley <conor+dt@kernel.org>
Cc: Geert Uytterhoeven <geert+renesas@glider.be>
Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
Cc: Magnus Damm <magnus.damm@gmail.com>
Cc: Michael Turquette <mturquette@baylibre.com>
Cc: Rob Herring <robh@kernel.org>
Cc: Stephen Boyd <sboyd@kernel.org>
Cc: devicetree@vger.kernel.org
Cc: linux-clk@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Cc: linux-renesas-soc@vger.kernel.org
--
2.53.0
^ permalink raw reply
* Re: [PATCH v13 00/48] arm64: Support for Arm CCA in KVM
From: Alper Gun @ 2026-04-15 23:27 UTC (permalink / raw)
To: Steven Price
Cc: kvm, kvmarm, Catalin Marinas, Marc Zyngier, Will Deacon,
James Morse, Oliver Upton, Suzuki K Poulose, Zenghui Yu,
linux-arm-kernel, linux-kernel, Joey Gouly, Alexandru Elisei,
Christoffer Dall, Fuad Tabba, linux-coco, Ganapatrao Kulkarni,
Gavin Shan, Shanker Donthineni, Aneesh Kumar K . V, Emi Kisanuki,
Vishal Annapurve
In-Reply-To: <d661a24c-6619-4734-96bd-075d3416e809@arm.com>
On Wed, Apr 15, 2026 at 4:01 AM Steven Price <steven.price@arm.com> wrote:
>
> On 14/04/2026 22:40, Alper Gun wrote:
> > On Wed, Mar 18, 2026 at 8:54 AM Steven Price <steven.price@arm.com> wrote:
> >>
> >> This series adds support for running protected VMs using KVM under the
> >> Arm Confidential Compute Architecture (CCA).
> >>
> >> New major version number! This now targets RMM v2.0-bet0[1]. And unlike
> >> for Linux this represents a significant change.
> >>
> >> RMM v2.0 brings with it the ability to configure the RMM to have the
> >> same page size as the host (so no more RMM_PAGE_SIZE and dealing with
> >> granules being different from host pages). It also introduces range
> >> based APIs for many operations which should be more efficient and
> >> simplifies the code in places.
> >>
> >> The handling of the GIC has changed, so the system registers are used to
> >> pass the GIC state rather than memory. This means fewer changes to the
> >> KVM code as it looks much like a normal VM in this respect.
> >>
> >> And of course the new uAPI introduced in the previous v12 posting is
> >> retained so that also remains simplified compared to earlier postings.
> >>
> >> The RMM support for v2.0 is still early and so this series includes a
> >> few hacks to ease the integration. Of note are that there are some RMM
> >> v1.0 SMCs added to paper over areas where the RMM implementation isn't
> >> quite ready for v2.0, and "SROs" (see below) are deferred to the final
> >> patch in the series.
> >>
> >> The PMU in RMM v2.0 requires more handling on the RMM-side (and
> >> therefore simplifies the implementation on Linux), but this isn't quite
> >> ready yet. The Linux side is implemented (but untested).
> >>
> >> PSCI still requires the VMM to provide the "target" REC for operations
> >> that affect another vCPU. This is likely to change in a future version
> >> of the specification. There's also a desire to force PSCI to be handled
> >> in the VMM for realm guests - this isn't implemented yet as I'm waiting
> >> for the dust to settle on the RMM interface first.
> >>
> >> Stateful RMI Operations
> >> -----------------------
> >>
> >> The RMM v2.0 spec brings a new concept of Stateful RMI Operations (SROs)
> >> which allow the RMM to complete an operation over several SMC calls and
> >> requesting/returning memory to the host. This has the benefit of
> >> allowing interrupts to be handled in the middle of an operation (by
> >> returning to the host to handle the interrupt without completing the
> >> operation) and enables the RMM to dynamically allocate memory for
> >> internal tracking purposes. One example of this is RMI_REC_CREATE no
> >> longer needs "auxiliary granules" provided upfront but can request the
> >> memory needed during the RMI_REC_CREATE operation.
> >>
> >> There are a fairly large number of operations that are defined as SROs
> >> in the specification, but current both Linux and RMM only have support
> >> for RMI_REC_CREATE and RMI_REC_DESTROY. There a number of TODOs/FIXMEs
> >> in the code where support is missing.
> >>
> >> Given the early stage support for this, the SRO handling is all confined
> >> to the final patch. This patch can be dropped to return to a pre-SRO
> >> state (albeit a mixture of RMM v1.0 and v2.0 APIs) for testing purposes.
> >>
> >> A future posting will reorder the series to move the generic SRO support
> >> to an early patch and will implement the proper support for this in all
> >> RMI SMCs.
> >>
> >> One aspect of SROs which is not yet well captured is that in some
> >> circumstances the Linux kernel will need to call an SRO call in a
> >> context where memory allocation is restricted (e.g. because a spinlock
> >> is held). In this case the intention is that the SRO will be cancelled,
> >> the spinlock dropped so the memory allocation can be completed, and then
> >> the SRO restarted (obviously after rechecking the state that the
> >> spinlock was protecting). For this reason the code stores the memory
> >> allocations within a struct rmi_sro_state object - see the final patch
> >> for more details.
> >>
> >> This series is based on v7.0-rc1. It is also available as a git
> >> repository:
> >>
> >> https://gitlab.arm.com/linux-arm/linux-cca cca-host/v13
> >>
> >>
> >
> > Hi Steven,
> >
> > I have a question regarding host kexec and kdump scenarios, and
> > whether there is any plan to make them work in this initial series.
> >
> > Intel TDX and AMD SEV-SNP both have a firmware shutdown command that
> > is invoked during the kexec or panic code paths to safely bypass
> > hardware memory protections and boot into the new kernel. As far as
> > I know, there is no similar global teardown command available for
> > the RMM.
>
> Correct, the RMM specification as it stands doesn't provide a mechanism
> for the host to do this. The host would have to identify all the realm
> guests in the system: specifically the address of the RDs (Realm
> Descriptors) and RECs (Realm Execution Contexts). It needs this to tear
> down the guests and be able to undelegate the memory.
>
> It's an interesting point and I'll raise the idea of a "firmware
> shutdown command" to make this more possible.
>
> > What is the roadmap for supporting both general kexec and
> > more specifically kdump (panic) scenarios with CCA?
>
> I don't have a roadmap I'm afraid for these. kexec in theory would be
> possible with KVM gracefully terminating all realms. For kdump/panic
> that sort of graceful shutdown isn't really appropriate (or likely to
> succeed).
>
Thanks Steven for the clarification.
For us, kdump is highly critical as it is our primary diagnostic tool
for host crashes. Without it, monitoring and debugging at fleet scale
would become unmanageable.
To confirm my understanding of the current architecture: if a host
panics while no Realms are actively running (and therefore no pages
are currently in the delegated state), the standard kdump extraction
should work perfectly fine without any modifications, correct?
Regarding the KVM tracking structures (RDs, RECs, RTTs, etc.) when VMs
are running, perhaps we could use `vmcoreinfo` to export the physical
addresses of these delegated pages. This would allow tools like
`makedumpfile` to explicitly filter them out. I assume these pages must
remain hardware-locked while the VMs are active.
Long-term, having an architectural shutdown command - similar to the
TDH.SYS.DISABLE command in Intel TDX - would be incredibly useful. It
would allow the kdump kernel to safely bypass these hardware security
checks, especially when extracting host-side KVM state.
As for the protected realm memory, I assume that is an easier problem.
We naturally want to exclude guest pages from a host dump regardless
of whether they are Realm pages or not. However, accidental touches
are still fatal.
> There is also some RMM configuration which cannot be repeated (see
> RMI_RMM_CONFIG_SET) - which implies that the kexec kernel must be
> similar to the first kernel (i.e. same page size).
>
> Thanks,
> Steve
^ permalink raw reply
* [PATCH 6/6] usb: typec: ucsi: huawei-gaokun: pass down HPD_IRQ events
From: Dmitry Baryshkov @ 2026-04-15 23:22 UTC (permalink / raw)
To: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Heikki Krogerus, Greg Kroah-Hartman, Andrzej Hajda,
Neil Armstrong, Robert Foss, Laurent Pinchart, Jonas Karlman,
Jernej Skrabec, Adrien Grassein, Jani Nikula, Rodrigo Vivi,
Joonas Lahtinen, Tvrtko Ursulin, Kevin Hilman, Jerome Brunet,
Martin Blumenstingl, Rob Clark, Dmitry Baryshkov, Abhinav Kumar,
Jessica Zhang, Sean Paul, Marijn Suijten, Tomi Valkeinen,
Bjorn Andersson, Konrad Dybcio, Pengyu Luo, Nikita Travkin,
Yongxing Mou
Cc: dri-devel, linux-kernel, linux-usb, intel-gfx, intel-xe,
linux-amlogic, linux-arm-kernel, linux-arm-msm, freedreno
In-Reply-To: <20260416-hpd-irq-events-v1-0-1ab1f1cfb2b2@oss.qualcomm.com>
Pass IRQ_HPD events to the HPD bridge, letting those to be delivered to
the DisplayPort driver.
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
---
drivers/usb/typec/ucsi/ucsi_huawei_gaokun.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/drivers/usb/typec/ucsi/ucsi_huawei_gaokun.c b/drivers/usb/typec/ucsi/ucsi_huawei_gaokun.c
index ca749fde49bd..328ba92e1b44 100644
--- a/drivers/usb/typec/ucsi/ucsi_huawei_gaokun.c
+++ b/drivers/usb/typec/ucsi/ucsi_huawei_gaokun.c
@@ -299,10 +299,11 @@ static void gaokun_ucsi_handle_altmode(struct gaokun_ucsi_port *port)
/* UCSI callback .connector_status() have set orientation */
if (port->bridge)
- drm_aux_hpd_bridge_notify(&port->bridge->dev,
- port->hpd_state ?
- connector_status_connected :
- connector_status_disconnected);
+ drm_aux_hpd_bridge_notify_with_irq(&port->bridge->dev,
+ port->hpd_state ?
+ connector_status_connected :
+ connector_status_disconnected,
+ port->hpd_irq);
gaokun_ec_ucsi_pan_ack(uec->ec, port->idx);
}
--
2.47.3
^ permalink raw reply related
* [PATCH 4/6] drm/msm: dp: handle the IRQ_HPD events reported by USB-C
From: Dmitry Baryshkov @ 2026-04-15 23:22 UTC (permalink / raw)
To: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Heikki Krogerus, Greg Kroah-Hartman, Andrzej Hajda,
Neil Armstrong, Robert Foss, Laurent Pinchart, Jonas Karlman,
Jernej Skrabec, Adrien Grassein, Jani Nikula, Rodrigo Vivi,
Joonas Lahtinen, Tvrtko Ursulin, Kevin Hilman, Jerome Brunet,
Martin Blumenstingl, Rob Clark, Dmitry Baryshkov, Abhinav Kumar,
Jessica Zhang, Sean Paul, Marijn Suijten, Tomi Valkeinen,
Bjorn Andersson, Konrad Dybcio, Pengyu Luo, Nikita Travkin,
Yongxing Mou
Cc: dri-devel, linux-kernel, linux-usb, intel-gfx, intel-xe,
linux-amlogic, linux-arm-kernel, linux-arm-msm, freedreno
In-Reply-To: <20260416-hpd-irq-events-v1-0-1ab1f1cfb2b2@oss.qualcomm.com>
Let the MSM DisplayPort driver properly track and handle IRQ_HPD
delivered over the OOB events (e.g. from the USB-C AltMode handler).
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
---
drivers/gpu/drm/msm/dp/dp_display.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c
index 45e14a0010c2..390a967a53f0 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.c
+++ b/drivers/gpu/drm/msm/dp/dp_display.c
@@ -1800,4 +1800,7 @@ void msm_dp_bridge_hpd_notify(struct drm_bridge *bridge,
msm_dp_add_event(dp, EV_HPD_PLUG_INT, 0, 0);
else if (msm_dp_display->link_ready && status == connector_status_disconnected)
msm_dp_add_event(dp, EV_HPD_UNPLUG_INT, 0, 0);
+
+ if (irq_hpd)
+ msm_dp_add_event(dp, EV_IRQ_HPD_INT, 0, 0);
}
--
2.47.3
^ permalink raw reply related
* [PATCH 5/6] soc: qcom: pmic-glink-altmode: pass down HPD_IRQ events
From: Dmitry Baryshkov @ 2026-04-15 23:22 UTC (permalink / raw)
To: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Heikki Krogerus, Greg Kroah-Hartman, Andrzej Hajda,
Neil Armstrong, Robert Foss, Laurent Pinchart, Jonas Karlman,
Jernej Skrabec, Adrien Grassein, Jani Nikula, Rodrigo Vivi,
Joonas Lahtinen, Tvrtko Ursulin, Kevin Hilman, Jerome Brunet,
Martin Blumenstingl, Rob Clark, Dmitry Baryshkov, Abhinav Kumar,
Jessica Zhang, Sean Paul, Marijn Suijten, Tomi Valkeinen,
Bjorn Andersson, Konrad Dybcio, Pengyu Luo, Nikita Travkin,
Yongxing Mou
Cc: dri-devel, linux-kernel, linux-usb, intel-gfx, intel-xe,
linux-amlogic, linux-arm-kernel, linux-arm-msm, freedreno
In-Reply-To: <20260416-hpd-irq-events-v1-0-1ab1f1cfb2b2@oss.qualcomm.com>
Pass IRQ_HPD events to the HPD bridge, letting those to be delivered to
the DisplayPort driver.
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
---
drivers/soc/qcom/pmic_glink_altmode.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/soc/qcom/pmic_glink_altmode.c b/drivers/soc/qcom/pmic_glink_altmode.c
index 619bad2c27ee..618dce748316 100644
--- a/drivers/soc/qcom/pmic_glink_altmode.c
+++ b/drivers/soc/qcom/pmic_glink_altmode.c
@@ -373,7 +373,9 @@ static void pmic_glink_altmode_worker(struct work_struct *work)
else
conn_status = connector_status_disconnected;
- drm_aux_hpd_bridge_notify(&alt_port->bridge->dev, conn_status);
+ drm_aux_hpd_bridge_notify_with_irq(&alt_port->bridge->dev,
+ conn_status,
+ alt_port->hpd_irq);
} else if (alt_port->mux_ctrl == MUX_CTRL_STATE_TUNNELING) {
if (alt_port->svid == USB_TYPEC_TBT_SID)
pmic_glink_altmode_enable_tbt(altmode, alt_port);
--
2.47.3
^ permalink raw reply related
* [PATCH 3/6] drm/bridge: aux-hpd: let drivers pass IRQ_HPD events
From: Dmitry Baryshkov @ 2026-04-15 23:22 UTC (permalink / raw)
To: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Heikki Krogerus, Greg Kroah-Hartman, Andrzej Hajda,
Neil Armstrong, Robert Foss, Laurent Pinchart, Jonas Karlman,
Jernej Skrabec, Adrien Grassein, Jani Nikula, Rodrigo Vivi,
Joonas Lahtinen, Tvrtko Ursulin, Kevin Hilman, Jerome Brunet,
Martin Blumenstingl, Rob Clark, Dmitry Baryshkov, Abhinav Kumar,
Jessica Zhang, Sean Paul, Marijn Suijten, Tomi Valkeinen,
Bjorn Andersson, Konrad Dybcio, Pengyu Luo, Nikita Travkin,
Yongxing Mou
Cc: dri-devel, linux-kernel, linux-usb, intel-gfx, intel-xe,
linux-amlogic, linux-arm-kernel, linux-arm-msm, freedreno
In-Reply-To: <20260416-hpd-irq-events-v1-0-1ab1f1cfb2b2@oss.qualcomm.com>
Let users of aux-hpd, the UCSI and PMIC GLINK drivers pass the IRQ_HPD
events to the DisplayPort drivers.
The drm_aux_hpd_bridge_notify() is keps to ease merging of the series,
preventing extra cross-tree merges. It will be removed once all
drivers are converted. The drm_bridge_hpd_notify() function is kept for
the driver which only care about the connector status and will always
pass false as the irq_hpd event.
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
---
drivers/gpu/drm/bridge/aux-hpd-bridge.c | 9 ++++++---
drivers/gpu/drm/drm_bridge.c | 15 +++++++++------
include/drm/bridge/aux-bridge.h | 13 +++++++++++--
include/drm/drm_bridge.h | 22 ++++++++++++++++++++--
4 files changed, 46 insertions(+), 13 deletions(-)
diff --git a/drivers/gpu/drm/bridge/aux-hpd-bridge.c b/drivers/gpu/drm/bridge/aux-hpd-bridge.c
index f02a38a2638a..74d606b27dc6 100644
--- a/drivers/gpu/drm/bridge/aux-hpd-bridge.c
+++ b/drivers/gpu/drm/bridge/aux-hpd-bridge.c
@@ -136,16 +136,19 @@ struct device *drm_dp_hpd_bridge_register(struct device *parent, struct device_n
EXPORT_SYMBOL_GPL(drm_dp_hpd_bridge_register);
/**
- * drm_aux_hpd_bridge_notify - notify hot plug detection events
+ * drm_aux_hpd_bridge_notify_with_irq - notify hot plug detection events
* @dev: device created for the HPD bridge
* @status: output connection status
+ * @irq_hpd: recorded IRQ_HPD status
*
* A wrapper around drm_bridge_hpd_notify() that is used to report hot plug
* detection events for bridges created via drm_dp_hpd_bridge_register().
*
* This function shall be called in a context that can sleep.
*/
-void drm_aux_hpd_bridge_notify(struct device *dev, enum drm_connector_status status)
+void drm_aux_hpd_bridge_notify_with_irq(struct device *dev,
+ enum drm_connector_status status,
+ bool irq_hpd)
{
struct auxiliary_device *adev = to_auxiliary_dev(dev);
struct drm_aux_hpd_bridge_data *data = auxiliary_get_drvdata(adev);
@@ -155,7 +158,7 @@ void drm_aux_hpd_bridge_notify(struct device *dev, enum drm_connector_status sta
drm_bridge_hpd_notify(&data->bridge, status);
}
-EXPORT_SYMBOL_GPL(drm_aux_hpd_bridge_notify);
+EXPORT_SYMBOL_GPL(drm_aux_hpd_bridge_notify_with_irq);
static int drm_aux_hpd_bridge_attach(struct drm_bridge *bridge,
struct drm_encoder *encoder,
diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c
index 9c44e9b6c638..5a3dd4f92fbc 100644
--- a/drivers/gpu/drm/drm_bridge.c
+++ b/drivers/gpu/drm/drm_bridge.c
@@ -1495,25 +1495,28 @@ void drm_bridge_hpd_disable(struct drm_bridge *bridge)
EXPORT_SYMBOL_GPL(drm_bridge_hpd_disable);
/**
- * drm_bridge_hpd_notify - notify hot plug detection events
+ * drm_bridge_hpd_notify_with_irq - notify hot plug detection and sink IRQ events
* @bridge: bridge control structure
* @status: output connection status
+ * @irq_hpd: recorded IRQ_HPD status
*
* Bridge drivers shall call this function to report hot plug events when they
- * detect a change in the output status, when hot plug detection has been
+ * detect a change in the output status or when the sink has reported the IRQ
+ * event (usually delivered as IRQ_HPD pulse), when hot plug detection has been
* enabled by drm_bridge_hpd_enable().
*
* This function shall be called in a context that can sleep.
*/
-void drm_bridge_hpd_notify(struct drm_bridge *bridge,
- enum drm_connector_status status)
+void drm_bridge_hpd_notify_with_irq(struct drm_bridge *bridge,
+ enum drm_connector_status status,
+ bool irq_hpd)
{
mutex_lock(&bridge->hpd_mutex);
if (bridge->hpd_cb)
- bridge->hpd_cb(bridge->hpd_data, status, false);
+ bridge->hpd_cb(bridge->hpd_data, status, irq_hpd);
mutex_unlock(&bridge->hpd_mutex);
}
-EXPORT_SYMBOL_GPL(drm_bridge_hpd_notify);
+EXPORT_SYMBOL_GPL(drm_bridge_hpd_notify_with_irq);
#ifdef CONFIG_OF
/**
diff --git a/include/drm/bridge/aux-bridge.h b/include/drm/bridge/aux-bridge.h
index c2f5a855512f..6f837df90b2f 100644
--- a/include/drm/bridge/aux-bridge.h
+++ b/include/drm/bridge/aux-bridge.h
@@ -25,7 +25,9 @@ struct auxiliary_device *devm_drm_dp_hpd_bridge_alloc(struct device *parent, str
int devm_drm_dp_hpd_bridge_add(struct device *dev, struct auxiliary_device *adev);
struct device *drm_dp_hpd_bridge_register(struct device *parent,
struct device_node *np);
-void drm_aux_hpd_bridge_notify(struct device *dev, enum drm_connector_status status);
+void drm_aux_hpd_bridge_notify_with_irq(struct device *dev,
+ enum drm_connector_status status,
+ bool irq_hpd);
#else
static inline struct auxiliary_device *devm_drm_dp_hpd_bridge_alloc(struct device *parent,
struct device_node *np)
@@ -44,9 +46,16 @@ static inline struct device *drm_dp_hpd_bridge_register(struct device *parent,
return NULL;
}
-static inline void drm_aux_hpd_bridge_notify(struct device *dev, enum drm_connector_status status)
+static inline void drm_aux_hpd_bridge_notify_with_irq(struct device *dev,
+ enum drm_connector_status status,
+ bool irq_hpd)
{
}
#endif
+static inline void drm_aux_hpd_bridge_notify(struct device *dev, enum drm_connector_status status)
+{
+ drm_aux_hpd_bridge_notify_with_irq(dev, status, false);
+}
+
#endif
diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h
index 4eea124c7eb7..c3bb30133925 100644
--- a/include/drm/drm_bridge.h
+++ b/include/drm/drm_bridge.h
@@ -1555,8 +1555,26 @@ void drm_bridge_hpd_enable(struct drm_bridge *bridge,
bool irq_hpd),
void *data);
void drm_bridge_hpd_disable(struct drm_bridge *bridge);
-void drm_bridge_hpd_notify(struct drm_bridge *bridge,
- enum drm_connector_status status);
+void drm_bridge_hpd_notify_with_irq(struct drm_bridge *bridge,
+ enum drm_connector_status status,
+ bool irq_hpd);
+
+/**
+ * drm_bridge_hpd_notify - notify hot plug detection events
+ * @bridge: bridge control structure
+ * @status: output connection status
+ *
+ * Bridge drivers shall call this function to report hot plug events when they
+ * detect a change in the output status, when hot plug detection has been
+ * enabled by drm_bridge_hpd_enable().
+ *
+ * This function shall be called in a context that can sleep.
+ */
+static inline void drm_bridge_hpd_notify(struct drm_bridge *bridge,
+ enum drm_connector_status status)
+{
+ drm_bridge_hpd_notify_with_irq(bridge, status, false);
+}
#ifdef CONFIG_DRM_PANEL_BRIDGE
bool drm_bridge_is_panel(const struct drm_bridge *bridge);
--
2.47.3
^ permalink raw reply related
* [PATCH 2/6] drm/bridge: pass down IRQ_HPD to the drivers
From: Dmitry Baryshkov @ 2026-04-15 23:22 UTC (permalink / raw)
To: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Heikki Krogerus, Greg Kroah-Hartman, Andrzej Hajda,
Neil Armstrong, Robert Foss, Laurent Pinchart, Jonas Karlman,
Jernej Skrabec, Adrien Grassein, Jani Nikula, Rodrigo Vivi,
Joonas Lahtinen, Tvrtko Ursulin, Kevin Hilman, Jerome Brunet,
Martin Blumenstingl, Rob Clark, Dmitry Baryshkov, Abhinav Kumar,
Jessica Zhang, Sean Paul, Marijn Suijten, Tomi Valkeinen,
Bjorn Andersson, Konrad Dybcio, Pengyu Luo, Nikita Travkin,
Yongxing Mou
Cc: dri-devel, linux-kernel, linux-usb, intel-gfx, intel-xe,
linux-amlogic, linux-arm-kernel, linux-arm-msm, freedreno
In-Reply-To: <20260416-hpd-irq-events-v1-0-1ab1f1cfb2b2@oss.qualcomm.com>
Pass down the notifications about the IRQ_HPD events down to the
individual drivers, letting them handle those as required.
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
---
drivers/gpu/drm/bridge/chrontel-ch7033.c | 2 +-
drivers/gpu/drm/bridge/lontium-lt8912b.c | 2 +-
drivers/gpu/drm/bridge/lontium-lt9611uxc.c | 3 ++-
drivers/gpu/drm/bridge/ti-tfp410.c | 2 +-
drivers/gpu/drm/display/drm_bridge_connector.c | 21 ++++++++++++---------
drivers/gpu/drm/drm_bridge.c | 5 +++--
drivers/gpu/drm/drm_connector.c | 2 +-
drivers/gpu/drm/i915/display/intel_dp.c | 3 ++-
drivers/gpu/drm/meson/meson_encoder_hdmi.c | 3 ++-
drivers/gpu/drm/msm/dp/dp_display.c | 3 ++-
drivers/gpu/drm/msm/dp/dp_drm.h | 3 ++-
drivers/gpu/drm/omapdrm/dss/hdmi4.c | 3 ++-
include/drm/drm_bridge.h | 8 +++++---
include/drm/drm_connector.h | 3 ++-
14 files changed, 38 insertions(+), 25 deletions(-)
diff --git a/drivers/gpu/drm/bridge/chrontel-ch7033.c b/drivers/gpu/drm/bridge/chrontel-ch7033.c
index 54d49d4882c8..6d932dbe062b 100644
--- a/drivers/gpu/drm/bridge/chrontel-ch7033.c
+++ b/drivers/gpu/drm/bridge/chrontel-ch7033.c
@@ -259,7 +259,7 @@ static const struct drm_connector_helper_funcs ch7033_connector_helper_funcs = {
.best_encoder = ch7033_connector_best_encoder,
};
-static void ch7033_hpd_event(void *arg, enum drm_connector_status status)
+static void ch7033_hpd_event(void *arg, enum drm_connector_status status, bool irq_hpd)
{
struct ch7033_priv *priv = arg;
diff --git a/drivers/gpu/drm/bridge/lontium-lt8912b.c b/drivers/gpu/drm/bridge/lontium-lt8912b.c
index 8a0b48efca58..3ffbb7346418 100644
--- a/drivers/gpu/drm/bridge/lontium-lt8912b.c
+++ b/drivers/gpu/drm/bridge/lontium-lt8912b.c
@@ -504,7 +504,7 @@ static int lt8912_attach_dsi(struct lt8912 *lt)
return 0;
}
-static void lt8912_bridge_hpd_cb(void *data, enum drm_connector_status status)
+static void lt8912_bridge_hpd_cb(void *data, enum drm_connector_status status, bool irq_hpd)
{
struct lt8912 *lt = data;
diff --git a/drivers/gpu/drm/bridge/lontium-lt9611uxc.c b/drivers/gpu/drm/bridge/lontium-lt9611uxc.c
index 11aab07d88df..7e5a110cfa1f 100644
--- a/drivers/gpu/drm/bridge/lontium-lt9611uxc.c
+++ b/drivers/gpu/drm/bridge/lontium-lt9611uxc.c
@@ -430,7 +430,8 @@ static const struct drm_edid *lt9611uxc_bridge_edid_read(struct drm_bridge *brid
static void lt9611uxc_bridge_hpd_notify(struct drm_bridge *bridge,
struct drm_connector *connector,
- enum drm_connector_status status)
+ enum drm_connector_status status,
+ bool irq_hpd)
{
const struct drm_edid *drm_edid;
diff --git a/drivers/gpu/drm/bridge/ti-tfp410.c b/drivers/gpu/drm/bridge/ti-tfp410.c
index 3b6b0e92cf89..4111aa104256 100644
--- a/drivers/gpu/drm/bridge/ti-tfp410.c
+++ b/drivers/gpu/drm/bridge/ti-tfp410.c
@@ -110,7 +110,7 @@ static void tfp410_hpd_work_func(struct work_struct *work)
drm_helper_hpd_irq_event(dvi->bridge.dev);
}
-static void tfp410_hpd_callback(void *arg, enum drm_connector_status status)
+static void tfp410_hpd_callback(void *arg, enum drm_connector_status status, bool irq_hpd)
{
struct tfp410 *dvi = arg;
diff --git a/drivers/gpu/drm/display/drm_bridge_connector.c b/drivers/gpu/drm/display/drm_bridge_connector.c
index 39cc18f78eda..749d3d63216c 100644
--- a/drivers/gpu/drm/display/drm_bridge_connector.c
+++ b/drivers/gpu/drm/display/drm_bridge_connector.c
@@ -141,7 +141,8 @@ struct drm_bridge_connector {
*/
static void drm_bridge_connector_hpd_notify(struct drm_connector *connector,
- enum drm_connector_status status)
+ enum drm_connector_status status,
+ bool irq_hpd)
{
struct drm_bridge_connector *bridge_connector =
to_drm_bridge_connector(connector);
@@ -149,12 +150,12 @@ static void drm_bridge_connector_hpd_notify(struct drm_connector *connector,
/* Notify all bridges in the pipeline of hotplug events. */
drm_for_each_bridge_in_chain_scoped(bridge_connector->encoder, bridge) {
if (bridge->funcs->hpd_notify)
- bridge->funcs->hpd_notify(bridge, connector, status);
+ bridge->funcs->hpd_notify(bridge, connector, status, irq_hpd);
}
}
static void drm_bridge_connector_handle_hpd(struct drm_bridge_connector *drm_bridge_connector,
- enum drm_connector_status status)
+ enum drm_connector_status status, bool irq_hpd)
{
struct drm_connector *connector = &drm_bridge_connector->base;
struct drm_device *dev = connector->dev;
@@ -163,24 +164,26 @@ static void drm_bridge_connector_handle_hpd(struct drm_bridge_connector *drm_bri
connector->status = status;
mutex_unlock(&dev->mode_config.mutex);
- drm_bridge_connector_hpd_notify(connector, status);
+ drm_bridge_connector_hpd_notify(connector, status, irq_hpd);
drm_kms_helper_connector_hotplug_event(connector);
}
static void drm_bridge_connector_hpd_cb(void *cb_data,
- enum drm_connector_status status)
+ enum drm_connector_status status,
+ bool irq_hpd)
{
- drm_bridge_connector_handle_hpd(cb_data, status);
+ drm_bridge_connector_handle_hpd(cb_data, status, irq_hpd);
}
static void drm_bridge_connector_oob_hotplug_event(struct drm_connector *connector,
- enum drm_connector_status status)
+ enum drm_connector_status status,
+ bool irq_hpd)
{
struct drm_bridge_connector *bridge_connector =
to_drm_bridge_connector(connector);
- drm_bridge_connector_handle_hpd(bridge_connector, status);
+ drm_bridge_connector_handle_hpd(bridge_connector, status, irq_hpd);
}
static void drm_bridge_connector_enable_hpd(struct drm_connector *connector)
@@ -223,7 +226,7 @@ drm_bridge_connector_detect(struct drm_connector *connector, bool force)
if (hdmi)
drm_atomic_helper_connector_hdmi_hotplug(connector, status);
- drm_bridge_connector_hpd_notify(connector, status);
+ drm_bridge_connector_hpd_notify(connector, status, false);
} else {
switch (connector->connector_type) {
case DRM_MODE_CONNECTOR_DPI:
diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c
index d6f512b73389..9c44e9b6c638 100644
--- a/drivers/gpu/drm/drm_bridge.c
+++ b/drivers/gpu/drm/drm_bridge.c
@@ -1444,7 +1444,8 @@ EXPORT_SYMBOL_GPL(drm_bridge_edid_read);
*/
void drm_bridge_hpd_enable(struct drm_bridge *bridge,
void (*cb)(void *data,
- enum drm_connector_status status),
+ enum drm_connector_status status,
+ bool irq_hpd),
void *data)
{
if (!(bridge->ops & DRM_BRIDGE_OP_HPD))
@@ -1509,7 +1510,7 @@ void drm_bridge_hpd_notify(struct drm_bridge *bridge,
{
mutex_lock(&bridge->hpd_mutex);
if (bridge->hpd_cb)
- bridge->hpd_cb(bridge->hpd_data, status);
+ bridge->hpd_cb(bridge->hpd_data, status, false);
mutex_unlock(&bridge->hpd_mutex);
}
EXPORT_SYMBOL_GPL(drm_bridge_hpd_notify);
diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index 5fdacbd84bd7..809ce38c4822 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -3531,7 +3531,7 @@ void drm_connector_oob_hotplug_event(struct fwnode_handle *connector_fwnode,
return;
if (connector->funcs->oob_hotplug_event)
- connector->funcs->oob_hotplug_event(connector, status);
+ connector->funcs->oob_hotplug_event(connector, status, irq_hpd);
drm_connector_put(connector);
}
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index b8b6d62fb275..524d6c67ca54 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -6784,7 +6784,8 @@ static int intel_dp_connector_atomic_check(struct drm_connector *_connector,
}
static void intel_dp_oob_hotplug_event(struct drm_connector *_connector,
- enum drm_connector_status hpd_state)
+ enum drm_connector_status hpd_state,
+ bool irq_hpd)
{
struct intel_connector *connector = to_intel_connector(_connector);
struct intel_display *display = to_intel_display(connector);
diff --git a/drivers/gpu/drm/meson/meson_encoder_hdmi.c b/drivers/gpu/drm/meson/meson_encoder_hdmi.c
index 1abb0572bb5f..346c4d2e26e8 100644
--- a/drivers/gpu/drm/meson/meson_encoder_hdmi.c
+++ b/drivers/gpu/drm/meson/meson_encoder_hdmi.c
@@ -323,7 +323,8 @@ static int meson_encoder_hdmi_atomic_check(struct drm_bridge *bridge,
static void meson_encoder_hdmi_hpd_notify(struct drm_bridge *bridge,
struct drm_connector *connector,
- enum drm_connector_status status)
+ enum drm_connector_status status,
+ bool irq_hpd)
{
struct meson_encoder_hdmi *encoder_hdmi = bridge_to_meson_encoder_hdmi(bridge);
diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c
index d2124d625485..45e14a0010c2 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.c
+++ b/drivers/gpu/drm/msm/dp/dp_display.c
@@ -1785,7 +1785,8 @@ void msm_dp_bridge_hpd_disable(struct drm_bridge *bridge)
void msm_dp_bridge_hpd_notify(struct drm_bridge *bridge,
struct drm_connector *connector,
- enum drm_connector_status status)
+ enum drm_connector_status status,
+ bool irq_hpd)
{
struct msm_dp_bridge *msm_dp_bridge = to_dp_bridge(bridge);
struct msm_dp *msm_dp_display = msm_dp_bridge->msm_dp_display;
diff --git a/drivers/gpu/drm/msm/dp/dp_drm.h b/drivers/gpu/drm/msm/dp/dp_drm.h
index 9eb3431dd93a..5a877655d56c 100644
--- a/drivers/gpu/drm/msm/dp/dp_drm.h
+++ b/drivers/gpu/drm/msm/dp/dp_drm.h
@@ -41,6 +41,7 @@ void msm_dp_bridge_hpd_enable(struct drm_bridge *bridge);
void msm_dp_bridge_hpd_disable(struct drm_bridge *bridge);
void msm_dp_bridge_hpd_notify(struct drm_bridge *bridge,
struct drm_connector *connector,
- enum drm_connector_status status);
+ enum drm_connector_status status,
+ bool irq_hpd);
#endif /* _DP_DRM_H_ */
diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi4.c b/drivers/gpu/drm/omapdrm/dss/hdmi4.c
index 29b2dfb90b5f..dae9e464889c 100644
--- a/drivers/gpu/drm/omapdrm/dss/hdmi4.c
+++ b/drivers/gpu/drm/omapdrm/dss/hdmi4.c
@@ -429,7 +429,8 @@ static void hdmi4_bridge_disable(struct drm_bridge *bridge,
static void hdmi4_bridge_hpd_notify(struct drm_bridge *bridge,
struct drm_connector *connector,
- enum drm_connector_status status)
+ enum drm_connector_status status,
+ bool irq_hpd)
{
struct omap_hdmi *hdmi = drm_bridge_to_hdmi(bridge);
diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h
index a8d67bd9ee50..4eea124c7eb7 100644
--- a/include/drm/drm_bridge.h
+++ b/include/drm/drm_bridge.h
@@ -615,7 +615,8 @@ struct drm_bridge_funcs {
*/
void (*hpd_notify)(struct drm_bridge *bridge,
struct drm_connector *connector,
- enum drm_connector_status status);
+ enum drm_connector_status status,
+ bool irq_hpd);
/**
* @hpd_enable:
@@ -1260,7 +1261,7 @@ struct drm_bridge {
* @hpd_cb: Hot plug detection callback, registered with
* drm_bridge_hpd_enable().
*/
- void (*hpd_cb)(void *data, enum drm_connector_status status);
+ void (*hpd_cb)(void *data, enum drm_connector_status status, bool irq_hpd);
/**
* @hpd_data: Private data passed to the Hot plug detection callback
* @hpd_cb.
@@ -1550,7 +1551,8 @@ const struct drm_edid *drm_bridge_edid_read(struct drm_bridge *bridge,
struct drm_connector *connector);
void drm_bridge_hpd_enable(struct drm_bridge *bridge,
void (*cb)(void *data,
- enum drm_connector_status status),
+ enum drm_connector_status status,
+ bool irq_hpd),
void *data);
void drm_bridge_hpd_disable(struct drm_bridge *bridge);
void drm_bridge_hpd_notify(struct drm_bridge *bridge,
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index e8e7e6c9eb5c..e164b0dbaa47 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -1704,7 +1704,8 @@ struct drm_connector_funcs {
* has been received from a source outside the display driver / device.
*/
void (*oob_hotplug_event)(struct drm_connector *connector,
- enum drm_connector_status status);
+ enum drm_connector_status status,
+ bool irq_hpd);
/**
* @debugfs_init:
--
2.47.3
^ permalink raw reply related
* [PATCH 1/6] drm/connector: report IRQ_HPD events to drm_connector_oob_hotplug_event()
From: Dmitry Baryshkov @ 2026-04-15 23:22 UTC (permalink / raw)
To: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Heikki Krogerus, Greg Kroah-Hartman, Andrzej Hajda,
Neil Armstrong, Robert Foss, Laurent Pinchart, Jonas Karlman,
Jernej Skrabec, Adrien Grassein, Jani Nikula, Rodrigo Vivi,
Joonas Lahtinen, Tvrtko Ursulin, Kevin Hilman, Jerome Brunet,
Martin Blumenstingl, Rob Clark, Dmitry Baryshkov, Abhinav Kumar,
Jessica Zhang, Sean Paul, Marijn Suijten, Tomi Valkeinen,
Bjorn Andersson, Konrad Dybcio, Pengyu Luo, Nikita Travkin,
Yongxing Mou
Cc: dri-devel, linux-kernel, linux-usb, intel-gfx, intel-xe,
linux-amlogic, linux-arm-kernel, linux-arm-msm, freedreno
In-Reply-To: <20260416-hpd-irq-events-v1-0-1ab1f1cfb2b2@oss.qualcomm.com>
The DisplayPort standard defines a special kind of events called IRQ.
These events are used to notify DP Source about the events on the Sink
side. It is extremely important for DP MST handling, where the MST
events are reported through this IRQ.
In case of the USB-C DP AltMode there is no actual HPD pulse, but the
events are ported through the bits in the AltMode VDOs.
Extend the drm_connector_oob_hotplug_event() interface and report IRQ
events to the DisplayPort Sink drivers.
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
---
drivers/gpu/drm/drm_connector.c | 4 +++-
drivers/usb/typec/altmodes/displayport.c | 12 ++++++++----
include/drm/drm_connector.h | 3 ++-
3 files changed, 13 insertions(+), 6 deletions(-)
diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index 47dc53c4a738..5fdacbd84bd7 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -3510,6 +3510,7 @@ struct drm_connector *drm_connector_find_by_fwnode(struct fwnode_handle *fwnode)
* drm_connector_oob_hotplug_event - Report out-of-band hotplug event to connector
* @connector_fwnode: fwnode_handle to report the event on
* @status: hot plug detect logical state
+ * @irq_hpd: HPD pulse detected
*
* On some hardware a hotplug event notification may come from outside the display
* driver / device. An example of this is some USB Type-C setups where the hardware
@@ -3520,7 +3521,8 @@ struct drm_connector *drm_connector_find_by_fwnode(struct fwnode_handle *fwnode)
* a drm_connector reference through calling drm_connector_find_by_fwnode().
*/
void drm_connector_oob_hotplug_event(struct fwnode_handle *connector_fwnode,
- enum drm_connector_status status)
+ enum drm_connector_status status,
+ bool irq_hpd)
{
struct drm_connector *connector;
diff --git a/drivers/usb/typec/altmodes/displayport.c b/drivers/usb/typec/altmodes/displayport.c
index 35d9c3086990..0cade62da905 100644
--- a/drivers/usb/typec/altmodes/displayport.c
+++ b/drivers/usb/typec/altmodes/displayport.c
@@ -189,7 +189,8 @@ static int dp_altmode_status_update(struct dp_altmode *dp)
} else {
drm_connector_oob_hotplug_event(dp->connector_fwnode,
hpd ? connector_status_connected :
- connector_status_disconnected);
+ connector_status_disconnected,
+ hpd && irq_hpd);
dp->hpd = hpd;
sysfs_notify(&dp->alt->dev.kobj, "displayport", "hpd");
if (hpd && irq_hpd) {
@@ -212,7 +213,8 @@ static int dp_altmode_configured(struct dp_altmode *dp)
*/
if (dp->pending_hpd) {
drm_connector_oob_hotplug_event(dp->connector_fwnode,
- connector_status_connected);
+ connector_status_connected,
+ dp->pending_irq_hpd);
sysfs_notify(&dp->alt->dev.kobj, "displayport", "hpd");
dp->pending_hpd = false;
if (dp->pending_irq_hpd) {
@@ -397,7 +399,8 @@ static int dp_altmode_vdm(struct typec_altmode *alt,
dp->data.conf = 0;
if (dp->hpd) {
drm_connector_oob_hotplug_event(dp->connector_fwnode,
- connector_status_disconnected);
+ connector_status_disconnected,
+ false);
dp->hpd = false;
sysfs_notify(&dp->alt->dev.kobj, "displayport", "hpd");
}
@@ -827,7 +830,8 @@ void dp_altmode_remove(struct typec_altmode *alt)
if (dp->connector_fwnode) {
drm_connector_oob_hotplug_event(dp->connector_fwnode,
- connector_status_disconnected);
+ connector_status_disconnected,
+ false);
fwnode_handle_put(dp->connector_fwnode);
}
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index f83f28cae207..e8e7e6c9eb5c 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -2521,7 +2521,8 @@ drm_connector_is_unregistered(struct drm_connector *connector)
}
void drm_connector_oob_hotplug_event(struct fwnode_handle *connector_fwnode,
- enum drm_connector_status status);
+ enum drm_connector_status status,
+ bool irq_hpd);
const char *drm_get_connector_type_name(unsigned int connector_type);
const char *drm_get_connector_status_name(enum drm_connector_status status);
const char *drm_get_subpixel_order_name(enum subpixel_order order);
--
2.47.3
^ permalink raw reply related
* [PATCH 0/6] drm: handle IRQ_HPD events correctly
From: Dmitry Baryshkov @ 2026-04-15 23:22 UTC (permalink / raw)
To: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Heikki Krogerus, Greg Kroah-Hartman, Andrzej Hajda,
Neil Armstrong, Robert Foss, Laurent Pinchart, Jonas Karlman,
Jernej Skrabec, Adrien Grassein, Jani Nikula, Rodrigo Vivi,
Joonas Lahtinen, Tvrtko Ursulin, Kevin Hilman, Jerome Brunet,
Martin Blumenstingl, Rob Clark, Dmitry Baryshkov, Abhinav Kumar,
Jessica Zhang, Sean Paul, Marijn Suijten, Tomi Valkeinen,
Bjorn Andersson, Konrad Dybcio, Pengyu Luo, Nikita Travkin,
Yongxing Mou
Cc: dri-devel, linux-kernel, linux-usb, intel-gfx, intel-xe,
linux-amlogic, linux-arm-kernel, linux-arm-msm, freedreno
Both DisplayPort and HDMI standards define a way for the Sink / display
to notify the Source / host about some kinds of events. In case of HDMI
it's as simple as singnalling changes to the EDID. In case of
DisplayPort it's more complicated and requires actual checking of the
DPCD registers.
Currently USB-C drivers don't have a way to deliver the IRQ_HPD
notifications, leading to missing MST notifications. Provide necessary
plumbing to let IRQ_HPD events be passed to the DisplayPort drivers.
Note: the Yoga C630 UCSI driver and Acer Aspire1 EC driver are not yet
enabled to send the IRQ_HPD events. Both of them would need some more
reverse engineering to find out how the event is being reported by the
EC.
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
---
Dmitry Baryshkov (6):
drm/connector: report IRQ_HPD events to drm_connector_oob_hotplug_event()
drm/bridge: pass down IRQ_HPD to the drivers
drm/bridge: aux-hpd: let drivers pass IRQ_HPD events
drm/msm: dp: handle the IRQ_HPD events reported by USB-C
soc: qcom: pmic-glink-altmode: pass down HPD_IRQ events
usb: typec: ucsi: huawei-gaokun: pass down HPD_IRQ events
drivers/gpu/drm/bridge/aux-hpd-bridge.c | 9 +++++---
drivers/gpu/drm/bridge/chrontel-ch7033.c | 2 +-
drivers/gpu/drm/bridge/lontium-lt8912b.c | 2 +-
drivers/gpu/drm/bridge/lontium-lt9611uxc.c | 3 ++-
drivers/gpu/drm/bridge/ti-tfp410.c | 2 +-
drivers/gpu/drm/display/drm_bridge_connector.c | 21 ++++++++++--------
drivers/gpu/drm/drm_bridge.c | 18 ++++++++++------
drivers/gpu/drm/drm_connector.c | 6 ++++--
drivers/gpu/drm/i915/display/intel_dp.c | 3 ++-
drivers/gpu/drm/meson/meson_encoder_hdmi.c | 3 ++-
drivers/gpu/drm/msm/dp/dp_display.c | 6 +++++-
drivers/gpu/drm/msm/dp/dp_drm.h | 3 ++-
drivers/gpu/drm/omapdrm/dss/hdmi4.c | 3 ++-
drivers/soc/qcom/pmic_glink_altmode.c | 4 +++-
drivers/usb/typec/altmodes/displayport.c | 12 +++++++----
drivers/usb/typec/ucsi/ucsi_huawei_gaokun.c | 9 ++++----
include/drm/bridge/aux-bridge.h | 13 +++++++++--
include/drm/drm_bridge.h | 30 +++++++++++++++++++++-----
include/drm/drm_connector.h | 6 ++++--
19 files changed, 107 insertions(+), 48 deletions(-)
---
base-commit: 66672af7a095d89f082c5327f3b15bc2f93d558e
change-id: 20260414-hpd-irq-events-e72bc076a5f1
Best regards,
--
With best wishes
Dmitry
^ permalink raw reply
* Re: [PATCH 1/1] KVM: arm64: nv: Avoid full shadow s2 unmap
From: Wei-Lin Chang @ 2026-04-15 23:05 UTC (permalink / raw)
To: Marc Zyngier
Cc: linux-arm-kernel, kvmarm, linux-kernel, Oliver Upton, Joey Gouly,
Suzuki K Poulose, Zenghui Yu, Catalin Marinas, Will Deacon
In-Reply-To: <86eckg39eo.wl-maz@kernel.org>
On Wed, Apr 15, 2026 at 09:38:55AM +0100, Marc Zyngier wrote:
> On Sat, 11 Apr 2026 13:50:24 +0100,
> Wei-Lin Chang <weilin.chang@arm.com> wrote:
> >
> > Currently we are forced to fully unmap all shadow stage-2 for a VM when
> > unmapping a page from the canonical stage-2, for example during an MMU
> > notifier call. This is because we are not tracking what canonical IPA
> > are mapped in the shadow stage-2 page tables hence there is no way to
> > know what to unmap.
> >
> > Create a per kvm_s2_mmu maple tree to track canonical IPA range ->
> > nested IPA range, so that it is possible to partially unmap shadow
> > stage-2 when a canonical IPA range is unmapped. The algorithm is simple
> > and conservative:
> >
> > At each shadow stage-2 map, insert the nested IPA range into the maple
> > tree, with the canonical IPA range as the key. If the canonical IPA
> > range doesn't overlap with existing ranges in the tree, insert as is,
> > and a reverse mapping for this range is established. But if the
> > canonical IPA range overlaps with any existing ranges in the tree,
> > create a new range that spans all the overlapping ranges including the
> > input range and replace those existing ranges. In the mean time, mark
> > this new spanning canonical IPA range as "polluted" indicating we lost
> > track of the nested IPA ranges that map to this canonical IPA range.
> >
> > The maple tree's 64 bit entry is enough to store the nested IPA and
> > polluted status (stored as a bit called UNKNOWN_IPA), therefore besides
> > maple tree's internal operation, memory allocation is avoided.
> >
> > Example:
> > |||| means existing range, ---- means empty range
> >
> > input: $$$$$$$$$$$$$$$$$$$$$$$$$$
> > tree: --||||-----|||||||---------||||||||||-----------
> >
> > insert spanning range and replace overlapping ones:
> > --||||-----||||||||||||||||||||||||||-----------
> > ^^^^^^^^polluted!^^^^^^^^^
>
> I think you should stick to a single terminology. It is either
> "polluted", or "unknown IPA". My preference goes to the latter, as the
> former is not very descriptive in this context.
Sure, I agree.
>
> >
> > With the reverse map created, when a canonical IPA range gets unmapped,
> > look into each s2 mmu's maple tree and look for canonical IPA ranges
> > affected, and base on their polluted status:
> >
> > polluted -> fall back and fully invalidate the current shadow stage-2,
> > also clear the tree
> > not polluted -> unmap the nested IPA range, and remove the reverse map
> > entry
> >
> > Suggested-by: Marc Zyngier <maz@kernel.org>
> > Signed-off-by: Wei-Lin Chang <weilin.chang@arm.com>
> > ---
> > arch/arm64/include/asm/kvm_host.h | 4 +
> > arch/arm64/include/asm/kvm_nested.h | 4 +
> > arch/arm64/kvm/mmu.c | 30 ++++--
> > arch/arm64/kvm/nested.c | 147 +++++++++++++++++++++++++++-
> > 4 files changed, 177 insertions(+), 8 deletions(-)
> >
> > diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> > index 851f6171751c..a97bd461c1e1 100644
> > --- a/arch/arm64/include/asm/kvm_host.h
> > +++ b/arch/arm64/include/asm/kvm_host.h
> > @@ -217,6 +217,10 @@ struct kvm_s2_mmu {
> > */
> > bool nested_stage2_enabled;
> >
> > + /* canonical IPA to nested IPA range lookup */
> > + struct maple_tree nested_revmap_mt;
> > + bool nested_revmap_broken;
> > +
>
> Consider moving this boolean next to the other ones so that you don't
> create too many holes in the kvm_s2_mmu structure (use pahole to find out).
>
> But I have some misgivings about the way things are structured
> here. Only NV needs a revmap, yet this is present irrelevant of the
> nature of the VM and bloats the data structure a bit.
>
> My naive approach would have been to only keep a pointer to the
> revmap, and make that pointer NULL when the tree is "broken", and
> freed under RCU if the context isn't the correct one.
Can you explain what you mean by "if the context isn't the correct one"?
If this refers to when selecting a specific kvm_s2_mmu instance for
another context, then IIUC refcnt would already be 0 and there would be
no other user of the tree.
However I do see RCU can be used for parallel accesses to the tree from
parallel s2 faults, and when one fault's revmap store fails RCU defers
freeing the tree until the other fault finishes using it.
>
> This would have multiple benefits: no large-ish structure embedded in
> the s2_mmu structure, no extra boolean to indicate an error condition,
> memory reclaimed earlier.
Yes I see.
>
> > #ifdef CONFIG_PTDUMP_STAGE2_DEBUGFS
> > struct dentry *shadow_pt_debugfs_dentry;
> > #endif
> > diff --git a/arch/arm64/include/asm/kvm_nested.h b/arch/arm64/include/asm/kvm_nested.h
> > index 091544e6af44..f039220e87a6 100644
> > --- a/arch/arm64/include/asm/kvm_nested.h
> > +++ b/arch/arm64/include/asm/kvm_nested.h
> > @@ -76,6 +76,8 @@ extern void kvm_s2_mmu_iterate_by_vmid(struct kvm *kvm, u16 vmid,
> > const union tlbi_info *info,
> > void (*)(struct kvm_s2_mmu *,
> > const union tlbi_info *));
> > +extern void kvm_record_nested_revmap(gpa_t gpa, struct kvm_s2_mmu *mmu,
> > + gpa_t fault_gpa, size_t map_size);
> > extern void kvm_vcpu_load_hw_mmu(struct kvm_vcpu *vcpu);
> > extern void kvm_vcpu_put_hw_mmu(struct kvm_vcpu *vcpu);
> >
> > @@ -164,6 +166,8 @@ extern int kvm_s2_handle_perm_fault(struct kvm_vcpu *vcpu,
> > struct kvm_s2_trans *trans);
> > extern int kvm_inject_s2_fault(struct kvm_vcpu *vcpu, u64 esr_el2);
> > extern void kvm_nested_s2_wp(struct kvm *kvm);
> > +extern void kvm_unmap_gfn_range_nested(struct kvm *kvm, gpa_t gpa, size_t size,
> > + bool may_block);
> > extern void kvm_nested_s2_unmap(struct kvm *kvm, bool may_block);
> > extern void kvm_nested_s2_flush(struct kvm *kvm);
> >
> > diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
> > index d089c107d9b7..4c9b9cf6dc43 100644
> > --- a/arch/arm64/kvm/mmu.c
> > +++ b/arch/arm64/kvm/mmu.c
> > @@ -5,6 +5,7 @@
> > */
> >
> > #include <linux/acpi.h>
> > +#include <linux/maple_tree.h>
> > #include <linux/mman.h>
> > #include <linux/kvm_host.h>
> > #include <linux/io.h>
> > @@ -1099,6 +1100,7 @@ void kvm_free_stage2_pgd(struct kvm_s2_mmu *mmu)
> > {
> > struct kvm *kvm = kvm_s2_mmu_to_kvm(mmu);
> > struct kvm_pgtable *pgt = NULL;
> > + struct maple_tree *mt = &mmu->nested_revmap_mt;
> >
> > write_lock(&kvm->mmu_lock);
> > pgt = mmu->pgt;
> > @@ -1108,8 +1110,11 @@ void kvm_free_stage2_pgd(struct kvm_s2_mmu *mmu)
> > free_percpu(mmu->last_vcpu_ran);
> > }
> >
> > - if (kvm_is_nested_s2_mmu(kvm, mmu))
> > + if (kvm_is_nested_s2_mmu(kvm, mmu)) {
> > + if (!mtree_empty(mt))
> > + mtree_destroy(mt);
> > kvm_init_nested_s2_mmu(mmu);
> > + }
> >
> > write_unlock(&kvm->mmu_lock);
> >
> > @@ -1631,6 +1636,10 @@ static int gmem_abort(const struct kvm_s2_fault_desc *s2fd)
> > goto out_unlock;
> > }
> >
> > + if (s2fd->nested)
> > + kvm_record_nested_revmap(gfn << PAGE_SHIFT, pgt->mmu,
> > + s2fd->fault_ipa, PAGE_SIZE);
> > +
> > ret = KVM_PGT_FN(kvm_pgtable_stage2_map)(pgt, s2fd->fault_ipa, PAGE_SIZE,
> > __pfn_to_phys(pfn), prot,
> > memcache, flags);
> > @@ -2031,6 +2040,13 @@ static int kvm_s2_fault_map(const struct kvm_s2_fault_desc *s2fd,
> > ret = KVM_PGT_FN(kvm_pgtable_stage2_relax_perms)(pgt, gfn_to_gpa(gfn),
> > prot, flags);
> > } else {
> > + if (s2fd->nested) {
> > + phys_addr_t ipa = gfn_to_gpa(get_canonical_gfn(s2fd, s2vi));
> > +
> > + ipa &= ~(mapping_size - 1);
>
> I guess it'd be worth adding a helper for this instead of duplicating
> the existing code.
Ack.
>
> > + kvm_record_nested_revmap(ipa, pgt->mmu, gfn_to_gpa(gfn),
> > + mapping_size);
>
> This worries me a bit, see below.
>
> > + }
> > ret = KVM_PGT_FN(kvm_pgtable_stage2_map)(pgt, gfn_to_gpa(gfn), mapping_size,
> > __pfn_to_phys(pfn), prot,
> > memcache, flags);
> > @@ -2388,14 +2404,16 @@ int kvm_handle_guest_abort(struct kvm_vcpu *vcpu)
> >
> > bool kvm_unmap_gfn_range(struct kvm *kvm, struct kvm_gfn_range *range)
> > {
> > + gpa_t gpa = range->start << PAGE_SHIFT;
> > + size_t size = (range->end - range->start) << PAGE_SHIFT;
> > + bool may_block = range->may_block;
> > +
> > if (!kvm->arch.mmu.pgt || kvm_vm_is_protected(kvm))
> > return false;
> >
> > - __unmap_stage2_range(&kvm->arch.mmu, range->start << PAGE_SHIFT,
> > - (range->end - range->start) << PAGE_SHIFT,
> > - range->may_block);
> > + __unmap_stage2_range(&kvm->arch.mmu, gpa, size, may_block);
> > + kvm_unmap_gfn_range_nested(kvm, gpa, size, may_block);
> >
> > - kvm_nested_s2_unmap(kvm, range->may_block);
> > return false;
> > }
> >
> > @@ -2673,7 +2691,7 @@ void kvm_arch_flush_shadow_memslot(struct kvm *kvm,
> >
> > write_lock(&kvm->mmu_lock);
> > kvm_stage2_unmap_range(&kvm->arch.mmu, gpa, size, true);
> > - kvm_nested_s2_unmap(kvm, true);
> > + kvm_unmap_gfn_range_nested(kvm, gpa, size, true);
> > write_unlock(&kvm->mmu_lock);
> > }
> >
> > diff --git a/arch/arm64/kvm/nested.c b/arch/arm64/kvm/nested.c
> > index 883b6c1008fb..c9ebe969b453 100644
> > --- a/arch/arm64/kvm/nested.c
> > +++ b/arch/arm64/kvm/nested.c
> > @@ -7,6 +7,7 @@
> > #include <linux/bitfield.h>
> > #include <linux/kvm.h>
> > #include <linux/kvm_host.h>
> > +#include <linux/maple_tree.h>
> >
> > #include <asm/fixmap.h>
> > #include <asm/kvm_arm.h>
> > @@ -43,6 +44,19 @@ struct vncr_tlb {
> > */
> > #define S2_MMU_PER_VCPU 2
> >
> > +/*
> > + * Per shadow S2 reverse map (IPA -> nested IPA range) maple tree payload
> > + * layout:
> > + *
> > + * bit 63: valid, 1 for non-polluted entries, prevents the case where the
> > + * nested IPA is 0 and turns the whole value to 0
> > + * bits 55-12: nested IPA bits 55-12
> > + * bit 0: polluted, 1 for polluted, 0 for not
> > + */
> > +#define VALID_ENTRY BIT(63)
> > +#define NESTED_IPA_MASK GENMASK_ULL(55, 12)
> > +#define UNKNOWN_IPA BIT(0)
> > +
>
> This only works because you are using the "advanced" API, right?
> Otherwise, you'd be losing the high bit. It'd be good to add a comment
> so that people keep that in mind.
Sorry, I can't find any relationship between the advanced API and the
top most bit of the maple tree value, what am I missing?
>
> > void kvm_init_nested(struct kvm *kvm)
> > {
> > kvm->arch.nested_mmus = NULL;
> > @@ -769,12 +783,57 @@ static struct kvm_s2_mmu *get_s2_mmu_nested(struct kvm_vcpu *vcpu)
> > return s2_mmu;
> > }
> >
> > +void kvm_record_nested_revmap(gpa_t ipa, struct kvm_s2_mmu *mmu,
> > + gpa_t fault_ipa, size_t map_size)
> > +{
> > + struct maple_tree *mt = &mmu->nested_revmap_mt;
> > + gpa_t start = ipa;
> > + gpa_t end = ipa + map_size - 1;
> > + u64 entry, new_entry = 0;
> > + MA_STATE(mas, mt, start, end);
> > +
> > + if (mmu->nested_revmap_broken)
> > + return;
> > +
> > + mtree_lock(mt);
> > + entry = (u64)mas_find_range(&mas, end);
> > +
> > + if (entry) {
> > + /* maybe just a perm update... */
> > + if (!(entry & UNKNOWN_IPA) && mas.index == start &&
> > + mas.last == end &&
> > + fault_ipa == (entry & NESTED_IPA_MASK))
> > + goto unlock;
> > + /*
> > + * Create a "polluted" range that spans all the overlapping
> > + * ranges and store it.
> > + */
> > + while (entry && mas.index <= end) {
> > + start = min(mas.index, start);
> > + end = max(mas.last, end);
> > + entry = (u64)mas_find_range(&mas, end);
> > + }
> > + new_entry |= UNKNOWN_IPA;
> > + } else {
> > + new_entry |= fault_ipa;
> > + new_entry |= VALID_ENTRY;
> > + }
> > +
> > + mas_set_range(&mas, start, end);
> > + if (mas_store_gfp(&mas, (void *)new_entry, GFP_NOWAIT | __GFP_ACCOUNT))
> > + mmu->nested_revmap_broken = true;
>
> Can we try and minimise the risk of allocation failure here?
>
> user_mem_abort() tries very hard to pre-allocate pages for page
> tables by maintaining an memcache. Can we have a similar approach for
> the revmap?
Unfortunately, as I understand the maple tree can only pre-allocate for
a store when the range and the entry to be stored is given, but in this
case we must inspect the tree to get that information after we hold the
mmu and maple tree locks. It is possible to do a two pass approach:
pre-allocate -> take MMU lock -> take maple tree lock -> revalidate what
we pre-allocated is still usable (nobody changed the tree before we took
the maple tree lock)
But I am not fond of this extra complexity..
>
> > +unlock:
> > + mtree_unlock(mt);
> > +}
> > +
> > void kvm_init_nested_s2_mmu(struct kvm_s2_mmu *mmu)
> > {
> > /* CnP being set denotes an invalid entry */
> > mmu->tlb_vttbr = VTTBR_CNP_BIT;
> > mmu->nested_stage2_enabled = false;
> > atomic_set(&mmu->refcnt, 0);
> > + mt_init(&mmu->nested_revmap_mt);
> > + mmu->nested_revmap_broken = false;
> > }
> >
> > void kvm_vcpu_load_hw_mmu(struct kvm_vcpu *vcpu)
> > @@ -1150,6 +1209,90 @@ void kvm_nested_s2_wp(struct kvm *kvm)
> > kvm_invalidate_vncr_ipa(kvm, 0, BIT(kvm->arch.mmu.pgt->ia_bits));
> > }
> >
> > +static void reset_revmap_and_unmap(struct kvm_s2_mmu *mmu, bool may_block)
> > +{
> > + mtree_destroy(&mmu->nested_revmap_mt);
> > + kvm_stage2_unmap_range(mmu, 0, kvm_phys_size(mmu), may_block);
> > + mmu->nested_revmap_broken = false;
> > +}
> > +
> > +static void unmap_mmu_ipa_range(struct kvm_s2_mmu *mmu, gpa_t gpa,
> > + size_t unmap_size, bool may_block)
> > +{
> > + struct maple_tree *mt = &mmu->nested_revmap_mt;
> > + gpa_t start = gpa;
> > + gpa_t end = gpa + unmap_size - 1;
> > + u64 entry;
> > + size_t entry_size;
> > + bool unlock, fallback;
> > + MA_STATE(mas, mt, gpa, end);
> > +
> > + if (mmu->nested_revmap_broken) {
> > + unlock = false;
> > + fallback = true;
> > + goto fin;
> > + }
>
> Using booleans to affect the control flow reads really badly. I'd
> expect this to simply be:
>
> if (...) {
> reset_revmap_and_unmap(mmu, may_block);
> return;
> }
>
> > +
> > + mtree_lock(mt);
> > + entry = (u64)mas_find_range(&mas, end);
> > +
> > + while (entry && mas.index <= end) {
> > + start = mas.last + 1;
> > + entry_size = mas.last - mas.index + 1;
> > + /*
> > + * Give up and invalidate this s2 mmu if the unmap range
> > + * touches any polluted range.
> > + */
> > + if (entry & UNKNOWN_IPA) {
> > + unlock = true;
> > + fallback = true;
> > + goto fin;
> > + }
>
> and this to be:
>
> if (entry & UNKNOWN_IPA) {
> mtree_unlock(mt);
> reset_revmap_and_unmap(mmu, may_block);
> return;
> }
>
> > +
> > + /*
> > + * Ignore result, it is okay if a reverse mapping erase
> > + * fails.
> > + */
> > + mas_store_gfp(&mas, NULL, GFP_NOWAIT | __GFP_ACCOUNT);
> > +
> > + mtree_unlock(mt);
> > + kvm_stage2_unmap_range(mmu, entry & NESTED_IPA_MASK, entry_size,
> > + may_block);
> > + mtree_lock(mt);
> > + /*
> > + * Other maple tree operations during preemption could render
> > + * this ma_state invalid, so reset it.
> > + */
> > + mas_set_range(&mas, start, end);
> > + entry = (u64)mas_find_range(&mas, end);
> > + }
> > + unlock = true;
> > + fallback = false;
> > +
> > +fin:
> > + if (unlock)
> > + mtree_unlock(mt);
> > + if (fallback)
> > + reset_revmap_and_unmap(mmu, may_block);
>
> and this can eventually be greatly simplified.
Sure, I agree.
>
> > +}
> > +
> > +void kvm_unmap_gfn_range_nested(struct kvm *kvm, gpa_t gpa, size_t size,
> > + bool may_block)
> > +{
> > + int i;
> > +
> > + if (!kvm->arch.nested_mmus_size)
> > + return;
> > +
> > + /* TODO: accelerate this using mt of canonical s2 mmu */
> > + for (i = 0; i < kvm->arch.nested_mmus_size; i++) {
> > + struct kvm_s2_mmu *mmu = &kvm->arch.nested_mmus[i];
> > +
> > + if (kvm_s2_mmu_valid(mmu))
> > + unmap_mmu_ipa_range(mmu, gpa, size, may_block);
> > + }
> > +}
> > +
> > void kvm_nested_s2_unmap(struct kvm *kvm, bool may_block)
> > {
> > int i;
> > @@ -1163,7 +1306,7 @@ void kvm_nested_s2_unmap(struct kvm *kvm, bool may_block)
> > struct kvm_s2_mmu *mmu = &kvm->arch.nested_mmus[i];
> >
> > if (kvm_s2_mmu_valid(mmu))
> > - kvm_stage2_unmap_range(mmu, 0, kvm_phys_size(mmu), may_block);
> > + reset_revmap_and_unmap(mmu, may_block);
> > }
> >
> > kvm_invalidate_vncr_ipa(kvm, 0, BIT(kvm->arch.mmu.pgt->ia_bits));
> > @@ -1848,7 +1991,7 @@ void check_nested_vcpu_requests(struct kvm_vcpu *vcpu)
> >
> > write_lock(&vcpu->kvm->mmu_lock);
> > if (mmu->pending_unmap) {
> > - kvm_stage2_unmap_range(mmu, 0, kvm_phys_size(mmu), true);
> > + reset_revmap_and_unmap(mmu, true);
> > mmu->pending_unmap = false;
> > }
> > write_unlock(&vcpu->kvm->mmu_lock);
>
> My other concern here is related to TLB invalidation. As the guest
> performs TLB invalidations that remove entries from the shadow S2,
> there is no way to update the revmap to account for this.
>
> This obviously means that the revmap becomes more and more inaccurate
> over time, and that is likely to accumulate conflicting entries.
>
> What is the plan to improve the situation on this front?
Right now I think using a direct map which goes from nested IPA to
canonical IPA could work while not generating too much complexity, if we
keep the reverse map and direct map in lockstep (direct map keeping the
same mappings as the reverse map but just in reverse).
I'll try to do that and include it in the next iteration.
Thanks,
Wei-Lin Chang
>
> Thanks,
>
> M.
>
> --
> Without deviation from the norm, progress is not possible.
^ permalink raw reply
* Re: [PATCH v6 2/3] dt-bindings: mfd: aspeed,ast2x00-scu: Describe AST2700 SCU0
From: Rob Herring (Arm) @ 2026-04-15 22:31 UTC (permalink / raw)
To: Billy Tsai
Cc: linux-arm-kernel, Andrew Jeffery, Bartosz Golaszewski, Ryan Chen,
Lee Jones, Andrew Jeffery, Linus Walleij, linux-kernel,
Conor Dooley, devicetree, linux-aspeed, Krzysztof Kozlowski,
linux-gpio, Joel Stanley, linux-clk, openbmc
In-Reply-To: <20260414-upstream_pinctrl-v6-2-709f2127da33@aspeedtech.com>
On Tue, 14 Apr 2026 17:39:00 +0800, Billy Tsai wrote:
> AST2700 consists of two interconnected SoC instances, each with its own
> System Control Unit (SCU). The SCU0 provides pin control, interrupt
> controllers, clocks, resets, and address-space mappings for the
> Secondary and Tertiary Service Processors (SSP and TSP).
>
> Describe the SSP/TSP address mappings using the standard
> memory-region and memory-region-names properties.
>
> Disallow legacy child nodes that are not present on AST2700, including
> p2a-control and smp-memram. The latter is unnecessary as software can
> access the scratch registers via the SCU syscon.
>
> Also allow the AST2700 SoC0 pin controller to be described as a child
> node of the SCU0, and add an example illustrating the SCU0 layout,
> including reserved-memory, interrupt controllers, and pinctrl.
>
> Signed-off-by: Billy Tsai <billy_tsai@aspeedtech.com>
> ---
> .../bindings/mfd/aspeed,ast2x00-scu.yaml | 112 +++++++++++++++++++++
> 1 file changed, 112 insertions(+)
>
My bot found errors running 'make dt_binding_check' on your patch:
yamllint warnings/errors:
dtschema/dtc warnings/errors:
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/mfd/aspeed,ast2x00-scu.yaml: allOf:1: 'then' is a dependency of 'if'
hint: Keywords must be a subset of known json-schema keywords
from schema $id: http://devicetree.org/meta-schemas/keywords.yaml
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/mfd/aspeed,ast2x00-scu.yaml: allOf:1: 'then' is a dependency of 'else'
hint: Keywords must be a subset of known json-schema keywords
from schema $id: http://devicetree.org/meta-schemas/keywords.yaml
doc reference errors (make refcheckdocs):
See https://patchwork.kernel.org/project/devicetree/patch/20260414-upstream_pinctrl-v6-2-709f2127da33@aspeedtech.com
The base for the series is generally the latest rc1. A different dependency
should be noted in *this* patch.
If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:
pip3 install dtschema --upgrade
Please check and re-submit after running the above command yourself. Note
that DT_SCHEMA_FILES can be set to your schema file to speed up checking
your schema. However, it must be unset to test all examples with your schema.
^ permalink raw reply
* Re: [PATCH v6 1/3] dt-bindings: pinctrl: Add aspeed,ast2700-soc0-pinctrl
From: Rob Herring (Arm) @ 2026-04-15 22:31 UTC (permalink / raw)
To: Billy Tsai
Cc: Linus Walleij, Ryan Chen, Joel Stanley, Conor Dooley, openbmc,
linux-aspeed, linux-gpio, linux-clk, Krzysztof Kozlowski,
devicetree, linux-arm-kernel, Andrew Jeffery, Lee Jones,
linux-kernel, Bartosz Golaszewski, Andrew Jeffery
In-Reply-To: <20260414-upstream_pinctrl-v6-1-709f2127da33@aspeedtech.com>
On Tue, 14 Apr 2026 17:38:59 +0800, Billy Tsai wrote:
> Add a device tree binding for the pin controller found in the
> ASPEED AST2700 SoC0.
>
> The controller manages various peripheral functions such as eMMC, USB,
> VGA DDC, JTAG, and PCIe root complex signals.
>
> Describe the AST2700 SoC0 pin controller using standard pin multiplexing
> and configuration properties.
>
> Signed-off-by: Billy Tsai <billy_tsai@aspeedtech.com>
> ---
> .../pinctrl/aspeed,ast2700-soc0-pinctrl.yaml | 170 +++++++++++++++++++++
> 1 file changed, 170 insertions(+)
>
My bot found errors running 'make dt_binding_check' on your patch:
yamllint warnings/errors:
dtschema/dtc warnings/errors:
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/pinctrl/aspeed,ast2700-soc0-pinctrl.yaml: patternProperties:-state$:allOf:2: 'then' is a dependency of 'if'
hint: Keywords must be a subset of known json-schema keywords
from schema $id: http://devicetree.org/meta-schemas/keywords.yaml
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/pinctrl/aspeed,ast2700-soc0-pinctrl.yaml: patternProperties:-state$:allOf:2: 'then' is a dependency of 'else'
hint: Keywords must be a subset of known json-schema keywords
from schema $id: http://devicetree.org/meta-schemas/keywords.yaml
doc reference errors (make refcheckdocs):
See https://patchwork.kernel.org/project/devicetree/patch/20260414-upstream_pinctrl-v6-1-709f2127da33@aspeedtech.com
The base for the series is generally the latest rc1. A different dependency
should be noted in *this* patch.
If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:
pip3 install dtschema --upgrade
Please check and re-submit after running the above command yourself. Note
that DT_SCHEMA_FILES can be set to your schema file to speed up checking
your schema. However, it must be unset to test all examples with your schema.
^ 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