* [PATCH 1/2] dt-bindings: soc: xilinx: Add MYIR MYS-7Z020-V2 board
From: Liu Yu @ 2026-06-19 10:22 UTC (permalink / raw)
To: Michal Simek
Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, devicetree,
linux-arm-kernel, Liu Yu
In-Reply-To: <20260619102214.223121-1-f78fk@live.com>
Add compatible string for the MYIR MYS-7Z020-V2 board, based on
the Xilinx Zynq-7000 XC7Z020 SoC.
Signed-off-by: Liu Yu <f78fk@live.com>
---
Documentation/devicetree/bindings/soc/xilinx/xilinx.yaml | 1 +
1 file changed, 1 insertion(+)
diff --git a/Documentation/devicetree/bindings/soc/xilinx/xilinx.yaml b/Documentation/devicetree/bindings/soc/xilinx/xilinx.yaml
index c9f99e0df2b3..72a84b628da3 100644
--- a/Documentation/devicetree/bindings/soc/xilinx/xilinx.yaml
+++ b/Documentation/devicetree/bindings/soc/xilinx/xilinx.yaml
@@ -23,6 +23,7 @@ properties:
- digilent,zynq-zybo
- digilent,zynq-zybo-z7
- ebang,ebaz4205
+ - myir,mys-7z020-v2
- myir,zynq-zturn-v5
- myir,zynq-zturn
- xlnx,zynq-cc108
--
2.43.0
^ permalink raw reply related
* [PATCH net v2] net: airoha: fix BQL underflow and UAF in shared QDMA TX ring
From: Lorenzo Bianconi @ 2026-06-19 10:30 UTC (permalink / raw)
To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Lorenzo Bianconi
Cc: Wayen Yan, linux-arm-kernel, linux-mediatek, netdev
When multiple netdevs share a QDMA TX ring and one device is stopped,
netdev_tx_reset_subqueue() zeroes that device's BQL counters while its
pending skbs remain in the shared HW TX ring. When NAPI later completes
those skbs via netdev_tx_completed_queue(), the already-zeroed
dql->num_queued counter underflows.
Moreover, in the airoha_remove() path, netdevs are unregistered
sequentially while skbs from previously unregistered netdevs may still
reference freed net_device memory via skb->dev, causing a use-after-free
during BQL accounting.
Fix both issues:
- Remove netdev_tx_reset_subqueue() from airoha_dev_stop() so pending
skbs are completed naturally by NAPI with proper BQL accounting.
- Introduce airoha_qdma_tx_flush() to stop NAPI and flush BQL counters
for all pending skbs while skb->dev references are still valid.
- Guard airoha_dev_xmit() with DEV_STATE_FLUSH to drop packets during
teardown.
- Move DMA engine start into probe and stop into airoha_qdma_cleanup().
Fixes: a9c2ca61fec7 ("net: airoha: Support multiple net_devices for a single FE GDM port")
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
Changes in v2:
- Introduce airoha_qdma_tx_flush() to account BQL in airoha_remove() or
airoha_probe() error path.
- Fix possible NULL pointer dereference in airoha_qdma_cleanup().
- Introduce DEV_STATE_FLUSH().
- Move back airoha_hw_cleanup().
- Set proper Fixes tag.
- Link to v1: https://lore.kernel.org/r/20260618-airoha-bql-fixes-v1-1-ffd2c2089518@kernel.org
---
drivers/net/ethernet/airoha/airoha_eth.c | 87 +++++++++++++++++++++++---------
drivers/net/ethernet/airoha/airoha_eth.h | 1 +
2 files changed, 63 insertions(+), 25 deletions(-)
diff --git a/drivers/net/ethernet/airoha/airoha_eth.c b/drivers/net/ethernet/airoha/airoha_eth.c
index 64dde6464f3f..e81cd806b57b 100644
--- a/drivers/net/ethernet/airoha/airoha_eth.c
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
@@ -1004,6 +1004,7 @@ static int airoha_qdma_tx_napi_poll(struct napi_struct *napi, int budget)
e = &q->entry[index];
skb = e->skb;
+ e->skb = NULL;
dma_unmap_single(eth->dev, e->dma_addr, e->dma_len,
DMA_TO_DEVICE);
@@ -1523,10 +1524,26 @@ static int airoha_qdma_init(struct platform_device *pdev,
return airoha_qdma_hw_init(qdma);
}
-static void airoha_qdma_cleanup(struct airoha_qdma *qdma)
+static void airoha_qdma_cleanup(struct airoha_eth *eth,
+ struct airoha_qdma *qdma)
{
int i;
+ if (test_bit(DEV_STATE_INITIALIZED, ð->state)) {
+ u32 status;
+
+ airoha_qdma_clear(qdma, REG_QDMA_GLOBAL_CFG,
+ GLOBAL_CFG_TX_DMA_EN_MASK |
+ GLOBAL_CFG_RX_DMA_EN_MASK);
+ if (read_poll_timeout(airoha_qdma_rr, status,
+ !(status & (GLOBAL_CFG_TX_DMA_BUSY_MASK |
+ GLOBAL_CFG_RX_DMA_BUSY_MASK)),
+ USEC_PER_MSEC, 50 * USEC_PER_MSEC, true,
+ qdma, REG_QDMA_GLOBAL_CFG))
+ dev_warn(eth->dev,
+ "QDMA DMA engine busy timeout\n");
+ }
+
for (i = 0; i < ARRAY_SIZE(qdma->q_rx); i++) {
if (!qdma->q_rx[i].ndesc)
continue;
@@ -1593,7 +1610,7 @@ static int airoha_hw_init(struct platform_device *pdev,
return 0;
error:
for (i = 0; i < ARRAY_SIZE(eth->qdma); i++)
- airoha_qdma_cleanup(ð->qdma[i]);
+ airoha_qdma_cleanup(eth, ð->qdma[i]);
return err;
}
@@ -1603,7 +1620,7 @@ static void airoha_hw_cleanup(struct airoha_eth *eth)
int i;
for (i = 0; i < ARRAY_SIZE(eth->qdma); i++)
- airoha_qdma_cleanup(ð->qdma[i]);
+ airoha_qdma_cleanup(eth, ð->qdma[i]);
airoha_ppe_deinit(eth);
}
@@ -1637,6 +1654,35 @@ static void airoha_qdma_stop_napi(struct airoha_qdma *qdma)
}
}
+static void airoha_qdma_tx_flush(struct airoha_qdma *qdma)
+{
+ int i;
+
+ airoha_qdma_stop_napi(qdma);
+
+ for (i = 0; i < ARRAY_SIZE(qdma->q_tx); i++) {
+ struct airoha_queue *q = &qdma->q_tx[i];
+ int j;
+
+ if (!q->ndesc)
+ continue;
+
+ spin_lock_bh(&q->lock);
+ for (j = 0; j < q->ndesc; j++) {
+ struct airoha_queue_entry *e = &q->entry[j];
+ struct sk_buff *skb = e->skb;
+ struct netdev_queue *txq;
+
+ if (!skb)
+ continue;
+
+ txq = skb_get_tx_queue(skb->dev, skb);
+ netdev_tx_completed_queue(txq, 1, skb->len);
+ }
+ spin_unlock_bh(&q->lock);
+ }
+}
+
static void airoha_dev_get_hw_stats(struct airoha_gdm_dev *dev)
{
struct airoha_gdm_port *port = dev->port;
@@ -1837,9 +1883,6 @@ static int airoha_dev_open(struct net_device *netdev)
}
port->users++;
- airoha_qdma_set(qdma, REG_QDMA_GLOBAL_CFG,
- GLOBAL_CFG_TX_DMA_EN_MASK |
- GLOBAL_CFG_RX_DMA_EN_MASK);
qdma->users++;
if (!airoha_is_lan_gdm_dev(dev) &&
@@ -1880,12 +1923,9 @@ static int airoha_dev_stop(struct net_device *netdev)
struct airoha_gdm_dev *dev = netdev_priv(netdev);
struct airoha_gdm_port *port = dev->port;
struct airoha_qdma *qdma = dev->qdma;
- int i;
netif_tx_disable(netdev);
airoha_set_vip_for_gdm_port(dev, false);
- for (i = 0; i < netdev->num_tx_queues; i++)
- netdev_tx_reset_subqueue(netdev, i);
if (--port->users)
airoha_set_port_mtu(dev->eth, port);
@@ -1893,19 +1933,7 @@ static int airoha_dev_stop(struct net_device *netdev)
airoha_set_gdm_port_fwd_cfg(qdma->eth,
REG_GDM_FWD_CFG(port->id),
FE_PSE_PORT_DROP);
-
- if (!--qdma->users) {
- airoha_qdma_clear(qdma, REG_QDMA_GLOBAL_CFG,
- GLOBAL_CFG_TX_DMA_EN_MASK |
- GLOBAL_CFG_RX_DMA_EN_MASK);
-
- for (i = 0; i < ARRAY_SIZE(qdma->q_tx); i++) {
- if (!qdma->q_tx[i].ndesc)
- continue;
-
- airoha_qdma_cleanup_tx_queue(&qdma->q_tx[i]);
- }
- }
+ qdma->users--;
return 0;
}
@@ -2191,6 +2219,9 @@ static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb,
u16 index;
u8 fport;
+ if (test_bit(DEV_STATE_FLUSH, &dev->eth->state))
+ goto error;
+
qid = airoha_qdma_get_txq(qdma, skb_get_queue_mapping(skb));
tag = airoha_get_dsa_tag(skb, netdev);
@@ -3413,8 +3444,12 @@ static int airoha_probe(struct platform_device *pdev)
if (err)
goto error_netdev_free;
- for (i = 0; i < ARRAY_SIZE(eth->qdma); i++)
+ for (i = 0; i < ARRAY_SIZE(eth->qdma); i++) {
airoha_qdma_start_napi(ð->qdma[i]);
+ airoha_qdma_set(ð->qdma[i], REG_QDMA_GLOBAL_CFG,
+ GLOBAL_CFG_TX_DMA_EN_MASK |
+ GLOBAL_CFG_RX_DMA_EN_MASK);
+ }
for_each_child_of_node(pdev->dev.of_node, np) {
if (!of_device_is_compatible(np, "airoha,eth-mac"))
@@ -3437,8 +3472,9 @@ static int airoha_probe(struct platform_device *pdev)
return 0;
error_napi_stop:
+ set_bit(DEV_STATE_FLUSH, ð->state);
for (i = 0; i < ARRAY_SIZE(eth->qdma); i++)
- airoha_qdma_stop_napi(ð->qdma[i]);
+ airoha_qdma_tx_flush(ð->qdma[i]);
for (i = 0; i < ARRAY_SIZE(eth->ports); i++) {
struct airoha_gdm_port *port = eth->ports[i];
@@ -3474,8 +3510,9 @@ static void airoha_remove(struct platform_device *pdev)
struct airoha_eth *eth = platform_get_drvdata(pdev);
int i;
+ set_bit(DEV_STATE_FLUSH, ð->state);
for (i = 0; i < ARRAY_SIZE(eth->qdma); i++)
- airoha_qdma_stop_napi(ð->qdma[i]);
+ airoha_qdma_tx_flush(ð->qdma[i]);
for (i = 0; i < ARRAY_SIZE(eth->ports); i++) {
struct airoha_gdm_port *port = eth->ports[i];
diff --git a/drivers/net/ethernet/airoha/airoha_eth.h b/drivers/net/ethernet/airoha/airoha_eth.h
index 41d2e7a1f9fb..f6dce5e74e02 100644
--- a/drivers/net/ethernet/airoha/airoha_eth.h
+++ b/drivers/net/ethernet/airoha/airoha_eth.h
@@ -92,6 +92,7 @@ enum {
enum {
DEV_STATE_INITIALIZED,
DEV_STATE_REGISTERED,
+ DEV_STATE_FLUSH,
};
enum {
---
base-commit: a887f2c7da66a805a55fd8706d45faec85f646db
change-id: 20260618-airoha-bql-fixes-f57b2d108573
Best regards,
--
Lorenzo Bianconi <lorenzo@kernel.org>
^ permalink raw reply related
* Re: [PATCH v2] arm64: errata: Handle Apple WFI State Loss
From: Mark Rutland @ 2026-06-19 10:38 UTC (permalink / raw)
To: Yureka Lilian
Cc: Will Deacon, Catalin Marinas, linux-arm-kernel, linux-kernel,
asahi, Sasha Finkelstein
In-Reply-To: <e105c7b2-a5eb-4b5d-955f-685058143e9d@cyberchaos.dev>
On Wed, Jun 17, 2026 at 09:23:03PM +0200, Yureka Lilian wrote:
> On 6/15/26 17:02, Will Deacon wrote:
> > On Mon, Jun 15, 2026 at 02:21:36PM +0200, Yureka Lilian wrote:
> > > Apple Silicon CPUs can lose register state in WFI, leading to crashes
> > > in the idle loop early in the boot process.
> > > This applies to any previous Apple Silicon CPUs too, but is worked
> > > around by configuring the WFI mode in SYS_IMP_APL_CYC_OVRD sysreg
> > > during m1n1's chickens setup.
> > > This workaround no longer exists since M4.
Are we *certain* that there's no equivalent control elsewhere? i.e. this
hasn't just moved?
> > > Add a workaround capability for replacing wfi and wfit with nop, and
> > > an erratum to enable it on the affected CPUs if the workaround using the
> > > sysreg is not already applied. Leave the decision whether the sysreg
> > > workaround can be used up to the earlier parts of the boot chain which
> > > already configure the Apple Silicon chicken bits.
> > >
> > > This alternative has to be applied in early boot, since otherwise some
> > > cores might enter the idle loop before apply_alternatives_all() is run.
> > >
> > > Reviewed-by: Sasha Finkelstein <k@chaosmail.tech>
> > > Signed-off-by: Yureka Lilian <yureka@cyberchaos.dev>
> > > ---
> > > Changes since v1:
> > > Restricted the erratum to EL2 only, since in EL1 we'd expect the
> > > hypervisor to trap WFI and handle the erratum.
The KVM portion doesn't seem to be implemented in this patch, so we
can't rely on that as-is.
[...]
> > > #define wfe() asm volatile("wfe" : : : "memory")
> > > #define wfet(val) asm volatile("msr s0_3_c1_c0_0, %0" \
> > > : : "r" (val) : "memory")
> > > -#define wfi() asm volatile("wfi" : : : "memory")
> > > -#define wfit(val) asm volatile("msr s0_3_c1_c0_1, %0" \
> > > - : : "r" (val) : "memory")
> > > +#define wfi() \
> > > + do { \
> > > + asm volatile( \
> > > + ALTERNATIVE("wfi", \
> > > + "nop", \
> > > + ARM64_WORKAROUND_WFI_STATE) \
> > > + : : : "memory"); \
> > > + } while (0)
> > > +#define wfit(val) \
> > > + do { \
> > > + asm volatile( \
> > > + ALTERNATIVE("msr s0_3_c1_c0_1, %0", \
> > > + "nop", \
> > > + ARM64_WORKAROUND_WFI_STATE) \
> > > + : : "r" (val) : "memory"); \
> > > + } while (0)
> > How can you guarantee that we don't run one of these prior to patching?
>
> We can't, but there are a few points to our advantage, namely the boot cpu
> isn't actually affected by this (when the CYC_OVRD bits are not configured
> or not supported), and first round of patching happens quite early before
> the other cpus are started.
I think you're saying that:
* On the boot CPU, WFI *never* loses register state.
* On other CPUs, WFI *might* lose register state (and this cannot be
inhibited).
Is that understanding correct, or are there other conditions where a WFI
on the boot CPU can lose register state?
IIRC kdump doesn't ensure the new kernel is started on the boot CPU, so
I think that would be broken. I guess you can't kexec generally due to a
lack of offlining of secondary CPUs.
Mark.
^ permalink raw reply
* Re: [PATCH 15/78] ASoC: codecs: cs42l43: Use guard() for mutex locks
From: Charles Keepax @ 2026-06-19 10:39 UTC (permalink / raw)
To: David Laight
Cc: Bui Duc Phuc, Mark Brown, Liam Girdwood, Jaroslav Kysela,
Takashi Iwai, Cheng-Yi Chiang, Tzung-Bi Shih, Guenter Roeck,
Benson Leung, David Rhodes, Richard Fitzgerald, povik+lin,
Support Opensource, Nick Li, Herve Codina, Srinivas Kandagatla,
Matthias Brugger, AngeloGioacchino Del Regno, Shenghao Ding,
Kevin Lu, Baojun Xu, Sen Wang, Oder Chiou, Lars-Peter Clausen,
nuno.sa, Steven Eckhoff, patches, chrome-platform, asahi,
linux-arm-msm, linux-sound, linux-kernel, linux-arm-kernel,
linux-mediatek
In-Reply-To: <20260619101346.2ec49087@pumpkin>
On Fri, Jun 19, 2026 at 10:13:46AM +0100, David Laight wrote:
> On Fri, 19 Jun 2026 15:20:37 +0700
> Bui Duc Phuc <phucduc.bui@gmail.com> wrote:
> > > > I believe you have to use scoped_guard here, as there is a return
> > > > from the function above, if memory serves it attempts to release
> > > > the mutex on that path despite it being above the guard.
> > >
> > > Indeed.
> > > I believe clang will complain.
> > > That makes these mechanical conversions of existing code dangerous churn.
> > >
> > > While using guard() (etc) can make it easier to ensure the lock is released
> > > when functions have multiple error exits, I'm not convinced it makes the
> > > code any easier to read (other people may disagree).
> >
> > I built the code with both GCC and Clang and didn't see any warnings.
> >
> > My understanding was that the early return exits the function before
> > the guard is instantiated, so it should not affect the guard's cleanup
> > handling.
>
> When a variable is defined (and initialised) part way down a block the
> compiler moves the definition to the top of the block but doesn't initialise
> it at all, the first assignment happens where the code contains the
> definition.
>
> However the destructor is always called at the end of the block.
> So if you return from a function before the definition the destructor
> is called with an uninitialised argument.
My understanding was exactly as your David, but it seems that isn't
the whole story and indeed I had to fix a bug in our SDCA code
that hit this. However testing this out, results in some things I
find very hard to explain.
It seems as far as I have managed to test, the code below works
fine as Phuc suggests. It does not appear to run the mutex_unlock
on the error path.
int function()
{
if (error)
return;
guard(mutex)(&mutex);
stuff();
return;
}
The situation I hit this in before that doesn't work was actually
this:
int function()
{
if (error)
goto error_label;
guard(mutex)(&mutex);
stuff();
error_label;
return;
}
Which in this case it does run the mutex_unlock and NULL pointer.
Will try to find sometime to look at the generated assembly, but
this basically totally blows my mind. Very unclear as to if this
is supposed to work this way or just does by pure luck.
Thanks,
Charles
^ permalink raw reply
* Re: [RFC PATCH 4/6] arm64: mm: add helper to fill execmem with trapping instructions
From: Ryan Roberts @ 2026-06-19 10:54 UTC (permalink / raw)
To: Adrian Barnaś, linux-arm-kernel
Cc: linux-mm, Catalin Marinas, Will Deacon, David Hildenbrand,
Mike Rapoport (Microsoft), Ard Biesheuvel, Christoph Lameter,
Yang Shi, Brendan Jackman
In-Reply-To: <20260611130144.1385343-5-abarnas@google.com>
On 11/06/2026 14:01, Adrian Barnaś wrote:
> Implement the architecture-specific execmem_fill_trapping_insns() helper
> to poison executable memory regions.
>
> When CONFIG_ARCH_HAS_EXECMEM_ROX is enabled, the execmem subsystem
> requires a way to fill unused or freed executable memory with
> architecture-specific trapping instructions. This implementation fills
> the specified region with AARCH64_BREAK_FAULT instructions and flushes
> the icache to ensure the traps are immediately visible to execution.
>
> Signed-off-by: Adrian Barnaś <abarnas@google.com>
> ---
> arch/arm64/mm/init.c | 14 ++++++++++++++
> 1 file changed, 14 insertions(+)
>
> diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
> index c673a9a839dd..71aa745e0bef 100644
> --- a/arch/arm64/mm/init.c
> +++ b/arch/arm64/mm/init.c
> @@ -408,6 +408,20 @@ void dump_mem_limit(void)
> }
>
> #ifdef CONFIG_EXECMEM
> +
> +#ifdef CONFIG_ARCH_HAS_EXECMEM_ROX
> +void execmem_fill_trapping_insns(void *ptr, size_t size)
> +{
> + int nr_inst = size / AARCH64_INSN_SIZE;
The x86 instruction is 1 byte, so it can exactly fill any provided buffer. For
arm64, the instruction is 4 bytes so we can only exactly fill the buffer if it's
size is 4 byte aligned.
I'm guessing that in practice, size will always be page aligned so we are good?
Perhaps worth a WARN_ON_ONCE() though?
Thanks,
Ryan
> + __le32 *updptr = ptr;
> +
> + for (int i = 0; i < nr_inst; i++)
> + updptr[i] = cpu_to_le32(AARCH64_BREAK_FAULT);
> +
> + flush_icache_range((unsigned long)ptr, (unsigned long)ptr + size);
> +}
> +#endif
> +
> static u64 module_direct_base __ro_after_init = 0;
> static u64 module_plt_base __ro_after_init = 0;
>
^ permalink raw reply
* Re: [PATCH v2 2/6] iommu/arm-smmu: Add interconnect bandwidth voting support
From: Bibek Kumar Patro @ 2026-06-19 10:54 UTC (permalink / raw)
To: Konrad Dybcio, Dmitry Baryshkov
Cc: Will Deacon, Robin Murphy, Joerg Roedel, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Bjorn Andersson, Konrad Dybcio,
linux-arm-kernel, iommu, devicetree, linux-kernel, linux-arm-msm
In-Reply-To: <299d54c5-fb93-47ee-9495-fbf48a3204fd@oss.qualcomm.com>
On 6/18/2026 2:58 PM, Konrad Dybcio wrote:
> On 6/17/26 4:26 PM, Bibek Kumar Patro wrote:
>>
>>
>> On 6/16/2026 5:51 AM, Dmitry Baryshkov wrote:
>>> On Mon, Jun 15, 2026 at 06:36:51PM +0530, Bibek Kumar Patro wrote:
>>>>
>>>>
>>>> On 6/8/2026 7:25 PM, Dmitry Baryshkov wrote:
>>>>> On Tue, May 26, 2026 at 08:12:03PM +0530, Bibek Kumar Patro wrote:
>>>>>> On some SoCs the SMMU registers require an active interconnect
>>>>>> bandwidth vote to be accessible. While other clients typically
>>>>>> satisfy this requirement implicitly, certain corner cases (e.g.
>>>>>> during sleep/wakeup transitions) can leave the SMMU without a
>>>>>> vote, causing intermittent register access failures.
>>>>>>
>>>>>> Add support for an optional interconnect path to the arm-smmu
>>>>>> driver and vote for bandwidth while the SMMU is active. The path
>>>>>> is acquired from DT if present and ignored otherwise.
>>>>>>
>>>>>> The bandwidth vote is enabled before accessing SMMU registers
>>>>>> during probe and runtime resume, and released during runtime
>>>>>> suspend and on error paths.
>>>>>>
>>>>>> Generally, from an architectural perspective, GEM_NOC and DDR are
>>>>>> expected to have an active vote whenever the adreno_smmu block is
>>>>>> powered on. In most common use cases, this requirement is implicitly
>>>>>> satisfied because other GPU-related clients (for example, the GMU
>>>>>> device) already hold a GEM_NOC vote when adreno_smmu is enabled.
>>>>>>
>>>>>> However, there are certain corner cases, such as during sleep/wakeup
>>>>>> transitions, where the GEM_NOC vote can be removed before adreno_smmu
>>>>>> is powered down. If adreno_smmu is then accessed while the interconnect
>>>>>> vote is missing, it can lead to the observed failures. Because of the
>>>>>> precise ordering involved, this scenario is difficult to reproduce
>>>>>> consistently.
>>>>>> (also GDSC is involved in adreno usecases can have an independent vote)
>>>>>>
>>>>>> Signed-off-by: Bibek Kumar Patro <bibek.patro@oss.qualcomm.com>
>>>>>> ---
>>>>>> drivers/iommu/arm/arm-smmu/arm-smmu.c | 57 +++++++++++++++++++++++++++++++++--
>>>>>> drivers/iommu/arm/arm-smmu/arm-smmu.h | 2 ++
>>>>>> 2 files changed, 57 insertions(+), 2 deletions(-)
>>>>>>
>>>>>> diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c b/drivers/iommu/arm/arm-smmu/arm-smmu.c
>>>>>> index 0bd21d206eb3e75c3b9fb1364cdc92e82c5aa499..07c7e44ec6a5bd1488f00f87d859a20495e46601 100644
>>>>>> --- a/drivers/iommu/arm/arm-smmu/arm-smmu.c
>>>>>> +++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c
>>>>>> @@ -53,6 +53,11 @@
>>>>>> #define MSI_IOVA_BASE 0x8000000
>>>>>> #define MSI_IOVA_LENGTH 0x100000
>>>>>> +/* Interconnect bandwidth vote values for the SMMU register access path */
>>>>>> +#define ARM_SMMU_ICC_AVG_BW 0
>>>>>> +#define ARM_SMMU_ICC_PEAK_BW_HIGH 1000
>>>>>
>>>>> totally random numbers, which might be different for non-Qualcomm platform.
>>>>>
>>>>
>>>> Ideally, any non-zero value would be enough to keep the path active.
>>>
>>> This is true for Qualcomm devices. However, you are adding this to a
>>> generic code.
>>>
>>>> Here 1 Would be enough to keep the path active, but might be too small to
>>>> reliably keep the bus active.
>>>> Other is UINT_MAX, which will reliably keep the bus active but might cause a
>>>> power penalty.
>>>>
>>>> #define ARM_SMMU_ICC_PEAK_BW_HIGH UINT_MAX
>>>>
>>>> seems to be suitable here to reliably keep the bus active by BCM
>>>> for both Qualcomm and non-Qualcomm platforms (with some power penalty).
>>>>
>>>> LMK, if you feel otherwise.
>>>
>>> Shift it to the qcom instance or provide platform-specific values? (My
>>> preference would be towards the first solution).
>>>
>>
>>
>> To support platform-specific values, we may need to introduce a LUT-based approach in the driver. (Bandwidth voting values cannot be placed in device-tree property IIRC ?)
>>
>> Currently, all Qualcomm platforms use 0x1000 for SMMU ICC voting. I
>
> (you used decimal 1000)
>
It's my bad, i meant 1000 only
(I'll check on the icc_bw calculation to get clarity on the values)
>> can evaluate if this could be moved to a Qualcomm-specific
>> implementation.
>
> Add a vendor hook to arm_smmu_runtime_suspend/resume and handle it within
> the QC driver
>
Just curious, wouldn't this apply for all the arm-smmu users in addition
to Qualcomm devices as i mentioned here [1].
Vendor hook would make it Qualcomm specific.
[1]:
https://lore.kernel.org/all/984ff9c7-3eef-463c-a330-bf7acd063667@oss.qualcomm.com/
Thanks & regards,
Bibek
> Konrad
^ permalink raw reply
* Re: [PATCH 15/78] ASoC: codecs: cs42l43: Use guard() for mutex locks
From: Bui Duc Phuc @ 2026-06-19 10:57 UTC (permalink / raw)
To: Charles Keepax
Cc: David Laight, Mark Brown, Liam Girdwood, Jaroslav Kysela,
Takashi Iwai, Cheng-Yi Chiang, Tzung-Bi Shih, Guenter Roeck,
Benson Leung, David Rhodes, Richard Fitzgerald, povik+lin,
Support Opensource, Nick Li, Herve Codina, Srinivas Kandagatla,
Matthias Brugger, AngeloGioacchino Del Regno, Shenghao Ding,
Kevin Lu, Baojun Xu, Sen Wang, Oder Chiou, Lars-Peter Clausen,
nuno.sa, Steven Eckhoff, patches, chrome-platform, asahi,
linux-arm-msm, linux-sound, linux-kernel, linux-arm-kernel,
linux-mediatek
In-Reply-To: <ajUcTfG3vSGz3n3d@opensource.cirrus.com>
Hi Charles, David,
> > > > > I believe you have to use scoped_guard here, as there is a return
> > > > > from the function above, if memory serves it attempts to release
> > > > > the mutex on that path despite it being above the guard.
> > > >
> > > > Indeed.
> > > > I believe clang will complain.
> > > > That makes these mechanical conversions of existing code dangerous churn.
> > > >
> > > > While using guard() (etc) can make it easier to ensure the lock is released
> > > > when functions have multiple error exits, I'm not convinced it makes the
> > > > code any easier to read (other people may disagree).
> > >
> > > I built the code with both GCC and Clang and didn't see any warnings.
> > >
> > > My understanding was that the early return exits the function before
> > > the guard is instantiated, so it should not affect the guard's cleanup
> > > handling.
> >
> > When a variable is defined (and initialised) part way down a block the
> > compiler moves the definition to the top of the block but doesn't initialise
> > it at all, the first assignment happens where the code contains the
> > definition.
> >
> > However the destructor is always called at the end of the block.
> > So if you return from a function before the definition the destructor
> > is called with an uninitialised argument.
>
> My understanding was exactly as your David, but it seems that isn't
> the whole story and indeed I had to fix a bug in our SDCA code
> that hit this. However testing this out, results in some things I
> find very hard to explain.
>
> It seems as far as I have managed to test, the code below works
> fine as Phuc suggests. It does not appear to run the mutex_unlock
> on the error path.
>
> int function()
> {
> if (error)
> return;
>
> guard(mutex)(&mutex);
>
> stuff();
>
> return;
> }
>
Thanks both for the clarification.
> The situation I hit this in before that doesn't work was actually
> this:
>
> int function()
> {
> if (error)
> goto error_label;
>
> guard(mutex)(&mutex);
>
> stuff();
>
> error_label;
> return;
> }
>
> Which in this case it does run the mutex_unlock and NULL pointer.
> Will try to find sometime to look at the generated assembly, but
> this basically totally blows my mind. Very unclear as to if this
> is supposed to work this way or just does by pure luck.
>
As stated in cleanup.h, mixing goto-based cleanup and scope-based
cleanup helpers in the same function is not expected, so I think
we should keep a consistent approach here.
Best regards,
Phuc
^ permalink raw reply
* Re: [RFC PATCH 4/6] arm64: mm: add helper to fill execmem with trapping instructions
From: Mike Rapoport @ 2026-06-19 10:58 UTC (permalink / raw)
To: Ryan Roberts
Cc: Adrian Barnaś, linux-arm-kernel, linux-mm, Catalin Marinas,
Will Deacon, David Hildenbrand, Ard Biesheuvel, Christoph Lameter,
Yang Shi, Brendan Jackman
In-Reply-To: <666a981f-44b6-4c19-a641-c1eff44fe54f@arm.com>
On Fri, Jun 19, 2026 at 11:54:25AM +0100, Ryan Roberts wrote:
> On 11/06/2026 14:01, Adrian Barnaś wrote:
> > Implement the architecture-specific execmem_fill_trapping_insns() helper
> > to poison executable memory regions.
> >
> > When CONFIG_ARCH_HAS_EXECMEM_ROX is enabled, the execmem subsystem
> > requires a way to fill unused or freed executable memory with
> > architecture-specific trapping instructions. This implementation fills
> > the specified region with AARCH64_BREAK_FAULT instructions and flushes
> > the icache to ensure the traps are immediately visible to execution.
> >
> > Signed-off-by: Adrian Barnaś <abarnas@google.com>
> > ---
> > arch/arm64/mm/init.c | 14 ++++++++++++++
> > 1 file changed, 14 insertions(+)
> >
> > diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
> > index c673a9a839dd..71aa745e0bef 100644
> > --- a/arch/arm64/mm/init.c
> > +++ b/arch/arm64/mm/init.c
> > @@ -408,6 +408,20 @@ void dump_mem_limit(void)
> > }
> >
> > #ifdef CONFIG_EXECMEM
> > +
> > +#ifdef CONFIG_ARCH_HAS_EXECMEM_ROX
> > +void execmem_fill_trapping_insns(void *ptr, size_t size)
> > +{
> > + int nr_inst = size / AARCH64_INSN_SIZE;
>
> The x86 instruction is 1 byte, so it can exactly fill any provided buffer. For
> arm64, the instruction is 4 bytes so we can only exactly fill the buffer if it's
> size is 4 byte aligned.
>
> I'm guessing that in practice, size will always be page aligned so we are good?
The size is always page aligned:
void *execmem_alloc(enum execmem_type type, size_t size)
{
...
size = PAGE_ALIGN(size);
--
Sincerely yours,
Mike.
^ permalink raw reply
* Re: [RFC PATCH v2 1/3] mm/huge_memory: make persistent huge zero folio read-only
From: David Hildenbrand (Arm) @ 2026-06-19 11:09 UTC (permalink / raw)
To: Xueyuan Chen
Cc: dave.hansen, akpm, linux-mm, linux-kernel, linux-arm-kernel, x86,
catalin.marinas, will, tglx, mingo, bp, dave.hansen, luto, peterz,
hpa, ljs, liam, vbabka, rppt, surenb, mhocko, ziy, baolin.wang,
npache, ryan.roberts, dev.jain, baohua, lance.yang, yang, jannh
In-Reply-To: <20260619025553.226940-1-xueyuan.chen21@gmail.com>
On 6/19/26 04:55, Xueyuan Chen wrote:
> On Thu, Jun 18, 2026 at 02:36:25PM +0200, David Hildenbrand (Arm) wrote:
>
> Hi, David
>
> [...]
>
>> Best to wait for some feedback.
>
> Sure.
>
>> I do wonder whether we want to pass an address instead of a page.
>>
>> https://lore.kernel.org/r/20260410151746.61150-2-kalyazin@amazon.com
>>
>> Wants to convert existing ones as well.
>>
>> That would imply that the caller must check for highmem.
>>
>> But then, we could just use existing set_memory_ro(), right?
>>
>
> Agreed. Passing an address and reusing the existing set_memory_ro()
> definitely makes things simpler.
>
> However, there is an arm64 specific limitation:
> currently, the set_memory_r* api on arm64 only support the vmap
> region and do not handle linear map addresses.
>
> If we go this route, should I extend the arm64 set_memory_r*
> implementation in the next version? The plan would be to make it check
> for the bblm2 feature and modify the linear map PTEs accordingly.
> What do you think?
Good point! It's not really clear on which ranges set_memory*() is supposed to
work ...
arm64 only works on vmalloc/vmap, x86 and riscv on ordinary directmap ... what a
mess.
Having a new direct-map specific function with clear semantics might indeed
avoid even messing with that.
So, yeah, given that we have
set_direct_map_invalid_noflush
set_direct_map_default_noflush
set_direct_map_valid_noflush
Let's add a
set_direct_map_ro()
Or (my preference)
change_direct_map_ro()
But given the existing naming scheme ... maybe just set_direct_map_ro() and
we'll clean this up another day.
Now, should there also be a "_noflush" in there, or who is supposed to flush the
TLB (or don't we flush at all, because it's used early during boot so far)?
In any case, for this function we should add excessive documentation and define
clear semantics.
--
Cheers,
David
^ permalink raw reply
* Re: [PATCH 15/78] ASoC: codecs: cs42l43: Use guard() for mutex locks
From: Takashi Iwai @ 2026-06-19 11:14 UTC (permalink / raw)
To: Bui Duc Phuc
Cc: Charles Keepax, David Laight, Mark Brown, Liam Girdwood,
Jaroslav Kysela, Takashi Iwai, Cheng-Yi Chiang, Tzung-Bi Shih,
Guenter Roeck, Benson Leung, David Rhodes, Richard Fitzgerald,
povik+lin, Support Opensource, Nick Li, Herve Codina,
Srinivas Kandagatla, Matthias Brugger, AngeloGioacchino Del Regno,
Shenghao Ding, Kevin Lu, Baojun Xu, Sen Wang, Oder Chiou,
Lars-Peter Clausen, nuno.sa, Steven Eckhoff, patches,
chrome-platform, asahi, linux-arm-msm, linux-sound, linux-kernel,
linux-arm-kernel, linux-mediatek
In-Reply-To: <CAABR9nGRCZ1zv0cyBGc3yuM8MeFNqBB1MkGUL7bTbtC_LcKKzA@mail.gmail.com>
On Fri, 19 Jun 2026 12:57:57 +0200,
Bui Duc Phuc wrote:
>
> Hi Charles, David,
>
>
>
> > > > > > I believe you have to use scoped_guard here, as there is a return
> > > > > > from the function above, if memory serves it attempts to release
> > > > > > the mutex on that path despite it being above the guard.
> > > > >
> > > > > Indeed.
> > > > > I believe clang will complain.
> > > > > That makes these mechanical conversions of existing code dangerous churn.
> > > > >
> > > > > While using guard() (etc) can make it easier to ensure the lock is released
> > > > > when functions have multiple error exits, I'm not convinced it makes the
> > > > > code any easier to read (other people may disagree).
> > > >
> > > > I built the code with both GCC and Clang and didn't see any warnings.
> > > >
> > > > My understanding was that the early return exits the function before
> > > > the guard is instantiated, so it should not affect the guard's cleanup
> > > > handling.
> > >
> > > When a variable is defined (and initialised) part way down a block the
> > > compiler moves the definition to the top of the block but doesn't initialise
> > > it at all, the first assignment happens where the code contains the
> > > definition.
> > >
> > > However the destructor is always called at the end of the block.
> > > So if you return from a function before the definition the destructor
> > > is called with an uninitialised argument.
> >
> > My understanding was exactly as your David, but it seems that isn't
> > the whole story and indeed I had to fix a bug in our SDCA code
> > that hit this. However testing this out, results in some things I
> > find very hard to explain.
> >
> > It seems as far as I have managed to test, the code below works
> > fine as Phuc suggests. It does not appear to run the mutex_unlock
> > on the error path.
> >
> > int function()
> > {
> > if (error)
> > return;
> >
> > guard(mutex)(&mutex);
> >
> > stuff();
> >
> > return;
> > }
> >
>
> Thanks both for the clarification.
>
> > The situation I hit this in before that doesn't work was actually
> > this:
> >
> > int function()
> > {
> > if (error)
> > goto error_label;
> >
> > guard(mutex)(&mutex);
> >
> > stuff();
> >
> > error_label;
> > return;
> > }
> >
> > Which in this case it does run the mutex_unlock and NULL pointer.
> > Will try to find sometime to look at the generated assembly, but
> > this basically totally blows my mind. Very unclear as to if this
> > is supposed to work this way or just does by pure luck.
> >
>
> As stated in cleanup.h, mixing goto-based cleanup and scope-based
> cleanup helpers in the same function is not expected, so I think
> we should keep a consistent approach here.
Right, and IIRC, clang would complain the mixed goto case at least
with W=1.
Takashi
^ permalink raw reply
* [PATCH v5 1/1] arm64: dts: add tqma9596la-mba95xxca
From: Alexander Stein @ 2026-06-19 11:24 UTC (permalink / raw)
To: Frank Li, Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam,
Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Geert Uytterhoeven, Magnus Damm
Cc: Markus Niebel, imx, linux-arm-kernel, devicetree, linux-kernel,
linux, linux-renesas-soc, Alexander Stein
From: Markus Niebel <Markus.Niebel@ew.tq-group.com>
This adds support for TQMa95xxLA modules, designed to be soldered
on a carrier board. MBa95xxCA is a carrier reference board / starter kit
design.
There is a common device tree for all variants with e.g. reduced
CPU core / feature count.
Enable the external accessible PCIe controllers as host,
add clocking and reset GPIO. While at it, add hogs for GPIO
lines from the M.2 slots until M.2 connector driver is available.
Signed-off-by: Markus Niebel <Markus.Niebel@ew.tq-group.com>
Signed-off-by: Alexander Stein <alexander.stein@ew.tq-group.com>
---
Changes in v5:
* Limit LPSPI4 max frequency
* Replace PCIe M2 Key-E GPIO hogs with dedicated connector node
* Fix PCIe clock configuration
Changes in v4:
* Fix LPSPI4 pad muxing and control
Changes in v3:
* Moved reserved-memory to board-lebel
* Remove VPU reserved memory (unused for now)
* Fix typo in connector comment
Changes in v2:
* removed useless regulator
* added USB PD source configuration
* Removed unused uart-has-rtscts properties (unused by LPUART)
* Fixed RTS/CTS pullups in pinctrl
* Added thermalzone on module
arch/arm64/boot/dts/freescale/Makefile | 1 +
.../freescale/imx95-tqma9596la-mba95xxca.dts | 963 ++++++++++++++++++
.../boot/dts/freescale/imx95-tqma9596la.dtsi | 278 +++++
3 files changed, 1242 insertions(+)
create mode 100644 arch/arm64/boot/dts/freescale/imx95-tqma9596la-mba95xxca.dts
create mode 100644 arch/arm64/boot/dts/freescale/imx95-tqma9596la.dtsi
diff --git a/arch/arm64/boot/dts/freescale/Makefile b/arch/arm64/boot/dts/freescale/Makefile
index 8ddaab127ab9c..43e1dc51b11d7 100644
--- a/arch/arm64/boot/dts/freescale/Makefile
+++ b/arch/arm64/boot/dts/freescale/Makefile
@@ -649,6 +649,7 @@ dtb-$(CONFIG_ARCH_MXC) += imx95-19x19-frdm-pro.dtb
dtb-$(CONFIG_ARCH_MXC) += imx95-aquila-clover.dtb
dtb-$(CONFIG_ARCH_MXC) += imx95-aquila-dev.dtb
dtb-$(CONFIG_ARCH_MXC) += imx95-toradex-smarc-dev.dtb
+dtb-$(CONFIG_ARCH_MXC) += imx95-tqma9596la-mba95xxca.dtb
dtb-$(CONFIG_ARCH_MXC) += imx95-tqma9596sa-mb-smarc-2.dtb
dtb-$(CONFIG_ARCH_MXC) += imx95-var-dart-sonata.dtb
dtb-$(CONFIG_ARCH_MXC) += imx95-verdin-nonwifi-dahlia.dtb
diff --git a/arch/arm64/boot/dts/freescale/imx95-tqma9596la-mba95xxca.dts b/arch/arm64/boot/dts/freescale/imx95-tqma9596la-mba95xxca.dts
new file mode 100644
index 0000000000000..4b49f6cf731da
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx95-tqma9596la-mba95xxca.dts
@@ -0,0 +1,963 @@
+// SPDX-License-Identifier: (GPL-2.0-or-later OR MIT)
+/*
+ * Copyright (c) 2024-2026 TQ-Systems GmbH <linux@ew.tq-group.com>,
+ * D-82229 Seefeld, Germany.
+ * Author: Alexander Stein
+ * Author: Markus Niebel
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/leds/common.h>
+#include <dt-bindings/net/ti-dp83867.h>
+#include <dt-bindings/pwm/pwm.h>
+#include <dt-bindings/usb/pd.h>
+#include "imx95-tqma9596la.dtsi"
+
+/ {
+ model = "TQ-Systems i.MX95 TQMa95xxLA on MBa95xxCA";
+ compatible = "tq,imx95-tqma9596la-mba95xxca", "tq,imx95-tqma9596la", "fsl,imx95";
+ chassis-type = "embedded";
+
+ aliases {
+ ethernet0 = &enetc_port0;
+ ethernet1 = &enetc_port1;
+ ethernet2 = &enetc_port2;
+ gpio0 = &gpio1;
+ gpio1 = &gpio2;
+ gpio2 = &gpio3;
+ gpio3 = &gpio4;
+ i2c0 = &lpi2c1;
+ i2c1 = &lpi2c2;
+ i2c2 = &lpi2c3;
+ i2c3 = &lpi2c4;
+ i2c4 = &lpi2c5;
+ i2c5 = &lpi2c6;
+ i2c6 = &lpi2c7;
+ i2c7 = &lpi2c8;
+ mmc0 = &usdhc1;
+ mmc1 = &usdhc2;
+ rtc0 = &pcf85063;
+ rtc1 = &scmi_bbm;
+ serial0 = &lpuart1;
+ serial1 = &lpuart2;
+ serial2 = &lpuart3;
+ serial3 = &lpuart4;
+ serial4 = &lpuart5;
+ serial5 = &lpuart6;
+ serial6 = &lpuart7;
+ serial7 = &lpuart8;
+ spi0 = &flexspi1;
+ };
+
+ chosen {
+ stdout-path = &lpuart1;
+ };
+
+ backlight_lvds: backlight-lvds {
+ compatible = "pwm-backlight";
+ pwms = <&tpm5 2 100000 0>;
+ brightness-levels = <0 4 8 16 32 64 128 255>;
+ default-brightness-level = <7>;
+ enable-gpios = <&expander2 6 GPIO_ACTIVE_HIGH>;
+ power-supply = <®_12v0>;
+ status = "disabled";
+ };
+
+ clk_eth: clk-eth {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <156250000>;
+ };
+
+ /*
+ * TODO: gate is disabled for now and GPIO are hogged
+ * ENETC driver switches the clock far too late for ENETC2 + SFP
+ */
+ clk_eth_gate: clk-eth-gate {
+ compatible = "gpio-gate-clock";
+ enable-gpios = <&expander2 0 GPIO_ACTIVE_HIGH>;
+ clocks = <&clk_eth>;
+ #clock-cells = <0>;
+ status = "disabled";
+ };
+
+ clk_xtal25: clk-xtal25 {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <25000000>;
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+ autorepeat;
+
+ button-b {
+ label = "BUTTON_B#";
+ linux,code = <BTN_1>;
+ gpios = <&expander1 0 GPIO_ACTIVE_LOW>;
+ wakeup-source;
+ };
+ };
+
+ gpio-leds {
+ compatible = "gpio-leds";
+
+ led-1 {
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_STATUS;
+ gpios = <&expander2 13 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "default-on";
+ };
+
+ led-2 {
+ color = <LED_COLOR_ID_AMBER>;
+ function = LED_FUNCTION_HEARTBEAT;
+ gpios = <&expander2 14 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "heartbeat";
+ };
+ };
+
+ iio-hwmon {
+ compatible = "iio-hwmon";
+ io-channels = <&adc1 0>, <&adc1 1>, <&adc1 2>, <&adc1 3>,
+ <&adc1 4>, <&adc1 5>, <&adc1 6>, <&adc1 7>;
+ };
+
+ reg_v1v8_mb: regulator-v1v8-mb {
+ compatible = "regulator-fixed";
+ regulator-name = "V_1V8_MB";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ reg_v3v3_mb: regulator-v3v3-mb {
+ compatible = "regulator-fixed";
+ regulator-name = "V_3V3_MB";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ reg_3v3a_10g: regulator-3v3a-10g {
+ compatible = "regulator-fixed";
+ regulator-name = "3V3A_10G";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&expander2 15 GPIO_ACTIVE_HIGH>;
+ startup-delay-us = <2000>;
+ enable-active-high;
+ };
+
+ reg_12v0: regulator-12v0 {
+ compatible = "regulator-fixed";
+ regulator-name = "12V0";
+ regulator-min-microvolt = <12000000>;
+ regulator-max-microvolt = <12000000>;
+ gpio = <&expander1 15 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ reg_pwm_fan: regulator-pwm-fan {
+ compatible = "regulator-fixed";
+ regulator-name = "FAN_PWR";
+ regulator-min-microvolt = <12000000>;
+ regulator-max-microvolt = <12000000>;
+ gpio = <&expander3 15 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ vin-supply = <®_12v0>;
+ };
+
+ reg_lvds: regulator-lvds {
+ compatible = "regulator-fixed";
+ regulator-name = "LCD_PWR_EN";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&expander2 7 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ /* USB NC limitations, RM 162.1.2 VBUS limitations */
+ reg_vbus_usb3: regulator-vbus-usb3 {
+ compatible = "regulator-fixed";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-name = "USB3_VBUS";
+ gpio = <&gpio4 1 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ reserved-memory {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ linux_cma: linux,cma {
+ compatible = "shared-dma-pool";
+ reusable;
+ size = <0 0x28000000>;
+ alloc-ranges = <0 0x80000000 0 0x80000000>;
+ linux,cma-default;
+ };
+ };
+
+ sfp_xfi: sfp-xfi {
+ compatible = "sff,sfp";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_sfp>;
+ i2c-bus = <&lpi2c7>;
+ maximum-power-milliwatt = <2000>;
+ mod-def0-gpios = <&expander1 3 GPIO_ACTIVE_LOW>;
+ tx-fault-gpios = <&gpio2 30 GPIO_ACTIVE_HIGH>;
+ los-gpios = <&gpio2 31 GPIO_ACTIVE_HIGH>;
+ tx-disable-gpios = <&expander2 2 GPIO_ACTIVE_HIGH>;
+ };
+
+ sound {
+ compatible = "fsl,imx-audio-tlv320aic32x4";
+ model = "tqm-tlv320aic32";
+ audio-codec = <&tlv320aic3x04>;
+ audio-cpu = <&sai3>;
+ audio-routing =
+ "IN3_L", "Mic Jack",
+ "Mic Jack", "Mic Bias",
+ "Headphone Jack", "HPL",
+ "Headphone Jack", "HPR",
+ "IN1_L", "Line In Jack",
+ "IN1_R", "Line In Jack",
+ "Line Out Jack", "LOL",
+ "Line Out Jack", "LOR";
+ };
+
+ wifi-connector {
+ compatible = "pcie-m2-e-connector";
+ vpcie3v3-supply = <®_v3v3_mb>;
+ vpcie1v8-supply = <®_v1v8_mb>;
+ i2c-parent = <&lpi2c2>;
+ w-disable1-gpios = <&expander2 9 GPIO_ACTIVE_LOW>;
+ w-disable2-gpios = <&expander2 10 GPIO_ACTIVE_LOW>;
+ /* UART_WAKE is connected to SM */
+ /* SDIO_WAKE is connected to SM */
+ sdio-reset-gpios = <&expander3 2 GPIO_ACTIVE_LOW>;
+ };
+};
+
+&adc1 {
+ status = "okay";
+};
+
+&enetc_port0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_enetc0>;
+ phy-handle = <ðphy0>;
+ phy-mode = "rgmii-id";
+ status = "okay";
+};
+
+&enetc_port1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_enetc1>;
+ phy-handle = <ðphy1>;
+ phy-mode = "rgmii-id";
+ status = "okay";
+};
+
+/* No support for XFI yet */
+&enetc_port2 {
+ sfp = <&sfp_xfi>;
+ phy-mode = "10gbase-r";
+ clocks = <&clk_eth>;
+ clock-names = "enet_ref_clk";
+ managed = "in-band-status";
+ status = "disabled";
+};
+
+&flexcan1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_flexcan1>;
+ status = "okay";
+};
+
+&flexcan2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_flexcan2>;
+ status = "okay";
+};
+
+&lpi2c2 {
+ tlv320aic3x04: audio-codec@18 {
+ compatible = "ti,tlv320aic32x4";
+ reg = <0x18>;
+ clocks = <&scmi_clk IMX95_CLK_SAI3>;
+ clock-names = "mclk";
+ reset-gpios = <&expander1 14 GPIO_ACTIVE_LOW>;
+ iov-supply = <®_v3v3_mb>;
+ ldoin-supply = <®_v3v3_mb>;
+ };
+
+ fan_controller: fan-controller@2f {
+ compatible = "microchip,emc2301", "microchip,emc2305";
+ reg = <0x2f>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #pwm-cells = <3>;
+ status = "okay";
+
+ fan: fan@0 {
+ reg = <0x0>;
+ pwms = <&fan_controller 40000 PWM_POLARITY_INVERTED 1>;
+ #cooling-cells = <2>;
+ fan-supply = <®_pwm_fan>;
+ };
+ };
+
+ ptn5110: usb-typec@50 {
+ compatible = "nxp,ptn5110", "tcpci";
+ reg = <0x50>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_typec>;
+ interrupt-parent = <&gpio2>;
+ interrupts = <28 IRQ_TYPE_LEVEL_LOW>;
+
+ typec_con: connector {
+ compatible = "usb-c-connector";
+ label = "X9";
+ power-role = "source";
+ data-role = "dual";
+ source-pdos = <PDO_FIXED(5000, 500, PDO_FIXED_USB_COMM)>;
+ self-powered;
+
+ port {
+ typec_con_hs: endpoint {
+ remote-endpoint = <&typec_hs>;
+ };
+ };
+ };
+ };
+
+ sensor_mb: temperature-sensor@1e {
+ compatible = "nxp,se97b", "jedec,jc-42.4-temp";
+ reg = <0x1e>;
+ };
+
+ eeprom_mb: eeprom@56 {
+ compatible = "nxp,se97b", "atmel,24c02";
+ reg = <0x56>;
+ pagesize = <16>;
+ vcc-supply = <®_v3v3_mb>;
+ };
+
+ pcieclk: clock-generator@68 {
+ compatible = "renesas,9fgv0441";
+ reg = <0x68>;
+ clocks = <&clk_xtal25>;
+ #clock-cells = <1>;
+ };
+
+ /* D39 IN/OUT 3V3 */
+ expander1: gpio@74 {
+ compatible = "ti,tca9539";
+ reg = <0x74>;
+ vcc-supply = <®_v3v3_mb>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_expander1>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ interrupt-parent = <&gpio2>;
+ interrupts = <14 IRQ_TYPE_EDGE_FALLING>;
+
+ gpio-line-names =
+ /* 00 */ "BUTTON_B#", "CAM0_SYNC_3V3",
+ /* 02 */ "CAM1_SYNC_3V3", "SFP_MOD_ABS",
+ /* 04 */ "DIG_IN1", "DIG_IN2",
+ /* 06 */ "DIG_IN3", "DIG_IN4",
+ /* 08 */ "DIG_OUT_1_2_STATE", "DIG_OUT_3_4_STATE",
+ /* 10 */ "DIG_OUT_1_EN", "DIG_OUT_2_EN",
+ /* 12 */ "DIG_OUT_3_EN", "DIG_OUT_4_EN",
+ /* 14 */ "AUDIO_RST#", "12V_EN";
+ };
+
+ /* D40 OUT 3V3 */
+ expander2: gpio@75 {
+ compatible = "ti,tca9539";
+ reg = <0x75>;
+ vcc-supply = <®_3v3>;
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ gpio-line-names =
+ /* 00 */ "ETH10G_REFCLK_EN", "ETH10G_REFCLK_RST#",
+ /* 02 */ "SFP_TX_DIS", "USB3_RESET#",
+ /* 04 */ "USB2_RESET#", "LCD_RESET#",
+ /* 06 */ "LCD_BLT_EN", "LCD_PWR_EN",
+ /* 08 */ "M2_KEYE_PERST#", "M2_KEYE_WDISABLE1#",
+ /* 10 */ "M2_KEYE_WDISABLE2#", "M2_KEYB_PERST#",
+ /* 12 */ "M2_KEYB_WDISABLE1#", "USER_LED1",
+ /* 14 */ "USER_LED2", "3V3A_10G_EN";
+
+ eth10g-refclk-en-hog {
+ gpio-hog;
+ gpios = <0 GPIO_ACTIVE_HIGH>;
+ output-high;
+ line-name = "ETH10G_REFCLK_EN";
+ };
+
+ eth10g-refclk-rst-hog {
+ gpio-hog;
+ gpios = <1 GPIO_ACTIVE_LOW>;
+ output-low;
+ line-name = "ETH10G_REFCLK_RST#";
+ };
+
+ m2-keyb-wdisable1-hog {
+ gpio-hog;
+ gpios = <12 GPIO_ACTIVE_LOW>;
+ output-low;
+ line-name = "M2_KEYB_WDISABLE1#";
+ };
+ };
+
+ /* D41 OUT 1V8 */
+ expander3: gpio@76 {
+ compatible = "ti,tca9539";
+ reg = <0x76>;
+ vcc-supply = <®_v1v8_mb>;
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ gpio-line-names =
+ /* 00 */ "ENET1_RESET#", "ENET2_RESET#",
+ /* 02 */ "M2_KEYE_SDIO_RST#", "M2_KEYE_DEV_WLAN_WAKE#",
+ /* 04 */ "M2_KEYE_DEV_BT_WAKE", "M2_KEYB_W_DISABLE2#",
+ /* 06 */ "M2_KEYB_RST#", "M2_KEYB_FULL_CARD_PWR_OFF#",
+ /* 08 */ "M2_KEYB_DPR", "CAM0_PWR#",
+ /* 10 */ "CAM1_PWR#", "CAM0_RST#",
+ /* 12 */ "CAM1_RST#", "CAM0_TRIGGER",
+ /* 14 */ "CAM1_TRIGGER", "FAN_PWR_EN";
+
+ m2-keye-sdio-rst-hog {
+ gpio-hog;
+ gpios = <2 GPIO_ACTIVE_LOW>;
+ output-low;
+ line-name = "M2_KEYE_SDIO_RST#";
+ };
+
+ m2-keye-dev_wlan-wake-hog {
+ gpio-hog;
+ gpios = <3 GPIO_ACTIVE_LOW>;
+ input;
+ line-name = "M2_KEYE_DEV_WLAN_WAKE#";
+ };
+
+ m2-keye-dev_bt-wake-hog {
+ gpio-hog;
+ gpios = <4 GPIO_ACTIVE_LOW>;
+ input;
+ line-name = "M2_KEYE_DEV_BT_WAKE#";
+ };
+
+ m2-keyb-wdisable2-hog {
+ gpio-hog;
+ gpios = <5 GPIO_ACTIVE_LOW>;
+ output-low;
+ line-name = "M2_KEYB_WDISABLE1#";
+ };
+
+ m2-keyb-rst-hog {
+ gpio-hog;
+ gpios = <6 GPIO_ACTIVE_LOW>;
+ output-low;
+ line-name = "M2_KEYB_RST#";
+ };
+
+ m2-keyb-full-card-pwr-off-hog {
+ gpio-hog;
+ gpios = <7 GPIO_ACTIVE_LOW>;
+ output-low;
+ line-name = "M2_KEYB_FULL_CARD_PWR_OFF#";
+ };
+ };
+};
+
+/* X4 + SFP */
+&lpi2c7 {
+ clock-frequency = <400000>;
+ pinctrl-names = "default", "gpio";
+ pinctrl-0 = <&pinctrl_lpi2c7>;
+ pinctrl-1 = <&pinctrl_lpi2c7_recovery>;
+ scl-gpios = <&gpio2 7 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ sda-gpios = <&gpio2 6 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ status = "okay";
+
+ /* TODO: 0x19: retimer */
+
+ /* 0x50 / 0x51: SFP EEPROM */
+};
+
+/* X4 */
+&lpspi4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lpspi4>;
+ cs-gpios = <&gpio5 14 GPIO_ACTIVE_LOW>, <&gpio5 13 GPIO_ACTIVE_LOW>;
+ /* per datasheet, without SCK loopback via pad (LPSPI_CFGR1[SAMPLE]) */
+ spi-max-frequency = <30000000>;
+ status = "okay";
+};
+
+&lpuart1 {
+ /* console */
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lpuart1>;
+ status = "okay";
+};
+
+&lpuart2 {
+ /* SM */
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lpuart2>;
+ status = "reserved";
+};
+
+&lpuart5 {
+ /* X16 M.2 KEY E */
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lpuart5>;
+ status = "okay";
+};
+
+&lpuart7 {
+ /* X5 */
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lpuart7>;
+ status = "okay";
+};
+
+&lpuart8 {
+ /* X15 */
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lpuart8>;
+ linux,rs485-enabled-at-boot-time;
+ status = "okay";
+};
+
+&netc_blk_ctrl {
+ status = "okay";
+};
+
+&netc_emdio {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_emdio>;
+ status = "okay";
+
+ /* IRQ pin is AON GPIO, not usable */
+ ethphy0: ethernet-phy@0 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <0>;
+ reset-gpios = <&expander3 0 GPIO_ACTIVE_LOW>;
+ reset-assert-us = <500000>;
+ reset-deassert-us = <50000>;
+ ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_50_NS>;
+ ti,tx-internal-delay = <DP83867_RGMIIDCTL_2_50_NS>;
+ ti,fifo-depth = <DP83867_PHYCR_FIFO_DEPTH_4_B_NIB>;
+ ti,dp83867-rxctrl-strap-quirk;
+ ti,clk-output-sel = <DP83867_CLK_O_SEL_OFF>;
+ };
+
+ ethphy1: ethernet-phy@1 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ethphy1>;
+ reset-gpios = <&expander3 1 GPIO_ACTIVE_LOW>;
+ reset-assert-us = <500000>;
+ reset-deassert-us = <50000>;
+ interrupt-parent = <&gpio4>;
+ interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+ ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_50_NS>;
+ ti,tx-internal-delay = <DP83867_RGMIIDCTL_2_50_NS>;
+ ti,fifo-depth = <DP83867_PHYCR_FIFO_DEPTH_4_B_NIB>;
+ ti,dp83867-rxctrl-strap-quirk;
+ ti,clk-output-sel = <DP83867_CLK_O_SEL_OFF>;
+ };
+};
+
+&netc_timer {
+ status = "okay";
+};
+
+&netcmix_blk_ctrl {
+ status = "okay";
+};
+
+/* X16 M2 / E-Key mPCIe */
+&pcie0 {
+ pinctrl-0 = <&pinctrl_pcie0>;
+ pinctrl-names = "default";
+ clocks = <&scmi_clk IMX95_CLK_HSIO>,
+ <&scmi_clk IMX95_CLK_HSIOPLL>,
+ <&scmi_clk IMX95_CLK_HSIOPLL_VCO>,
+ <&scmi_clk IMX95_CLK_HSIOPCIEAUX>,
+ <&hsio_blk_ctl 0>,
+ <&pcieclk 1>;
+ clock-names = "pcie", "pcie_bus", "pcie_phy", "pcie_aux", "ref", "extref";
+ reset-gpios = <&expander2 8 GPIO_ACTIVE_LOW>;
+ /* Not supported on REV.0100 */
+ /* supports-clkreq; */
+ status = "okay";
+};
+
+/* X17 M2 / B-Key PCIe */
+&pcie1 {
+ pinctrl-0 = <&pinctrl_pcie1>;
+ pinctrl-names = "default";
+ clocks = <&scmi_clk IMX95_CLK_HSIO>,
+ <&scmi_clk IMX95_CLK_HSIOPLL>,
+ <&scmi_clk IMX95_CLK_HSIOPLL_VCO>,
+ <&scmi_clk IMX95_CLK_HSIOPCIEAUX>,
+ <&hsio_blk_ctl 0>,
+ <&pcieclk 0>;
+ clock-names = "pcie", "pcie_bus", "pcie_phy", "pcie_aux", "ref", "extref";
+ reset-gpios = <&expander2 11 GPIO_ACTIVE_LOW>;
+ /* Not supported on REV.0100 */
+ /* supports-clkreq; */
+ status = "okay";
+};
+
+®_sdvmmc {
+ status = "okay";
+};
+
+&sai3 {
+ #sound-dai-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_sai3>;
+ assigned-clocks = <&scmi_clk IMX95_CLK_AUDIOPLL1_VCO>,
+ <&scmi_clk IMX95_CLK_AUDIOPLL2_VCO>,
+ <&scmi_clk IMX95_CLK_AUDIOPLL1>,
+ <&scmi_clk IMX95_CLK_AUDIOPLL2>,
+ <&scmi_clk IMX95_CLK_SAI3>;
+ assigned-clock-parents = <0>, <0>, <0>, <0>,
+ <&scmi_clk IMX95_CLK_AUDIOPLL1>;
+ assigned-clock-rates = <3932160000>,
+ <3612672000>, <393216000>,
+ <361267200>, <12288000>;
+ fsl,sai-mclk-direction-output;
+ status = "okay";
+};
+
+&scmi_bbm {
+ linux,code = <KEY_POWER>;
+};
+
+&thermal_zones {
+ a55-thermal {
+ trips {
+ cpu_active0: trip-active0 {
+ temperature = <40000>;
+ hysteresis = <5000>;
+ type = "active";
+ };
+
+ cpu_active1: trip-active1 {
+ temperature = <48000>;
+ hysteresis = <3000>;
+ type = "active";
+ };
+
+ cpu_active2: trip-active2 {
+ temperature = <60000>;
+ hysteresis = <10000>;
+ type = "active";
+ };
+ };
+
+ cooling-maps {
+ map1 {
+ trip = <&cpu_active0>;
+ cooling-device = <&fan 0 2>;
+ };
+
+ map2 {
+ trip = <&cpu_active1>;
+ cooling-device = <&fan 3 5>;
+ };
+
+ map3 {
+ trip = <&cpu_active2>;
+ cooling-device = <&fan 6 10>;
+ };
+ };
+ };
+};
+
+&tpm3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_tpm3>;
+ status = "okay";
+};
+
+&tpm5 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_tpm5>;
+};
+
+&usb2 {
+ dr_mode = "otg";
+ hnp-disable;
+ srp-disable;
+ adp-disable;
+ usb-role-switch;
+ disable-over-current;
+ samsung,picophy-pre-emp-curr-control = <3>;
+ samsung,picophy-dc-vol-level-adjust = <7>;
+ status = "okay";
+
+ port {
+ typec_hs: endpoint {
+ remote-endpoint = <&typec_con_hs>;
+ };
+ };
+};
+
+&usb3 {
+ status = "okay";
+};
+
+&usb3_dwc3 {
+ dr_mode = "host";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "okay";
+
+ hub_2_0: hub@1 {
+ compatible = "usb451,8142";
+ reg = <1>;
+ peer-hub = <&hub_3_0>;
+ reset-gpios = <&expander2 3 GPIO_ACTIVE_LOW>;
+ vdd-supply = <®_v3v3_mb>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ hub_2_1: hub@1 {
+ compatible = "usb424,2514";
+ reg = <1>;
+ reset-gpios = <&expander2 4 GPIO_ACTIVE_LOW>;
+ vdd-supply = <®_v3v3_mb>;
+ vdda-supply = <®_v3v3_mb>;
+ };
+ };
+
+ hub_3_0: hub@2 {
+ compatible = "usb451,8140";
+ reg = <2>;
+ peer-hub = <&hub_2_0>;
+ reset-gpios = <&expander2 3 GPIO_ACTIVE_LOW>;
+ vdd-supply = <®_v3v3_mb>;
+ };
+};
+
+&usb3_phy {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usb3>;
+ vbus-supply = <®_vbus_usb3>;
+ status = "okay";
+};
+
+/* X7 µSD */
+&usdhc2 {
+ pinctrl-names = "default", "state_100mhz", "state_200mhz";
+ pinctrl-0 = <&pinctrl_usdhc2>;
+ pinctrl-1 = <&pinctrl_usdhc2_100mhz>;
+ pinctrl-2 = <&pinctrl_usdhc2_200mhz>;
+ vmmc-supply = <®_sdvmmc>;
+ cd-gpios = <&gpio3 0 GPIO_ACTIVE_LOW>;
+ no-mmc;
+ no-sdio;
+ disable-wp;
+ bus-width = <4>;
+ status = "okay";
+};
+
+&scmi_iomuxc {
+ pinctrl_enetc0: enetc0grp {
+ fsl,pins = <IMX95_PAD_ENET1_RD0__NETCMIX_TOP_ETH0_RGMII_RD0 0x1100>,
+ <IMX95_PAD_ENET1_RD1__NETCMIX_TOP_ETH0_RGMII_RD1 0x1100>,
+ <IMX95_PAD_ENET1_RD2__NETCMIX_TOP_ETH0_RGMII_RD2 0x1100>,
+ <IMX95_PAD_ENET1_RD3__NETCMIX_TOP_ETH0_RGMII_RD3 0x1100>,
+ <IMX95_PAD_ENET1_RXC__NETCMIX_TOP_ETH0_RGMII_RX_CLK 0x1100>,
+ <IMX95_PAD_ENET1_RX_CTL__NETCMIX_TOP_ETH0_RGMII_RX_CTL 0x1100>,
+ <IMX95_PAD_ENET1_TD0__NETCMIX_TOP_ETH0_RGMII_TD0 0x11e>,
+ <IMX95_PAD_ENET1_TD1__NETCMIX_TOP_ETH0_RGMII_TD1 0x11e>,
+ <IMX95_PAD_ENET1_TD2__NETCMIX_TOP_ETH0_RGMII_TD2 0x11e>,
+ <IMX95_PAD_ENET1_TD3__NETCMIX_TOP_ETH0_RGMII_TD3 0x11e>,
+ <IMX95_PAD_ENET1_TXC__NETCMIX_TOP_ETH0_RGMII_TX_CLK 0x11e>,
+ <IMX95_PAD_ENET1_TX_CTL__NETCMIX_TOP_ETH0_RGMII_TX_CTL 0x11e>;
+ };
+
+ pinctrl_enetc1: enetc1grp {
+ fsl,pins = <IMX95_PAD_ENET2_RD0__NETCMIX_TOP_ETH1_RGMII_RD0 0x1100>,
+ <IMX95_PAD_ENET2_RD1__NETCMIX_TOP_ETH1_RGMII_RD1 0x1100>,
+ <IMX95_PAD_ENET2_RD2__NETCMIX_TOP_ETH1_RGMII_RD2 0x1100>,
+ <IMX95_PAD_ENET2_RD3__NETCMIX_TOP_ETH1_RGMII_RD3 0x1100>,
+ <IMX95_PAD_ENET2_RXC__NETCMIX_TOP_ETH1_RGMII_RX_CLK 0x1100>,
+ <IMX95_PAD_ENET2_RX_CTL__NETCMIX_TOP_ETH1_RGMII_RX_CTL 0x1100>,
+ <IMX95_PAD_ENET2_TD0__NETCMIX_TOP_ETH1_RGMII_TD0 0x11e>,
+ <IMX95_PAD_ENET2_TD1__NETCMIX_TOP_ETH1_RGMII_TD1 0x11e>,
+ <IMX95_PAD_ENET2_TD2__NETCMIX_TOP_ETH1_RGMII_TD2 0x11e>,
+ <IMX95_PAD_ENET2_TD3__NETCMIX_TOP_ETH1_RGMII_TD3 0x11e>,
+ <IMX95_PAD_ENET2_TXC__NETCMIX_TOP_ETH1_RGMII_TX_CLK 0x11e>,
+ <IMX95_PAD_ENET2_TX_CTL__NETCMIX_TOP_ETH1_RGMII_TX_CTL 0x11e>;
+ };
+
+ pinctrl_ethphy0: ethphy0grp {
+ fsl,pins = <IMX95_PAD_PDM_BIT_STREAM0__AONMIX_TOP_GPIO1_IO_BIT9 0x1100>;
+ };
+
+ pinctrl_ethphy1: ethphy1grp {
+ fsl,pins = <IMX95_PAD_ENET1_MDC__GPIO4_IO_BIT0 0x1100>;
+ };
+
+ pinctrl_expander1: expander1grp {
+ fsl,pins = <IMX95_PAD_GPIO_IO14__GPIO2_IO_BIT14 0x1100>;
+ };
+
+ pinctrl_flexcan1: flexcan1grp {
+ fsl,pins = <IMX95_PAD_SAI1_TXC__AONMIX_TOP_CAN1_RX 0x1300>,
+ <IMX95_PAD_SAI1_TXD0__AONMIX_TOP_CAN1_TX 0x31e>;
+ };
+
+ pinctrl_flexcan2: flexcan2grp {
+ fsl,pins = <IMX95_PAD_GPIO_IO25__CAN2_TX 0x31e>,
+ <IMX95_PAD_GPIO_IO27__CAN2_RX 0x1300>;
+ };
+
+ pinctrl_lpi2c7: lpi2c7grp {
+ fsl,pins = <IMX95_PAD_GPIO_IO07__LPI2C7_SCL 0x40001b1e>,
+ <IMX95_PAD_GPIO_IO06__LPI2C7_SDA 0x40001b1e>;
+ };
+
+ pinctrl_lpi2c7_recovery: lpi2c7recoverygrp {
+ fsl,pins = <IMX95_PAD_GPIO_IO07__GPIO2_IO_BIT7 0x40001b1e>,
+ <IMX95_PAD_GPIO_IO06__GPIO2_IO_BIT6 0x40001b1e>;
+ };
+
+ pinctrl_lpspi4: lpspi4grp {
+ fsl,pins = <IMX95_PAD_GPIO_IO37__LPSPI4_SCK 0x11e>,
+ <IMX95_PAD_GPIO_IO19__LPSPI4_SIN 0x111e>,
+ <IMX95_PAD_GPIO_IO36__LPSPI4_SOUT 0x11e>,
+ <IMX95_PAD_GPIO_IO34__GPIO5_IO_BIT14 0x11e>,
+ <IMX95_PAD_GPIO_IO33__GPIO5_IO_BIT13 0x11e>;
+ };
+
+ pinctrl_lpuart1: lpuart1grp {
+ fsl,pins = <IMX95_PAD_UART1_TXD__AONMIX_TOP_LPUART1_TX 0x31e>,
+ <IMX95_PAD_UART1_RXD__AONMIX_TOP_LPUART1_RX 0x1300>;
+ };
+
+ pinctrl_lpuart2: lpuart2grp {
+ fsl,pins = <IMX95_PAD_UART2_TXD__AONMIX_TOP_LPUART2_TX 0x31e>,
+ <IMX95_PAD_UART2_RXD__AONMIX_TOP_LPUART2_RX 0x1300>;
+ };
+
+ pinctrl_lpuart5: lpuart5grp {
+ fsl,pins = <IMX95_PAD_GPIO_IO00__LPUART5_TX 0x31e>,
+ <IMX95_PAD_GPIO_IO01__LPUART5_RX 0x1300>,
+ <IMX95_PAD_GPIO_IO02__LPUART5_CTS_B 0x1300>,
+ <IMX95_PAD_GPIO_IO03__LPUART5_RTS_B 0x31e>;
+ };
+
+ pinctrl_lpuart7: lpuart7grp {
+ fsl,pins = <IMX95_PAD_GPIO_IO08__LPUART7_TX 0x31e>,
+ <IMX95_PAD_GPIO_IO09__LPUART7_RX 0x1300>,
+ <IMX95_PAD_GPIO_IO10__LPUART7_CTS_B 0x1300>,
+ <IMX95_PAD_GPIO_IO11__LPUART7_RTS_B 0x31e>;
+ };
+
+ pinctrl_lpuart8: lpuart8grp {
+ fsl,pins = <IMX95_PAD_GPIO_IO12__LPUART8_TX 0x31e>,
+ <IMX95_PAD_GPIO_IO13__LPUART8_RX 0x1300>,
+ <IMX95_PAD_GPIO_IO15__LPUART8_RTS_B 0x31e>;
+ };
+
+ pinctrl_emdio: emdiogrp {
+ fsl,pins = <IMX95_PAD_ENET2_MDC__NETCMIX_TOP_NETC_MDC 0x51e>,
+ <IMX95_PAD_ENET2_MDIO__NETCMIX_TOP_NETC_MDIO 0x51e>;
+ };
+
+ pinctrl_pcie0: pcie0grp {
+ fsl,pins = <IMX95_PAD_GPIO_IO32__HSIOMIX_TOP_PCIE1_CLKREQ_B 0x111e>;
+ };
+
+ pinctrl_pcie1: pcie1grp {
+ fsl,pins = <IMX95_PAD_GPIO_IO35__HSIOMIX_TOP_PCIE2_CLKREQ_B 0x111e>;
+ };
+
+ pinctrl_sai3: sai3grp {
+ fsl,pins = <IMX95_PAD_GPIO_IO16__SAI3_TX_BCLK 0x51e>,
+ <IMX95_PAD_GPIO_IO17__SAI3_MCLK 0x51e>,
+ <IMX95_PAD_GPIO_IO20__SAI3_RX_DATA_BIT0 0x1300>,
+ <IMX95_PAD_GPIO_IO21__SAI3_TX_DATA_BIT0 0x51e>,
+ <IMX95_PAD_GPIO_IO26__SAI3_TX_SYNC 0x51e>;
+ };
+
+ pinctrl_retimer: retirmergrp {
+ fsl,pins = <IMX95_PAD_GPIO_IO29__GPIO2_IO_BIT29 0x1100>;
+ };
+
+ pinctrl_sfp: sfpgrp {
+ fsl,pins = <IMX95_PAD_GPIO_IO30__GPIO2_IO_BIT30 0x1100>,
+ <IMX95_PAD_GPIO_IO31__GPIO2_IO_BIT31 0x1100>;
+ };
+
+ pinctrl_tpm3: tpm3grp {
+ fsl,pins = <IMX95_PAD_GPIO_IO24__TPM3_CH3 0x51e>;
+ };
+
+ pinctrl_tpm5: tpm5grp {
+ fsl,pins = <IMX95_PAD_GPIO_IO18__TPM5_CH2 0x51e>;
+ };
+
+ pinctrl_typec: typcegrp {
+ fsl,pins = <IMX95_PAD_GPIO_IO28__GPIO2_IO_BIT28 0x1100>;
+ };
+
+ pinctrl_usb3: usb3grp {
+ fsl,pins = <IMX95_PAD_ENET1_MDIO__GPIO4_IO_BIT1 0x31e>;
+ };
+
+ pinctrl_usdhc2: usdhc2grp {
+ fsl,pins = <IMX95_PAD_SD2_CD_B__GPIO3_IO_BIT0 0x1100>,
+ <IMX95_PAD_SD2_CLK__USDHC2_CLK 0x51e>,
+ <IMX95_PAD_SD2_CMD__USDHC2_CMD 0x31e>,
+ <IMX95_PAD_SD2_DATA0__USDHC2_DATA0 0x131e>,
+ <IMX95_PAD_SD2_DATA1__USDHC2_DATA1 0x131e>,
+ <IMX95_PAD_SD2_DATA2__USDHC2_DATA2 0x131e>,
+ <IMX95_PAD_SD2_DATA3__USDHC2_DATA3 0x131e>,
+ <IMX95_PAD_SD2_VSELECT__USDHC2_VSELECT 0x51e>;
+ };
+
+ pinctrl_usdhc2_100mhz: usdhc2-100mhzgrp {
+ fsl,pins = <IMX95_PAD_SD2_CD_B__GPIO3_IO_BIT0 0x1100>,
+ <IMX95_PAD_SD2_CLK__USDHC2_CLK 0x58e>,
+ <IMX95_PAD_SD2_CMD__USDHC2_CMD 0x38e>,
+ <IMX95_PAD_SD2_DATA0__USDHC2_DATA0 0x138e>,
+ <IMX95_PAD_SD2_DATA1__USDHC2_DATA1 0x138e>,
+ <IMX95_PAD_SD2_DATA2__USDHC2_DATA2 0x138e>,
+ <IMX95_PAD_SD2_DATA3__USDHC2_DATA3 0x138e>,
+ <IMX95_PAD_SD2_VSELECT__USDHC2_VSELECT 0x51e>;
+ };
+
+ pinctrl_usdhc2_200mhz: usdhc2-200mhzgrp {
+ fsl,pins = <IMX95_PAD_SD2_CD_B__GPIO3_IO_BIT0 0x1100>,
+ <IMX95_PAD_SD2_CLK__USDHC2_CLK 0x5fe>,
+ <IMX95_PAD_SD2_CMD__USDHC2_CMD 0x3fe>,
+ <IMX95_PAD_SD2_DATA0__USDHC2_DATA0 0x13fe>,
+ <IMX95_PAD_SD2_DATA1__USDHC2_DATA1 0x13fe>,
+ <IMX95_PAD_SD2_DATA2__USDHC2_DATA2 0x13fe>,
+ <IMX95_PAD_SD2_DATA3__USDHC2_DATA3 0x13fe>,
+ <IMX95_PAD_SD2_VSELECT__USDHC2_VSELECT 0x51e>;
+ };
+};
diff --git a/arch/arm64/boot/dts/freescale/imx95-tqma9596la.dtsi b/arch/arm64/boot/dts/freescale/imx95-tqma9596la.dtsi
new file mode 100644
index 0000000000000..aa2756c14e461
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx95-tqma9596la.dtsi
@@ -0,0 +1,278 @@
+// SPDX-License-Identifier: (GPL-2.0-or-later OR MIT)
+/*
+ * Copyright (c) 2024-2026 TQ-Systems GmbH <linux@ew.tq-group.com>,
+ * D-82229 Seefeld, Germany.
+ * Author: Alexander Stein
+ * Author: Markus Niebel
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include "imx95.dtsi"
+
+/ {
+ memory@80000000 {
+ device_type = "memory";
+ /*
+ * DRAM base addr, size : 2048 MiB DRAM
+ * should be corrected by bootloader
+ */
+ reg = <0 0x80000000 0 0x80000000>;
+ };
+
+ reg_1v8: regulator-1v8 {
+ compatible = "regulator-fixed";
+ regulator-name = "V_1V8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ reg_3v3: regulator-3v3 {
+ compatible = "regulator-fixed";
+ regulator-name = "V_3V3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ reg_sdvmmc: regulator-sdvmmc {
+ compatible = "regulator-fixed";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_sdvmmc>;
+ regulator-name = "SD_PWR_EN";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio3 7 GPIO_ACTIVE_HIGH>;
+ off-on-delay-us = <12000>;
+ enable-active-high;
+ /* can be enabled by mainboard with SD-Card support */
+ status = "disabled";
+ };
+};
+
+&adc1 {
+ vref-supply = <®_1v8>;
+};
+
+&flexspi1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_flexspi1>;
+ status = "okay";
+
+ flash0: flash@0 {
+ compatible = "jedec,spi-nor";
+ reg = <0>;
+ spi-max-frequency = <66000000>;
+ spi-tx-bus-width = <4>;
+ spi-rx-bus-width = <4>;
+ vcc-supply = <®_1v8>;
+
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ };
+ };
+};
+
+/* System Manager */
+&gpio1 {
+ status = "reserved";
+};
+
+/* System Manager */
+&lpi2c1 {
+ status = "reserved";
+};
+
+&lpi2c2 {
+ clock-frequency = <400000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lpi2c2>;
+ status = "okay";
+
+ pcf85063: rtc@51 {
+ compatible = "nxp,pcf85063a";
+ reg = <0x51>;
+ quartz-load-femtofarads = <7000>;
+ };
+
+ m24c64: eeprom@54 {
+ compatible = "atmel,24c64";
+ reg = <0x54>;
+ pagesize = <32>;
+ vcc-supply = <®_3v3>;
+ };
+
+ /* protectable identification memory (part of M24C64-D @54) */
+ eeprom@5c {
+ compatible = "atmel,24c64d-wl";
+ reg = <0x5c>;
+ pagesize = <32>;
+ vcc-supply = <®_3v3>;
+ };
+
+ imu@6b {
+ compatible = "st,ism330dhcx";
+ reg = <0x6b>;
+ vdd-supply = <®_3v3>;
+ vddio-supply = <®_3v3>;
+ };
+};
+
+&thermal_zones {
+ pf09-thermal {
+ polling-delay = <2000>;
+ polling-delay-passive = <250>;
+ thermal-sensors = <&scmi_sensor 2>;
+
+ trips {
+ pf09_alert: trip0 {
+ hysteresis = <2000>;
+ temperature = <140000>;
+ type = "passive";
+ };
+
+ pf09_crit: trip1 {
+ hysteresis = <2000>;
+ temperature = <155000>;
+ type = "critical";
+ };
+ };
+ };
+
+ pf53arm-thermal {
+ polling-delay = <2000>;
+ polling-delay-passive = <250>;
+ thermal-sensors = <&scmi_sensor 4>;
+
+ cooling-maps {
+ map0 {
+ trip = <&pf5301_alert>;
+ cooling-device =
+ <&A55_0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&A55_1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&A55_2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&A55_3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&A55_4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&A55_5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
+
+ trips {
+ pf5301_alert: trip0 {
+ hysteresis = <2000>;
+ temperature = <140000>;
+ type = "passive";
+ };
+
+ pf5301_crit: trip1 {
+ hysteresis = <2000>;
+ temperature = <155000>;
+ type = "critical";
+ };
+ };
+ };
+
+ pf53soc-thermal {
+ polling-delay = <2000>;
+ polling-delay-passive = <250>;
+ thermal-sensors = <&scmi_sensor 3>;
+
+ trips {
+ pf5302_alert: trip0 {
+ hysteresis = <2000>;
+ temperature = <140000>;
+ type = "passive";
+ };
+
+ pf5302_crit: trip1 {
+ hysteresis = <2000>;
+ temperature = <155000>;
+ type = "critical";
+ };
+ };
+ };
+};
+
+&usdhc1 {
+ pinctrl-names = "default", "state_100mhz", "state_200mhz";
+ pinctrl-0 = <&pinctrl_usdhc1>;
+ pinctrl-1 = <&pinctrl_usdhc1_100mhz>;
+ pinctrl-2 = <&pinctrl_usdhc1_200mhz>;
+ bus-width = <8>;
+ non-removable;
+ no-sdio;
+ no-sd;
+ status = "okay";
+};
+
+&wdog3 {
+ status = "okay";
+};
+
+&scmi_iomuxc {
+ pinctrl_flexspi1: flexspi1grp {
+ fsl,pins = <IMX95_PAD_XSPI1_SS0_B__FLEXSPI1_A_SS0_B 0x19e>,
+ <IMX95_PAD_XSPI1_DATA0__FLEXSPI1_A_DATA_BIT0 0x19e>,
+ <IMX95_PAD_XSPI1_DATA1__FLEXSPI1_A_DATA_BIT1 0x19e>,
+ <IMX95_PAD_XSPI1_DATA2__FLEXSPI1_A_DATA_BIT2 0x19e>,
+ <IMX95_PAD_XSPI1_DATA3__FLEXSPI1_A_DATA_BIT3 0x19e>,
+ /* SION to allow clock loopback from pad */
+ <IMX95_PAD_XSPI1_SCLK__FLEXSPI1_A_SCLK 0x4000019e>,
+ <IMX95_PAD_XSPI1_DQS__FLEXSPI1_A_DQS 0x4000019e>;
+ };
+
+ pinctrl_lpi2c2: lpi2c2grp {
+ fsl,pins = <IMX95_PAD_I2C2_SCL__AONMIX_TOP_LPI2C2_SCL 0x4000191e>,
+ <IMX95_PAD_I2C2_SDA__AONMIX_TOP_LPI2C2_SDA 0x4000191e>;
+ };
+
+ pinctrl_sdvmmc: sdvmmcgrp {
+ fsl,pins = <IMX95_PAD_SD2_RESET_B__GPIO3_IO_BIT7 0x11e>;
+ };
+
+ pinctrl_usdhc1: usdhc1grp {
+ fsl,pins = <IMX95_PAD_SD1_CLK__USDHC1_CLK 0x158e>,
+ <IMX95_PAD_SD1_CMD__USDHC1_CMD 0x138e>,
+ <IMX95_PAD_SD1_DATA0__USDHC1_DATA0 0x138e>,
+ <IMX95_PAD_SD1_DATA1__USDHC1_DATA1 0x138e>,
+ <IMX95_PAD_SD1_DATA2__USDHC1_DATA2 0x138e>,
+ <IMX95_PAD_SD1_DATA3__USDHC1_DATA3 0x138e>,
+ <IMX95_PAD_SD1_DATA4__USDHC1_DATA4 0x138e>,
+ <IMX95_PAD_SD1_DATA5__USDHC1_DATA5 0x138e>,
+ <IMX95_PAD_SD1_DATA6__USDHC1_DATA6 0x138e>,
+ <IMX95_PAD_SD1_DATA7__USDHC1_DATA7 0x138e>,
+ <IMX95_PAD_SD1_STROBE__USDHC1_STROBE 0x158e>;
+ };
+
+ pinctrl_usdhc1_100mhz: usdhc1-100mhzgrp {
+ fsl,pins = <IMX95_PAD_SD1_CLK__USDHC1_CLK 0x158e>,
+ <IMX95_PAD_SD1_CMD__USDHC1_CMD 0x138e>,
+ <IMX95_PAD_SD1_DATA0__USDHC1_DATA0 0x138e>,
+ <IMX95_PAD_SD1_DATA1__USDHC1_DATA1 0x138e>,
+ <IMX95_PAD_SD1_DATA2__USDHC1_DATA2 0x138e>,
+ <IMX95_PAD_SD1_DATA3__USDHC1_DATA3 0x138e>,
+ <IMX95_PAD_SD1_DATA4__USDHC1_DATA4 0x138e>,
+ <IMX95_PAD_SD1_DATA5__USDHC1_DATA5 0x138e>,
+ <IMX95_PAD_SD1_DATA6__USDHC1_DATA6 0x138e>,
+ <IMX95_PAD_SD1_DATA7__USDHC1_DATA7 0x138e>,
+ <IMX95_PAD_SD1_STROBE__USDHC1_STROBE 0x158e>;
+ };
+
+ pinctrl_usdhc1_200mhz: usdhc1-200mhzgrp {
+ fsl,pins = <IMX95_PAD_SD1_CLK__USDHC1_CLK 0x15fe>,
+ <IMX95_PAD_SD1_CMD__USDHC1_CMD 0x13fe>,
+ <IMX95_PAD_SD1_DATA0__USDHC1_DATA0 0x13fe>,
+ <IMX95_PAD_SD1_DATA1__USDHC1_DATA1 0x13fe>,
+ <IMX95_PAD_SD1_DATA2__USDHC1_DATA2 0x13fe>,
+ <IMX95_PAD_SD1_DATA3__USDHC1_DATA3 0x13fe>,
+ <IMX95_PAD_SD1_DATA4__USDHC1_DATA4 0x13fe>,
+ <IMX95_PAD_SD1_DATA5__USDHC1_DATA5 0x13fe>,
+ <IMX95_PAD_SD1_DATA6__USDHC1_DATA6 0x13fe>,
+ <IMX95_PAD_SD1_DATA7__USDHC1_DATA7 0x13fe>,
+ <IMX95_PAD_SD1_STROBE__USDHC1_STROBE 0x15fe>;
+ };
+};
--
2.54.0
^ permalink raw reply related
* [PATCH 1/1] PCI: imx6: Use dev_err_probe
From: Alexander Stein @ 2026-06-19 11:25 UTC (permalink / raw)
To: Richard Zhu, Lucas Stach, Lorenzo Pieralisi,
Krzysztof Wilczyński, Manivannan Sadhasivam, Rob Herring,
Bjorn Helgaas, Frank Li, Sascha Hauer, Pengutronix Kernel Team,
Fabio Estevam
Cc: Alexander Stein, linux-pci, linux-arm-kernel, imx, linux-kernel
pci_pwrctrl_power_on_devices() might return -EPROBE_DEFER resulting in
an error message. Use dev_err_probe to silence this non-error message.
Signed-off-by: Alexander Stein <alexander.stein@ew.tq-group.com>
---
drivers/pci/controller/dwc/pci-imx6.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
index 98e1db751132a..b7a502e9a1c59 100644
--- a/drivers/pci/controller/dwc/pci-imx6.c
+++ b/drivers/pci/controller/dwc/pci-imx6.c
@@ -1381,7 +1381,7 @@ static int imx_pcie_host_init(struct dw_pcie_rp *pp)
ret = pci_pwrctrl_power_on_devices(dev);
if (ret) {
- dev_err(dev, "failed to power on pwrctrl devices\n");
+ dev_err_probe(dev, ret, "failed to power on pwrctrl devices\n");
goto err_pwrctrl_destroy;
}
--
2.54.0
^ permalink raw reply related
* Re: [PATCH net 2/2] net: airoha: fix netif_set_real_num_tx_queues for sparse QoS channels
From: Lorenzo Bianconi @ 2026-06-19 11:34 UTC (permalink / raw)
To: Simon Horman
Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Wayen Yan, linux-arm-kernel, linux-mediatek, netdev
In-Reply-To: <20260619093529.GV827683@horms.kernel.org>
[-- Attachment #1: Type: text/plain, Size: 2052 bytes --]
> On Thu, Jun 18, 2026 at 08:00:30AM +0200, Lorenzo Bianconi wrote:
> > airoha_tc_htb_alloc_leaf_queue() assigns queue IDs based on the channel
> > index (opt->qid = AIROHA_NUM_TX_RING + channel), but updates
> > real_num_tx_queues with a simple increment (num_tx_queues + 1). When QoS
> > channels are allocated sparsely (e.g., channels 0 and 3 without 1 and
> > 2), the returned qid can exceed real_num_tx_queues, causing out-of-bounds
> > accesses in the networking stack.
> > For example, allocating channel 0 then channel 3 results in
> > real_num_tx_queues = 34 but qid = 35, which is out of range [0, 34).
> > Fix this by computing real_num_tx_queues based on the highest active
> > channel index rather than using a simple counter, in both the allocation
> > and deletion paths.
> >
> > Fixes: ef1ca9271313b ("net: airoha: Add sched HTB offload support")
> > Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
> > ---
> > drivers/net/ethernet/airoha/airoha_eth.c | 15 ++++++++++++---
> > 1 file changed, 12 insertions(+), 3 deletions(-)
> >
> > diff --git a/drivers/net/ethernet/airoha/airoha_eth.c b/drivers/net/ethernet/airoha/airoha_eth.c
>
> ...
>
> > @@ -2806,7 +2806,10 @@ static int airoha_tc_htb_alloc_leaf_queue(struct net_device *netdev,
> > if (err)
> > goto error;
> >
> > - err = netif_set_real_num_tx_queues(netdev, num_tx_queues + 1);
> > + if (num_tx_queues <= netdev->real_num_tx_queues)
> > + goto set_qos_sq_bmap;
> > +
> > + err = netif_set_real_num_tx_queues(netdev, num_tx_queues);
> > if (err) {
> > airoha_qdma_set_tx_rate_limit(netdev, channel, 0,
> > opt->quantum);
> > @@ -2815,6 +2818,7 @@ static int airoha_tc_htb_alloc_leaf_queue(struct net_device *netdev,
> > goto error;
> > }
> >
> > +set_qos_sq_bmap:
>
> I would prefer if this could be achieved without a goto.
ack, I will fix it in v2.
Regards,
Lorenzo
>
> > set_bit(channel, dev->qos_sq_bmap);
> > opt->qid = AIROHA_NUM_TX_RING + channel;
> >
>
> ...
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply
* [PATCH net v2 0/2] airoha: fixes for sched HTB offload support
From: Lorenzo Bianconi @ 2026-06-19 11:37 UTC (permalink / raw)
To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Lorenzo Bianconi
Cc: Simon Horman, Wayen Yan, linux-arm-kernel, linux-mediatek, netdev
---
Changes in v2:
- cosmetics
- Link to v1: https://lore.kernel.org/r/20260618-airoha-qos-fixes-v1-0-37192652157f@kernel.org
---
Lorenzo Bianconi (2):
net: airoha: Fix off-by-one in airoha_tc_remove_htb_queue()
net: airoha: fix netif_set_real_num_tx_queues for sparse QoS channels
drivers/net/ethernet/airoha/airoha_eth.c | 27 +++++++++++++++++----------
1 file changed, 17 insertions(+), 10 deletions(-)
---
base-commit: 96e7f9122aae0ed000ee321f324b812a447906d9
change-id: 20260618-airoha-qos-fixes-b6460b085680
Best regards,
--
Lorenzo Bianconi <lorenzo@kernel.org>
^ permalink raw reply
* [PATCH net v2 1/2] net: airoha: Fix off-by-one in airoha_tc_remove_htb_queue()
From: Lorenzo Bianconi @ 2026-06-19 11:37 UTC (permalink / raw)
To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Lorenzo Bianconi
Cc: Simon Horman, Wayen Yan, linux-arm-kernel, linux-mediatek, netdev
In-Reply-To: <20260619-airoha-qos-fixes-v2-0-5c43485038f9@kernel.org>
airoha_tc_htb_alloc_leaf_queue() computes the HTB QoS channel index
as opt->classid % AIROHA_NUM_QOS_CHANNELS and stores it in qos_sq_bmap.
However, airoha_tc_remove_htb_queue() clears the HTB configuration
using queue + 1 as the channel index, causing an off-by-one error.
Use queue directly as the QoS channel index to match the allocation
logic.
Fixes: ef1ca9271313b ("net: airoha: Add sched HTB offload support")
Reviewed-by: Simon Horman <horms@kernel.org>
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
drivers/net/ethernet/airoha/airoha_eth.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/airoha/airoha_eth.c b/drivers/net/ethernet/airoha/airoha_eth.c
index 64dde6464f3f..aa98d1823ab6 100644
--- a/drivers/net/ethernet/airoha/airoha_eth.c
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
@@ -3006,7 +3006,7 @@ static void airoha_tc_remove_htb_queue(struct net_device *netdev, int queue)
struct airoha_qdma *qdma = dev->qdma;
netif_set_real_num_tx_queues(netdev, netdev->real_num_tx_queues - 1);
- airoha_qdma_set_tx_rate_limit(netdev, queue + 1, 0, 0);
+ airoha_qdma_set_tx_rate_limit(netdev, queue, 0, 0);
clear_bit(queue, qdma->qos_channel_map);
clear_bit(queue, dev->qos_sq_bmap);
--
2.54.0
^ permalink raw reply related
* [PATCH net v2 2/2] net: airoha: fix netif_set_real_num_tx_queues for sparse QoS channels
From: Lorenzo Bianconi @ 2026-06-19 11:37 UTC (permalink / raw)
To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Lorenzo Bianconi
Cc: Simon Horman, Wayen Yan, linux-arm-kernel, linux-mediatek, netdev
In-Reply-To: <20260619-airoha-qos-fixes-v2-0-5c43485038f9@kernel.org>
airoha_tc_htb_alloc_leaf_queue() assigns queue IDs based on the channel
index (opt->qid = AIROHA_NUM_TX_RING + channel), but updates
real_num_tx_queues with a simple increment (num_tx_queues + 1). When QoS
channels are allocated sparsely (e.g., channels 0 and 3 without 1 and
2), the returned qid can exceed real_num_tx_queues, causing out-of-bounds
accesses in the networking stack.
For example, allocating channel 0 then channel 3 results in
real_num_tx_queues = 34 but qid = 35, which is out of range [0, 34).
Fix this by computing real_num_tx_queues based on the highest active
channel index rather than using a simple counter, in both the allocation
and deletion paths.
Fixes: ef1ca9271313b ("net: airoha: Add sched HTB offload support")
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
drivers/net/ethernet/airoha/airoha_eth.c | 25 ++++++++++++++++---------
1 file changed, 16 insertions(+), 9 deletions(-)
diff --git a/drivers/net/ethernet/airoha/airoha_eth.c b/drivers/net/ethernet/airoha/airoha_eth.c
index aa98d1823ab6..aa2ddfd3af9f 100644
--- a/drivers/net/ethernet/airoha/airoha_eth.c
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
@@ -2789,7 +2789,7 @@ static int airoha_tc_htb_alloc_leaf_queue(struct net_device *netdev,
struct tc_htb_qopt_offload *opt)
{
u32 channel = TC_H_MIN(opt->classid) % AIROHA_NUM_QOS_CHANNELS;
- int err, num_tx_queues = netdev->real_num_tx_queues;
+ int err, num_tx_queues = AIROHA_NUM_TX_RING + channel + 1;
struct airoha_gdm_dev *dev = netdev_priv(netdev);
struct airoha_qdma *qdma = dev->qdma;
@@ -2806,13 +2806,15 @@ static int airoha_tc_htb_alloc_leaf_queue(struct net_device *netdev,
if (err)
goto error;
- err = netif_set_real_num_tx_queues(netdev, num_tx_queues + 1);
- if (err) {
- airoha_qdma_set_tx_rate_limit(netdev, channel, 0,
- opt->quantum);
- NL_SET_ERR_MSG_MOD(opt->extack,
- "failed setting real_num_tx_queues");
- goto error;
+ if (num_tx_queues > netdev->real_num_tx_queues) {
+ err = netif_set_real_num_tx_queues(netdev, num_tx_queues);
+ if (err) {
+ airoha_qdma_set_tx_rate_limit(netdev, channel, 0,
+ opt->quantum);
+ NL_SET_ERR_MSG_MOD(opt->extack,
+ "failed setting real_num_tx_queues");
+ goto error;
+ }
}
set_bit(channel, dev->qos_sq_bmap);
@@ -3003,13 +3005,18 @@ static int airoha_dev_setup_tc_block(struct net_device *dev,
static void airoha_tc_remove_htb_queue(struct net_device *netdev, int queue)
{
struct airoha_gdm_dev *dev = netdev_priv(netdev);
+ int num_tx_queues = AIROHA_NUM_TX_RING;
struct airoha_qdma *qdma = dev->qdma;
- netif_set_real_num_tx_queues(netdev, netdev->real_num_tx_queues - 1);
airoha_qdma_set_tx_rate_limit(netdev, queue, 0, 0);
clear_bit(queue, qdma->qos_channel_map);
clear_bit(queue, dev->qos_sq_bmap);
+
+ if (!bitmap_empty(dev->qos_sq_bmap, AIROHA_NUM_QOS_CHANNELS))
+ num_tx_queues += find_last_bit(dev->qos_sq_bmap,
+ AIROHA_NUM_QOS_CHANNELS) + 1;
+ netif_set_real_num_tx_queues(netdev, num_tx_queues);
}
static int airoha_tc_htb_delete_leaf_queue(struct net_device *netdev,
--
2.54.0
^ permalink raw reply related
* Re: [PATCH net v2] net: airoha: Fix TX scheduler queue mask loop upper bound
From: Lorenzo Bianconi @ 2026-06-19 11:39 UTC (permalink / raw)
To: Wayen Yan
Cc: netdev, horms, pabeni, kuba, edumazet, andrew+netdev,
angelogioacchino.delregno, matthias.bgg, linux-arm-kernel,
linux-mediatek
In-Reply-To: <178185574223.2378148.13454900445528174929@gmail.com>
[-- Attachment #1: Type: text/plain, Size: 2499 bytes --]
> In airoha_qdma_set_chan_tx_sched(), the loop clearing queue mask was
> using AIROHA_NUM_TX_RING (32) instead of AIROHA_NUM_QOS_QUEUES (8).
>
> Each channel has 8 queues, and TXQ_DISABLE_CHAN_QUEUE_MASK(channel, i)
> computes BIT(i + (channel * 8)). With i ranging 0..31, this causes:
> - channel 0: clears bit 0..31 (all 4 channels) instead of 0..7
> - channel 1: clears bit 8..31 (channels 1-3) instead of 8..15
> - channel 2: clears bit 16..31 (channels 2-3) instead of 16..23
> - channel 3: clears bit 24..31 (channel 3 only) - correct by accident
>
> While BIT(32+) on arm64 produces 64-bit values truncated to 0 in u32
> mask parameter, the loop still incorrectly clears queues within the
> same channel beyond queue 7.
>
> Even though this is functionally harmless (the register resets to 0
> and is only ever cleared, never set — so clearing extra bits is a
> no-op), the loop bound is semantically wrong and should be fixed for
> correctness and clarity.
>
> Fix by using AIROHA_NUM_QOS_QUEUES (8) as the loop upper bound.
>
> Fixes: ef1ca9271313 ("net: airoha: Add sched HTB offload support")
> Acked-by: Lorenzo Bianconi <lorenzo@kernel.org>
> Signed-off-by: Wayen Yan <win847@gmail.com>
> ---
> Changes in v2:
> - Add Lorenzo's Acked-by tag.
> - Clarify in commit message that this is semantically wrong but
> functionally harmless (register resets to 0, only cleared), as
> Lorenzo pointed out in review.
> - Rebase on current net tree.
>
> Link: https://lore.kernel.org/netdev/ajJIWMs4dVbfkHZ5@lore-desk/
> Link: https://lore.kernel.org/netdev/CAL_ptrs6J3Ryw_4mVTq5VgzkB4RreF5S0huHyLvd9YwWr1m6jAA@mail.gmail.com/
>
> drivers/net/ethernet/airoha/airoha_eth.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/net/ethernet/airoha/airoha_eth.c b/drivers/net/ethernet/airoha/airoha_eth.c
> index d0c0c0ec8a..ca77747b44 100644
> --- a/drivers/net/ethernet/airoha/airoha_eth.c
> +++ b/drivers/net/ethernet/airoha/airoha_eth.c
> @@ -2212,7 +2212,7 @@ static int airoha_qdma_set_chan_tx_sched(struct net_device *dev,
> struct airoha_gdm_port *port = netdev_priv(dev);
it seems you have not rebased on top of net tree.
Regards,
Lorenzo
> int i;
>
> - for (i = 0; i < AIROHA_NUM_TX_RING; i++)
> + for (i = 0; i < AIROHA_NUM_QOS_QUEUES; i++)
> airoha_qdma_clear(port->qdma, REG_QUEUE_CLOSE_CFG(channel),
> TXQ_DISABLE_CHAN_QUEUE_MASK(channel, i));
>
> --
> 2.51.0
>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply
* [PATCH v2] ARM: tegra: Replace __ASSEMBLY__ with __ASSEMBLER__
From: Thomas Huth @ 2026-06-19 11:56 UTC (permalink / raw)
To: Thierry Reding, Jonathan Hunter
Cc: Russell King, linux-tegra, linux-arm-kernel, linux-kernel
From: Thomas Huth <thuth@redhat.com>
While the GCC and Clang compilers already define __ASSEMBLER__
automatically when compiling assembly code, __ASSEMBLY__ is a
macro that only gets defined by the Makefiles in the kernel.
This can be very confusing when switching between userspace
and kernelspace coding, or when dealing with uapi headers that
rather should use __ASSEMBLER__ instead. So let's standardize now
on the __ASSEMBLER__ macro that is provided by the compilers.
This is a completely mechanical patch (done with a simple "sed -i"
statement).
Signed-off-by: Thomas Huth <thuth@redhat.com>
---
v2: Added changes to files in include/soc/tegra/
arch/arm/mach-tegra/reset.h | 2 +-
arch/arm/mach-tegra/sleep.h | 2 +-
include/soc/tegra/flowctrl.h | 4 ++--
include/soc/tegra/fuse.h | 4 ++--
4 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/arch/arm/mach-tegra/reset.h b/arch/arm/mach-tegra/reset.h
index 51265592cb1ae..92a89713d5e57 100644
--- a/arch/arm/mach-tegra/reset.h
+++ b/arch/arm/mach-tegra/reset.h
@@ -21,7 +21,7 @@
#define RESET_DATA(x) ((TEGRA_RESET_##x)*4)
-#ifndef __ASSEMBLY__
+#ifndef __ASSEMBLER__
#include "irammap.h"
diff --git a/arch/arm/mach-tegra/sleep.h b/arch/arm/mach-tegra/sleep.h
index 4718a3cb45a16..e332d261c1dbd 100644
--- a/arch/arm/mach-tegra/sleep.h
+++ b/arch/arm/mach-tegra/sleep.h
@@ -38,7 +38,7 @@
#define TEGRA_FLUSH_CACHE_LOUIS 0
#define TEGRA_FLUSH_CACHE_ALL 1
-#ifdef __ASSEMBLY__
+#ifdef __ASSEMBLER__
/* waits until the microsecond counter (base) is > rn */
.macro wait_until, rn, base, tmp
add \rn, \rn, #1
diff --git a/include/soc/tegra/flowctrl.h b/include/soc/tegra/flowctrl.h
index 1aacc5c7a9dba..2a60bd4934c32 100644
--- a/include/soc/tegra/flowctrl.h
+++ b/include/soc/tegra/flowctrl.h
@@ -39,7 +39,7 @@
#define TEGRA30_FLOW_CTRL_CSR_WFE_BITMAP (0xF << 4)
#define TEGRA30_FLOW_CTRL_CSR_WFI_BITMAP (0xF << 8)
-#ifndef __ASSEMBLY__
+#ifndef __ASSEMBLER__
#ifdef CONFIG_SOC_TEGRA_FLOWCTRL
u32 flowctrl_read_cpu_csr(unsigned int cpuid);
void flowctrl_write_cpu_csr(unsigned int cpuid, u32 value);
@@ -67,5 +67,5 @@ static inline void flowctrl_cpu_suspend_exit(unsigned int cpuid)
{
}
#endif /* CONFIG_SOC_TEGRA_FLOWCTRL */
-#endif /* __ASSEMBLY */
+#endif /* __ASSEMBLER__ */
#endif /* __SOC_TEGRA_FLOWCTRL_H__ */
diff --git a/include/soc/tegra/fuse.h b/include/soc/tegra/fuse.h
index 8f421b9f7585c..c4f7a1b97c547 100644
--- a/include/soc/tegra/fuse.h
+++ b/include/soc/tegra/fuse.h
@@ -24,7 +24,7 @@
#define TEGRA30_FUSE_SATA_CALIB 0x124
#define TEGRA_FUSE_USB_CALIB_EXT_0 0x250
-#ifndef __ASSEMBLY__
+#ifndef __ASSEMBLER__
enum tegra_revision {
TEGRA_REVISION_UNKNOWN = 0,
@@ -122,6 +122,6 @@ static inline int tegra194_miscreg_mask_serror(void)
struct device *tegra_soc_device_register(void);
-#endif /* __ASSEMBLY__ */
+#endif /* __ASSEMBLER__ */
#endif /* __SOC_TEGRA_FUSE_H__ */
--
2.54.0
^ permalink raw reply related
* Re: [PATCH v6 00/20] dma-mapping: Use DMA_ATTR_CC_SHARED through direct, pool and swiotlb paths
From: Jason Gunthorpe @ 2026-06-19 12:03 UTC (permalink / raw)
To: Alexey Kardashevskiy
Cc: Aneesh Kumar K.V, Catalin Marinas, iommu, linux-arm-kernel,
linux-kernel, linux-coco, Robin Murphy, Marek Szyprowski,
Will Deacon, Marc Zyngier, Steven Price, Suzuki K Poulose,
Jiri Pirko, Mostafa Saleh, Petr Tesarik, Dan Williams, Xu Yilun,
linuxppc-dev, linux-s390, Madhavan Srinivasan, Michael Ellerman,
Nicholas Piggin, Christophe Leroy (CS GROUP), Alexander Gordeev,
Gerald Schaefer, Heiko Carstens, Vasily Gorbik,
Christian Borntraeger, Sven Schnelle, x86
In-Reply-To: <d4ef9a9f-18d9-40e1-9d02-87aeb9cb6540@amd.com>
On Fri, Jun 19, 2026 at 12:05:45PM +1000, Alexey Kardashevskiy wrote:
> > > > > IMHO that's an AMD issue, not with the design of this series..
> > > > >
> > > > > The series is right, a device that is !force_dma_decrypted() must be
> > > > > considerd to be a trusted device and we must never place any DMA
> > > > > mappings for a trusted device into shared memory.
> > > >
> > > > swiotlb=force forces swiotlb, not decryption.
> >
> > If force_dma_decrypted() == true then swiotlb must allocate from a
> > decrypted memory pool. It is right there in the name!
> >
> > The hypervisor environment should *never* set force_dma_decrypted()
> > because all devices can access all hypervisor memory, up to their IOVA
> > limits.
>
> True. But we do not have encrypted swiotlb pool today, right?
"encrypted" is just normal struct page memory, that's the default for
swiotlb.
I think it was a big mistake for the AMD SME stuff to overload the
decrypted/encrypted CC stuff which should mean shared/private in a
guest context to also mean things about physical memory encryption in
the host. It is really confusing.
The SME side is just a bad arch choice, the real world doesn't work
well if you set high address bits in your dma_addr_t. I think AMD
needs to use those restricted swiotlb pool where it allocates this
very special "SME Disabled" memory that will have a low
dma_addr_t. Then alloc and bouncing will get memory with a suitable
dma_addr_t. This has nothing to do with force_dma_unencrypted() which
is only a CC guest concept and nothing else in the OS should ever
touch decrypted memory.
> > And this is more insane logic. The right fix is to allocate the
> > swiotlb bounce from the *encrypted* pools when running on the
> > hypervisor which requires undoing this abuse of force_dma_decrypted().
>
> +1.
>
> But how does the kernel decide if it is this swiotlb pool or just
> some page which happens to be below the IOVA limit?
You mean in swiotlb_tbl_unmap_single() ? It checks the address against
the pool's range?
> swiotlb can be for bouncing (with all these dma_sync_single_for_cpu)
> or, if dev->dma_io_tlb_mem->for_alloc = true, for coherent
> allocation (no need in dma_sync_single_for_cpu).
>
> I am looking for a way to set up my "sev-guest" device such as when
Whats a "sev-guest" device?
> dma_alloc_attrs(snp_dev->dev,...) happens, it allocates a page from
> the shared swiotlb pool (with no actual bouncing) and there is no
> obvious way to trick the DMA layer into doing that.
Why do you need this?
Jason
^ permalink raw reply
* Re: [RFC PATCH 5/6] arm64: execmem: enable EXECMEM_ROX_CACHE on supported CPUs
From: Ryan Roberts @ 2026-06-19 12:09 UTC (permalink / raw)
To: Adrian Barnaś, linux-arm-kernel
Cc: linux-mm, Catalin Marinas, Will Deacon, David Hildenbrand,
Mike Rapoport (Microsoft), Ard Biesheuvel, Christoph Lameter,
Yang Shi, Brendan Jackman
In-Reply-To: <20260611130144.1385343-6-abarnas@google.com>
On 11/06/2026 14:01, Adrian Barnaś wrote:
> Enable EXECMEM_ROX_CACHE support for ARM64 systems that implement
> the bbml2_no_abort CPU feature.
>
> Using the ROX cache brings a performance boost by reducing linear region
> fragmentation caused by strict memory permissions (e.g., W^X enforcement).
> Grouping executable code (which is read-only in the linear region alias)
> into PMD-sized block mappings reduces TLB pressure and page table size.
Do you have any data on fragmentation reduction and/or performance improvement
in practice due to this change?
>
> This is only enabled on systems with bbml2_no_abort, as splitting
> these large blocks to make pages writable during module loading would
> otherwise risk triggering TLB Conflict Aborts.
> > Signed-off-by: Adrian Barnaś <abarnas@google.com>
> ---
> arch/arm64/Kconfig | 1 +
> arch/arm64/mm/init.c | 22 +++++++++++++++++++++-
> 2 files changed, 22 insertions(+), 1 deletion(-)
>
> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> index 38dba5f7e4d2..79c347ab841e 100644
> --- a/arch/arm64/Kconfig
> +++ b/arch/arm64/Kconfig
> @@ -285,6 +285,7 @@ config ARM64
> select USER_STACKTRACE_SUPPORT
> select VDSO_GETRANDOM
> select VMAP_STACK
> + select ARCH_HAS_EXECMEM_ROX
nit: This list is sorted in alphabetical order; please maintain that ordering.
> help
> ARM 64-bit (AArch64) Linux support.
>
> diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
> index 71aa745e0bef..8269d7747b84 100644
> --- a/arch/arm64/mm/init.c
> +++ b/arch/arm64/mm/init.c
> @@ -420,6 +420,12 @@ void execmem_fill_trapping_insns(void *ptr, size_t size)
>
> flush_icache_range((unsigned long)ptr, (unsigned long)ptr + size);
> }
> +
> +#define MODULE_TEXT_FLAG EXECMEM_ROX_CACHE
> +#define MODULE_TEXT_PGPROT PAGE_KERNEL_ROX
> +#else
> +#define MODULE_TEXT_FLAG (0)
> +#define MODULE_TEXT_PGPROT PAGE_KERNEL
> #endif
>
> static u64 module_direct_base __ro_after_init = 0;
> @@ -511,6 +517,8 @@ struct execmem_info __init *execmem_arch_setup(void)
> {
> unsigned long fallback_start = 0, fallback_end = 0;
> unsigned long start = 0, end = 0;
> + enum execmem_range_flags module_text_flags = 0;
> + pgprot_t module_text_pgprot = PAGE_KERNEL;
>
> module_init_limits();
>
> @@ -531,12 +539,24 @@ struct execmem_info __init *execmem_arch_setup(void)
> end = module_plt_base + SZ_2G;
> }
>
> + /*
> + * The ROX Cache requires bbml2_no_abort because it uses large block
> + * mappings. On systems without this guarantee, splitting these blocks
> + * to make pages writable for module loading can trigger TLB Conflict
> + * Aborts.
> + */
> + if (system_supports_bbml2_noabort()) {
> + module_text_flags = MODULE_TEXT_FLAG;
> + module_text_pgprot = MODULE_TEXT_PGPROT;
> + }
Perhaps this is a bit clearer? Then you don't need the MODULE_TEXT_* macros:
if (IS_ENABLED(CONFIG_ARCH_HAS_EXECMEM_ROX) &&
system_supports_bbml2_noabort()) {
module_text_flags = EXECMEM_ROX_CACHE;
module_text_pgprot = PAGE_KERNEL_ROX;
}
Thanks,
Ryan
> +
> execmem_info = (struct execmem_info){
> .ranges = {
> [EXECMEM_MODULE_TEXT] = {
> .start = start,
> .end = end,
> - .pgprot = PAGE_KERNEL,
> + .flags = module_text_flags,
> + .pgprot = module_text_pgprot,
> .alignment = 1,
> .fallback_start = fallback_start,
> .fallback_end = fallback_end,
^ permalink raw reply
* Re: [PATCH v6 00/20] dma-mapping: Use DMA_ATTR_CC_SHARED through direct, pool and swiotlb paths
From: Aneesh Kumar K.V @ 2026-06-19 12:14 UTC (permalink / raw)
To: Jason Gunthorpe
Cc: Alexey Kardashevskiy, Catalin Marinas, iommu, linux-arm-kernel,
linux-kernel, linux-coco, Robin Murphy, Marek Szyprowski,
Will Deacon, Marc Zyngier, Steven Price, Suzuki K Poulose,
Jiri Pirko, Mostafa Saleh, Petr Tesarik, Dan Williams, Xu Yilun,
linuxppc-dev, linux-s390, Madhavan Srinivasan, Michael Ellerman,
Nicholas Piggin, Christophe Leroy (CS GROUP), Alexander Gordeev,
Gerald Schaefer, Heiko Carstens, Vasily Gorbik,
Christian Borntraeger, Sven Schnelle, x86
In-Reply-To: <20260618153705.GH231643@ziepe.ca>
Jason Gunthorpe <jgg@ziepe.ca> writes:
> On Thu, Jun 18, 2026 at 09:37:22AM +0100, Aneesh Kumar K.V wrote:
>> Alexey Kardashevskiy <aik@amd.com> writes:
>>
>> > On 10/6/26 00:47, Jason Gunthorpe wrote:
>> >> On Tue, Jun 09, 2026 at 02:43:08PM +0100, Catalin Marinas wrote:
>> >>> On Thu, Jun 04, 2026 at 02:09:39PM +0530, Aneesh Kumar K.V (Arm) wrote:
>> >>>> This series propagates DMA_ATTR_CC_SHARED through the dma-direct,
>> >>>> dma-pool, and swiotlb paths so that encrypted and decrypted DMA buffers
>> >>>> are handled consistently.
>> >>>>
>> >>>> Today, the direct DMA path mostly relies on force_dma_unencrypted() for
>> >>>> shared/decrypted buffer handling. This series consolidates the
>> >>>> force_dma_unencrypted() checks in the top-level functions and ensures
>> >>>> that the remaining DMA interfaces use DMA attributes to make the correct
>> >>>> decisions.
>> >>>
>> >>> Please check Sashiko's reports, it has some good points:
>> >>>
>> >>> https://sashiko.dev/#/patchset/20260604083959.1265923-1-aneesh.kumar@kernel.org
>> >>>
>> >>> I think the main one is the swiotlb_tbl_map_single() changes which break
>> >>> AMD SME host support. There cc_platform_has(CC_ATTR_MEM_ENCRYPT) is true
>> >>> but force_dma_unencrypted() is false. Normally you'd not end up on this
>> >>> path but you can have swiotlb=force.
>> >>
>> >> IMHO that's an AMD issue, not with the design of this series..
>> >>
>> >> The series is right, a device that is !force_dma_decrypted() must be
>> >> considerd to be a trusted device and we must never place any DMA
>> >> mappings for a trusted device into shared memory.
>> >
>> > swiotlb=force forces swiotlb, not decryption.
>
> If force_dma_decrypted() == true then swiotlb must allocate from a
> decrypted memory pool. It is right there in the name!
>
> The hypervisor environment should *never* set force_dma_decrypted()
> because all devices can access all hypervisor memory, up to their IOVA
> limits.
>
>> > So when I try "mem_encrypt=on iommu=pt swiotlb=force" with this
>> > patchset, it fails to boot. But it boots with a hack like this:
>
> On the host side I expect this to cause swiotlb to allocate encrypted
> memory and bounce to it.
>
>> u64 dma_enc_mask = DMA_BIT_MASK(__ffs64(sme_me_mask));
>> u64 dma_dev_mask = min_not_zero(dev->coherent_dma_mask,
>> dev->bus_dma_limit);
>> + /*
>> + * With memory encryption enabled, SWIOTLB is marked decrypted.
>> + * If SWIOTLB bouncing is forced, treat the device as requiring
>> + * decrypted DMA.
>> + */
>
> And this is more insane logic. The right fix is to allocate the
> swiotlb bounce from the *encrypted* pools when running on the
> hypervisor which requires undoing this abuse of force_dma_decrypted().
>
Agreed. If the device can do encrypted DMA and requires bouncing, it
should bounce through encrypted pools. We don't support encrypted pools
now and that means, we mark the option ("mem_encrypt=on iommu=pt
swiotlb=force") not supported for now?
-aneesh
^ permalink raw reply
* Re: [PATCH v6 00/20] dma-mapping: Use DMA_ATTR_CC_SHARED through direct, pool and swiotlb paths
From: Jason Gunthorpe @ 2026-06-19 12:21 UTC (permalink / raw)
To: Aneesh Kumar K.V
Cc: Alexey Kardashevskiy, Catalin Marinas, iommu, linux-arm-kernel,
linux-kernel, linux-coco, Robin Murphy, Marek Szyprowski,
Will Deacon, Marc Zyngier, Steven Price, Suzuki K Poulose,
Jiri Pirko, Mostafa Saleh, Petr Tesarik, Dan Williams, Xu Yilun,
linuxppc-dev, linux-s390, Madhavan Srinivasan, Michael Ellerman,
Nicholas Piggin, Christophe Leroy (CS GROUP), Alexander Gordeev,
Gerald Schaefer, Heiko Carstens, Vasily Gorbik,
Christian Borntraeger, Sven Schnelle, x86
In-Reply-To: <yq5ao6h6enhm.fsf@kernel.org>
On Fri, Jun 19, 2026 at 01:14:13PM +0100, Aneesh Kumar K.V wrote:
> > And this is more insane logic. The right fix is to allocate the
> > swiotlb bounce from the *encrypted* pools when running on the
> > hypervisor which requires undoing this abuse of force_dma_decrypted().
> >
>
> Agreed. If the device can do encrypted DMA and requires bouncing, it
> should bounce through encrypted pools. We don't support encrypted pools
> now and that means, we mark the option ("mem_encrypt=on iommu=pt
> swiotlb=force") not supported for now?
?? if you don't have a CC system then the swiotlb is "encrypted"
meaning ordinary struct page system memory.
The hypervisor should not be triggering any CC special stuff here, it
is not a CC guest.
Agree we don't need to worry about swiotlb=force with a trusted device
in the GUEST for now, but it should be something to fix eventually.
Jason
^ permalink raw reply
* [PATCH] soc: imx: Replace __ASSEMBLY__ with __ASSEMBLER__ in header file
From: Thomas Huth @ 2026-06-19 12:24 UTC (permalink / raw)
To: Frank Li, Sascha Hauer, Pengutronix Kernel Team
Cc: Fabio Estevam, imx, linux-arm-kernel, linux-kernel
From: Thomas Huth <thuth@redhat.com>
While the GCC and Clang compilers already define __ASSEMBLER__
automatically when compiling assembly code, __ASSEMBLY__ is a
macro that only gets defined by the Makefiles in the kernel.
This can be very confusing when switching between userspace
and kernelspace coding, or when dealing with uapi headers that
rather should use __ASSEMBLER__ instead. So let's standardize now
on the __ASSEMBLER__ macro that is provided by the compilers.
This is a completely mechanical patch (done with a simple "sed -i"
statement).
Signed-off-by: Thomas Huth <thuth@redhat.com>
---
Note: This patch has been split from an earlier bigger patch of
mine to ease reviewing.
include/soc/imx/cpu.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/soc/imx/cpu.h b/include/soc/imx/cpu.h
index 0bf610acafd06..8c53150acd76e 100644
--- a/include/soc/imx/cpu.h
+++ b/include/soc/imx/cpu.h
@@ -30,7 +30,7 @@
#define MXC_CPU_VF600 0x600
#define MXC_CPU_VF610 (MXC_CPU_VF600 | MXC_CPU_VFx10)
-#ifndef __ASSEMBLY__
+#ifndef __ASSEMBLER__
extern unsigned int __mxc_cpu_type;
#endif
--
2.54.0
^ permalink raw reply related
* [PATCH v3 14/78] drm/bridge: imx8mp-hdmi-pvi: Switch to atomic_create_state
From: Maxime Ripard @ 2026-06-19 12:24 UTC (permalink / raw)
To: Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
Jonas Karlman, Jernej Skrabec, Luca Ceresoli, Maarten Lankhorst,
Thomas Zimmermann, David Airlie, Simona Vetter
Cc: Dmitry Baryshkov, dri-devel, Maxime Ripard, Liu Ying, Frank Li,
Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam, imx,
linux-arm-kernel
In-Reply-To: <20260619-drm-no-more-bridge-reset-v3-0-ff399263111b@kernel.org>
The drm_bridge_funcs.atomic_reset callback and its
drm_atomic_helper_bridge_reset() helper are deprecated.
Switch to the atomic_create_state callback and its
drm_atomic_helper_bridge_create_state() counterpart.
Reviewed-by: Liu Ying <victor.liu@nxp.com>
Reviewed-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de>
Signed-off-by: Maxime Ripard <mripard@kernel.org>
---
To: Liu Ying <victor.liu@nxp.com>
To: Frank Li <Frank.Li@nxp.com>
To: Sascha Hauer <s.hauer@pengutronix.de>
Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
Cc: Fabio Estevam <festevam@gmail.com>
Cc: dri-devel@lists.freedesktop.org
Cc: imx@lists.linux.dev
Cc: linux-arm-kernel@lists.infradead.org
---
drivers/gpu/drm/bridge/imx/imx8mp-hdmi-pvi.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/bridge/imx/imx8mp-hdmi-pvi.c b/drivers/gpu/drm/bridge/imx/imx8mp-hdmi-pvi.c
index 7d5fda7173e5..a31d4fc76f35 100644
--- a/drivers/gpu/drm/bridge/imx/imx8mp-hdmi-pvi.c
+++ b/drivers/gpu/drm/bridge/imx/imx8mp-hdmi-pvi.c
@@ -129,11 +129,11 @@ static const struct drm_bridge_funcs imx_hdmi_pvi_bridge_funcs = {
.atomic_enable = imx8mp_hdmi_pvi_bridge_enable,
.atomic_disable = imx8mp_hdmi_pvi_bridge_disable,
.atomic_get_input_bus_fmts = imx8mp_hdmi_pvi_bridge_get_input_bus_fmts,
.atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
.atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
- .atomic_reset = drm_atomic_helper_bridge_reset,
+ .atomic_create_state = drm_atomic_helper_bridge_create_state,
};
static int imx8mp_hdmi_pvi_probe(struct platform_device *pdev)
{
struct device_node *remote;
--
2.54.0
^ permalink raw reply related
* [PATCH v3 15/78] drm/bridge: imx8qm-ldb: Switch to atomic_create_state
From: Maxime Ripard @ 2026-06-19 12:24 UTC (permalink / raw)
To: Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
Jonas Karlman, Jernej Skrabec, Luca Ceresoli, Maarten Lankhorst,
Thomas Zimmermann, David Airlie, Simona Vetter
Cc: Dmitry Baryshkov, dri-devel, Maxime Ripard, Liu Ying, Frank Li,
Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam, imx,
linux-arm-kernel
In-Reply-To: <20260619-drm-no-more-bridge-reset-v3-0-ff399263111b@kernel.org>
The drm_bridge_funcs.atomic_reset callback and its
drm_atomic_helper_bridge_reset() helper are deprecated.
Switch to the atomic_create_state callback and its
drm_atomic_helper_bridge_create_state() counterpart.
Reviewed-by: Liu Ying <victor.liu@nxp.com>
Reviewed-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de>
Signed-off-by: Maxime Ripard <mripard@kernel.org>
---
To: Liu Ying <victor.liu@nxp.com>
To: Frank Li <Frank.Li@nxp.com>
To: Sascha Hauer <s.hauer@pengutronix.de>
Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
Cc: Fabio Estevam <festevam@gmail.com>
Cc: dri-devel@lists.freedesktop.org
Cc: imx@lists.linux.dev
Cc: linux-arm-kernel@lists.infradead.org
---
drivers/gpu/drm/bridge/imx/imx8qm-ldb.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/bridge/imx/imx8qm-ldb.c b/drivers/gpu/drm/bridge/imx/imx8qm-ldb.c
index a6ca4f5c6cc6..5884af991547 100644
--- a/drivers/gpu/drm/bridge/imx/imx8qm-ldb.c
+++ b/drivers/gpu/drm/bridge/imx/imx8qm-ldb.c
@@ -387,11 +387,11 @@ imx8qm_ldb_bridge_mode_valid(struct drm_bridge *bridge,
}
static const struct drm_bridge_funcs imx8qm_ldb_bridge_funcs = {
.atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
.atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
- .atomic_reset = drm_atomic_helper_bridge_reset,
+ .atomic_create_state = drm_atomic_helper_bridge_create_state,
.mode_valid = imx8qm_ldb_bridge_mode_valid,
.attach = ldb_bridge_attach_helper,
.atomic_check = imx8qm_ldb_bridge_atomic_check,
.mode_set = imx8qm_ldb_bridge_mode_set,
.atomic_enable = imx8qm_ldb_bridge_atomic_enable,
--
2.54.0
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox